> -----Original Message----- > From: Larry Wall [mailto:[EMAIL PROTECTED] > > On Fri, Apr 23, 2004 at 02:07:16PM -0400, Austin Hastings wrote: > : I guess I'm more strongly attached to the sigil than I > realized. IMO, if you > : have > : > : $obj handles 'a'; > : > : and put an arrayref in $obj, then you get what's coming: > iteration. But if > : you have > : > : @obj handles 'a'; > : > : then you know it's an array, or array subtype, and delegate > array-things to > : it. > : > : So I prefer cases 1:s, 1:n, and a:a instead of 1:s, 1:a, and a:n. > > But a delegating attribute is not an alias for its delegatee, or if it is, > should maybe not be thought of as one. The question is, if you've gone > and delegated to another object, should this class be mucking around with > the innards of the array object as if it owned it? I don't think so. > I think it's better to have the reference in a scalar variable to remind > you of that it's a different object. On the other hand, the list of > handlers *is* a valid concern for this class, and it shouldn't have to > go poking down through a reference to get at that list. It has a valid > use for the @ sigil.
Aha! A light comes on: Delegation is not the same as subordination. The C<handles> delegation syntax declares "formal" delegation, meaning that the handler is treated as a separate object. Thus, by default delegate objects are stored in scalar references. However, you may delegate to many objects by using the @handler or %handler syntaxes. That's an explanation/ideology I can sink my teeth into. Can I declare a const reference and have it optimized away? class Queue { has @:elements; has $:array_delegate handles <push pop int> = \@:elements is const; } > > : > : Also, it's not clear: > : > : > : > : "first one that succeeds" > : > : > : > : Does that mean "First one for which a matching > : > : method exists" or does it mean "First one for which > : > : a method exists that does not C<fail> or return > : > : undef or some other badness"? > : > > : > The latter is the intent. > : > : Then array handling is doing some sort of .+method > : dispatch instead of "plain old dispatch", no? > > No, it's plain old, I expect. > > : I think this should be made explicit. At first glance, > : I'd hate to lose C<return undef;> or C<return FALSE;> > : as an option just because than means "keep searching for > : handlers". > : > : Can you tell us why the initial spec calls for continuing > : search? > > It doesn't. The question in question had an "or", which > seem in your thinking to have mutated into an "and". The > "badness" in the question in question is provided by "next > METHOD", not by returning false or undef. So if a method > knows it can handle something, all it does is return the > value, whatever that is. Okay. So one way to fail would be a subtype violation: class Row { has @:flavors handles <print_row>; } type OddRow ::= Row where $:row_num mod 2 == 1; type EvenRow ::= Row where $:row_num mod 2 == 0; $even_row = new Row(row_num => 0); $odd_row = new Row(row_num => 1); @:flavors = ( $even_row, $odd_row ); $row.print_row; Right? (I know, this could be done with a multimethod.) So what are the ways to fail? -> Subtype incompatibility, as above -> Invocation signature: Does the @:handlers list become a wierd sort of tunable multimethod dispatch? -> C<fail> keyword? -> C<next METHOD> obviously -> Others? =Austin