On Mon, May 30, 2005 at 05:00:26PM +0100, Carl Franks wrote: : I have a class that normally takes a list of named arguments. : I also want to be able to handle a single argument. : : class Foo { : multi method new (Class $class: Str $date) { : return $class.bless(date => $date); : } : : submethod BUILD ($.date, $.time, $.offset) { : # some error checking here : } : } : : my $foo = Foo.new('2005-05-30'); : : # : Is this the correct way to handle my scenario?
I think you probably want a "multi sub" there. In the current plan, "multi method" is an MMD dispatch that occurs *after* dispatch to the class. (Though it's possible we changed that and I've just forgotten...) : My explicit 'new' method should only handle the case of : a single argument - otherwise the 'new' method : inherited from Class will handle a list of named : arguments. Saying multi sub new (Class $class, Str $date) {...} should have that effect, provided you call it as new(Foo,'2005-05-30'). However, when called as Foo.new('2005-05-30'), all the multi subs defined in the class hierarchy add themselves to the dispatch list as if they were ordinary single-invocant methods, with additional invocants treated as tie-breakers in the case that there are multiple multi-subs in a single class. Or to put it another way, all class-based instances of "multi sub" behave like "multi method" when invoked via SMD. It dispatches first to the class, then looks to see if there are multiple methods of that name within the class. This is probably not what you want in this case, unfortunately. We have specified that there's some kind of pragmatic way to turn Foo.new() into MMD from the get-go, but that seems a bit crude. So maybe that kind of dispatch needs to be reformulated a bit. Perhaps Foo.new() should be forced to ordinary MMD any time any parent class defines "multi sub new", so that all invocants are considered. Or maybe Foo.new() is still not quite "ordinary MMD" in that it only considers that subset of multis defined in Foo or parent classes of Foo. If that dispatch fails it retries under ordinary MMD, including methods defined outside of the classes in question. (Or another way to say that might be that such non-class multis are always ordered after all the class multis when invoked as Foo.new('2005-05-30'), unlike with new(Foo,'2005-05-30'), which pays no attention to class boundaries.) : My explicit BUILD submethod is called, regardless : of which 'new' method is called, correct? Yes, as long as the constructor in question calls the .bless built-in, which always BUILDALL. (Though you could, of course, also redefine BUILDALL evilly to bypass calling the correct BUILDs. But don't do that.) Larry