Re: Subclassing DateTime?
> On April 29, 2017 at 8:08 PM Zefram <zef...@fysh.org> wrote: > > > Thomas (HFM) Wyant wrote: > >It seems to me that in at least some such cases subclassing > >DateTime would be a better alternative. > > You've run into the terrible factoring of the DateTime system. All three > of the modules you named already suffer from it, but subclassing DateTime > would make things worse. For subclassing to be the right answer, > the objects of your classes would have to be everything that DateTime > objects are, plus something that you're adding. But one of the things > that DateTime objects are is Gregorian, which your objects are not. > > -zefram Well, before I adopted the nasssty Hobbitsesss calendar I wrote my own never-published Shire Calendar module that _was_ in fact a subclass of DateTime. It overrode a pot load of public methods, of course, plus private methods _maybe_future_dst_warning(), _month_length(), _new(), _rd2ymd(), and _ymd2rd(). And, subject to the caveat that I never explored the corner cases (such as infinite times), it worked. But I was nervous about all the overridden private methods, plus the fact that I was relying on the DateTime internals (other than the ones I overrode) not to croak on a non-numeric day, plus probably other ad-hoc assumptions I do not now recall. I suppose what I was hoping was that someone would come out of the woodwork and say something like "Oh, yes, there is a subclassing guide in such-and-such obscure place, and this list of private methods (including the ones I listed) should really be considered protected ..." What I was trying to do before I wrote the note was to write a module (working name DateTime::Calendar::Framework) that was not a subclass of DateTime, but that passed the DateTime test suite. Then someone doing a non-Gregorian module could start from that and override what they needed to override (a lot in the case of the Shire calendar, or DateTime::Calendar::Discordian), but only public methods, and define any attributes they felt like. At the moment it passes all the tests through t/41cldr-format.t (except for t/09greg.t, which tests _rmd2yd and _yd2rmd, and which I skip, and except for a couple that access DateTime internals, which I modified). But t/42duration-class.t actually tests the subclassing of DateTime. I guess if I can't get it sorted out I can always mark the test TODO, document the associated restriction, and truck on. Tom
Re: Subclassing DateTime?
Thomas (HFM) Wyant wrote: >It seems to me that in at least some such cases subclassing >DateTime would be a better alternative. You've run into the terrible factoring of the DateTime system. All three of the modules you named already suffer from it, but subclassing DateTime would make things worse. For subclassing to be the right answer, the objects of your classes would have to be everything that DateTime objects are, plus something that you're adding. But one of the things that DateTime objects are is Gregorian, which your objects are not. -zefram
Subclassing DateTime?
Dear list, A pattern seen frequently in DateTime::Calendar-like modules is to put the functionality in a top-level module which holds a DateTime object to do the DateTime-specific stuff. If you want anything like the full DateTime functionality this involves writing a bunch of methods on the order of sub some_method { $_[0]->{dt}->some_method( @_[ 1 .. $#_ ] ) } Fortunately if I turn off strict refs the methods can be defined in a loop by assigning an anonymous subroutine to a glob. But the above is not the only subroutine template, merely the most common. It seems to me that in at least some such cases subclassing DateTime would be a better alternative. But I find no documentation on how to do this. I made a sort of middle-level pass through http://datetime.perl.org/, and browsed the mailing list archives back to 2012 or so. Did I miss the documentation somehow? If so, could someone give me a pointer to it? The main issue I see are: * Where can I, in some supported way, stash any extra attribute values? * Is there a naming convention to avoid method name conflicts (i.e. unintentional overrides), especially for private methods? You can stop reading here unless you are curious about what motivated the question. Feel free to snip it in a reply. My reason for asking is that I have adopted a couple modules that use this pattern: DateTime::Calendar::Christian and DateTime::Fiction::JRRTolkien::Shire. Both were missing some DateTime functionality of interest to me -- a lot in the latter case. A bunch of methods had to be written to get it, and these methods have a strong family resemblance. When I was going through the process of adopting DateTime::Calendar::Christian I was offered DateTime::Calendar::Liturgical::Christian. I refused, because I do not have the religious background to understand the first thing about what feast we celebrate today or what color altar cloth to use; DateTIme::Calendar::Christian just does the Julian calendar before the conversion date and the Gregorian calendar after. Well, I decided to take another look at DateTime::Calendar::Liturgical::Christian, found myself writing those same methods for a second or third time, and decided maybe some laziness was in order. I started writing a class that does not inherit from DateTime but uses the $self->{dt} pattern, AND that passes all the DateTime tests. This is mostly just drudgery, but the methods that take two DateTime arguments (e.g. subtract_datetime()) are turning out to be problematic. So I thought, belatedly, that I would look into doing the simple obvious thing rather than the complex obscure thing. Thanks, Tom Wyant