> -----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


Reply via email to