On Thu, Oct 29, 2009 at 04:18:12PM +0200, Damyan Ivanov wrote: > Note that constructors of Date::Simple (the base class) work both when > called as functions (D::S::today) and when called as a class methods > (D::S->today) so perhaps upstream overlooked the problem in the > subclasses. > > -- > dam
While trying to write a patch to fix this, I found that calling the d8 and ymd constructors as a class method did not work in the base class or any of the subclasses, producing message such as: $ perl -MDate::Simple -e 'print Date::Simple->d8('20100102');' Usage: Date::Simple::_d8(obj_or_class, d8) at /usr/lib/perl5/Date/Simple.pm line 70. This seems to be caused by "return $_[0]->SUPER::_d8(@_);" which ends up with _d8 being called with two copies of the class name or object. This bug is fixed by replacing the above with "return shift->SUPER::_d8(@_);" and the corresponding change for _ymd. I attach a patch which makes the above changes and copies the constructors from the base class into the three subclasses (D8, Fmt and ISO) which appears to fix both bugs. Test script: echo "Base:" perl -MDate::Simple -e 'print Date::Simple::today()."\n";' perl -MDate::Simple -e 'print Date::Simple->today()."\n";' perl -MDate::Simple -e 'print Date::Simple::ymd(2010,01,02)."\n";' perl -MDate::Simple -e 'print Date::Simple->ymd(2010,01,02)."\n";' perl -MDate::Simple -e 'print Date::Simple::d8('20100102')."\n";' perl -MDate::Simple -e 'print Date::Simple->d8('20100102')."\n";' echo "Fmt:" perl -MDate::Simple::Fmt -e 'print Date::Simple::Fmt::today()."\n";' perl -MDate::Simple::Fmt -e 'print Date::Simple::Fmt->today()."\n";' perl -MDate::Simple::Fmt -e 'print Date::Simple::Fmt::ymd(2010,01,02)."\n";' perl -MDate::Simple::Fmt -e 'print Date::Simple::Fmt->ymd(2010,01,02)."\n";' perl -MDate::Simple::Fmt -e 'print Date::Simple::Fmt::d8('20100102')."\n";' perl -MDate::Simple::Fmt -e 'print Date::Simple::Fmt->d8('20100102')."\n";' echo "D8:" perl -MDate::Simple::D8 -e 'print Date::Simple::D8::today()."\n";' perl -MDate::Simple::D8 -e 'print Date::Simple::D8->today()."\n";' perl -MDate::Simple::D8 -e 'print Date::Simple::D8::ymd(2010,01,02)."\n";' perl -MDate::Simple::D8 -e 'print Date::Simple::D8->ymd(2010,01,02)."\n";' perl -MDate::Simple::D8 -e 'print Date::Simple::D8::d8('20100102')."\n";' perl -MDate::Simple::D8 -e 'print Date::Simple::D8->d8('20100102')."\n";' echo "ISO:" perl -MDate::Simple::ISO -e 'print Date::Simple::ISO::today()."\n";' perl -MDate::Simple::ISO -e 'print Date::Simple::ISO->today()."\n";' perl -MDate::Simple::ISO -e 'print Date::Simple::ISO::ymd(2010,01,02)."\n";' perl -MDate::Simple::ISO -e 'print Date::Simple::ISO->ymd(2010,01,02)."\n";' perl -MDate::Simple::ISO -e 'print Date::Simple::ISO::d8('20100102')."\n";' perl -MDate::Simple::ISO -e 'print Date::Simple::ISO->d8('20100102')."\n";' The output using version 3.03.03 is: Base: 2010-01-02 2010-01-02 2010-01-02 Usage: Date::Simple::_ymd(obj_or_class, y, m, d) at /usr/lib/perl5/Date/Simple.pm line 97. 2010-01-02 Usage: Date::Simple::_d8(obj_or_class, d8) at /usr/lib/perl5/Date/Simple.pm line 70. Fmt: Can't call method "_today" on an undefined value at /usr/lib/perl5/Date/Simple/Fmt.pm line 11. 2010-01-02 Can't call method "_ymd" without a package or object reference at /usr/lib/perl5/Date/Simple/Fmt.pm line 12. 2010-01-02 Can't call method "_d8" without a package or object reference at /usr/lib/perl5/Date/Simple/Fmt.pm line 10. 2010-01-02 D8: Can't call method "_today" on an undefined value at /usr/lib/perl5/Date/Simple/D8.pm line 11. 20100102 Can't call method "_ymd" without a package or object reference at /usr/lib/perl5/Date/Simple/D8.pm line 12. 20100102 Can't call method "_d8" without a package or object reference at /usr/lib/perl5/Date/Simple/D8.pm line 10. 20100102 ISO: Can't call method "_today" on an undefined value at /usr/lib/perl5/Date/Simple/ISO.pm line 11. 2010-01-02 Can't call method "_ymd" without a package or object reference at /usr/lib/perl5/Date/Simple/ISO.pm line 12. 2010-01-02 Can't call method "_d8" without a package or object reference at /usr/lib/perl5/Date/Simple/ISO.pm line 10. 2010-01-02 The output with the patched version is: Base: 2010-01-02 2010-01-02 2010-01-02 2010-01-02 2010-01-02 2010-01-02 Fmt: 2010-01-02 2010-01-02 2010-01-02 2010-01-02 2010-01-02 2010-01-02 D8: 20100102 20100102 20100102 20100102 20100102 20100102 ISO: 2010-01-02 2010-01-02 2010-01-02 2010-01-02 2010-01-02 2010-01-02 Thanks, Chris
diff -ur libdate-simple-perl-3.03.03/lib/Date/Simple/D8.pm libdate-simple-perl-3.03.03-fixed/lib/Date/Simple/D8.pm --- libdate-simple-perl-3.03.03/lib/Date/Simple/D8.pm 2008-01-11 22:30:50.000000000 +0000 +++ libdate-simple-perl-3.03.03-fixed/lib/Date/Simple/D8.pm 2010-01-02 05:12:46.000000000 +0000 @@ -7,9 +7,50 @@ *EXPORT_OK = *Date::Simple::EXPORT_OK; *EXPORT_TAGS = *Date::Simple::EXPORT_TAGS; -sub d8 { shift->_d8(@_) } -sub today { shift->_today(@_) } -sub ymd { shift->_ymd(@_) } +sub d8 { + + # called as function + if ( $#_ == 0 ) { + return __PACKAGE__->_d8(@_); + } + + # called as method + else { + if ( ref $_[0] eq 'SCALAR' ) { + return shift->SUPER::_d8(@_); + } + else { + return shift->_d8(@_); + } + } +} + +sub today { + if ( $#_ == -1 ) { + return __PACKAGE__->_today(@_); + } + else { + return shift->_today(@_); + } +} + +sub ymd { + + # called as function + if ( $#_ == 2 ) { + return __PACKAGE__->_ymd(@_); + } + + # called as method + else { + if ( ref $_[0] eq 'SCALAR' ) { + return shift->SUPER::_ymd(@_); + } + else { + return shift->_ymd(@_); + } + } +} 1; diff -ur libdate-simple-perl-3.03.03/lib/Date/Simple/Fmt.pm libdate-simple-perl-3.03.03-fixed/lib/Date/Simple/Fmt.pm --- libdate-simple-perl-3.03.03/lib/Date/Simple/Fmt.pm 2008-01-11 22:31:17.000000000 +0000 +++ libdate-simple-perl-3.03.03-fixed/lib/Date/Simple/Fmt.pm 2010-01-02 05:12:46.000000000 +0000 @@ -7,9 +7,50 @@ *EXPORT_OK = *Date::Simple::EXPORT_OK; *EXPORT_TAGS = *Date::Simple::EXPORT_TAGS; -sub d8 { shift->_d8(@_) } -sub today { shift->_today(@_) } -sub ymd { shift->_ymd(@_) } +sub d8 { + + # called as function + if ( $#_ == 0 ) { + return __PACKAGE__->_d8(@_); + } + + # called as method + else { + if ( ref $_[0] eq 'SCALAR' ) { + return shift->SUPER::_d8(@_); + } + else { + return shift->_d8(@_); + } + } +} + +sub today { + if ( $#_ == -1 ) { + return __PACKAGE__->_today(@_); + } + else { + return shift->_today(@_); + } +} + +sub ymd { + + # called as function + if ( $#_ == 2 ) { + return __PACKAGE__->_ymd(@_); + } + + # called as method + else { + if ( ref $_[0] eq 'SCALAR' ) { + return shift->SUPER::_ymd(@_); + } + else { + return shift->_ymd(@_); + } + } +} sub new { my ( $class, $fmt, @args ) = @_; diff -ur libdate-simple-perl-3.03.03/lib/Date/Simple/ISO.pm libdate-simple-perl-3.03.03-fixed/lib/Date/Simple/ISO.pm --- libdate-simple-perl-3.03.03/lib/Date/Simple/ISO.pm 2008-01-11 22:30:00.000000000 +0000 +++ libdate-simple-perl-3.03.03-fixed/lib/Date/Simple/ISO.pm 2010-01-02 05:12:46.000000000 +0000 @@ -7,9 +7,50 @@ *EXPORT_OK = *Date::Simple::EXPORT_OK; *EXPORT_TAGS = *Date::Simple::EXPORT_TAGS; -sub d8 { shift->_d8(@_); } -sub today { shift->_today(@_); } -sub ymd { shift->_ymd(@_); } +sub d8 { + + # called as function + if ( $#_ == 0 ) { + return __PACKAGE__->_d8(@_); + } + + # called as method + else { + if ( ref $_[0] eq 'SCALAR' ) { + return shift->SUPER::_d8(@_); + } + else { + return shift->_d8(@_); + } + } +} + +sub today { + if ( $#_ == -1 ) { + return __PACKAGE__->_today(@_); + } + else { + return shift->_today(@_); + } +} + +sub ymd { + + # called as function + if ( $#_ == 2 ) { + return __PACKAGE__->_ymd(@_); + } + + # called as method + else { + if ( ref $_[0] eq 'SCALAR' ) { + return shift->SUPER::_ymd(@_); + } + else { + return shift->_ymd(@_); + } + } +} 1; diff -ur libdate-simple-perl-3.03.03/lib/Date/Simple.pm libdate-simple-perl-3.03.03-fixed/lib/Date/Simple.pm --- libdate-simple-perl-3.03.03/lib/Date/Simple.pm 2008-01-11 23:03:51.000000000 +0000 +++ libdate-simple-perl-3.03.03-fixed/lib/Date/Simple.pm 2010-01-02 05:09:05.000000000 +0000 @@ -64,10 +64,10 @@ # called as method else { if ( ref $_[0] eq 'SCALAR' ) { - return $_[0]->SUPER::_d8(@_); + return shift->SUPER::_d8(@_); } else { - return $_[0]->_d8(@_); + return shift->_d8(@_); } } } @@ -91,10 +91,10 @@ # called as method else { if ( ref $_[0] eq 'SCALAR' ) { - return $_[0]->SUPER::_ymd(@_); + return shift->SUPER::_ymd(@_); } else { - return $_[0]->_ymd(@_); + return shift->_ymd(@_); } } }