> From whence did it get its Item container?

OK, my brain made a wrong turn some time on Tuesday.

Let me review the basics.

From S02:

|$x| may be bound to any object, including any object that can be bound to any other sigil.

Perl variables have two associated types: their "value type" and their "implementation type".
Value type = "of", implementation type is the type of the container itself.

   my $spot is Scalar;             # this is the default

From S03:

A new form of assignment is present in Perl 6, called /binding/, used in place of typeglob assignment. It is performed with the |:=| operator. Instead of replacing the value in a container like normal assignment, it replaces the container itself. For instance:

   my $x = 'Just Another';
   my $y := $x;
   $y = 'Perl Hacker';

From S12:

Method calls on mutable scalars always go to the object contained in the scalar (autoboxing value types as necessary):

   $result = $object.doit();
   $length = "mystring".codes;

Method calls on non-scalar variables just calls the |Array|, |Hash| or |Code| object bound to the variable:

   $elems = @array.elems;
   @keys  = %hash.keys;
   $sig   = &sub.signature;

Use the prefix |VAR| macro on a scalar variable to get at its underlying |Scalar| object:

   if VAR($scalar).readonly {...}


So, if you say

   my $x;

then $x is bound to a newly-created Scalar (not worrying about conflating the name the Role and the concrete type at this point).

   my $x = 'Just Another';

Now the "item assignment" operates on the container, storing the Str instance within it. $x is bound to a container, and the container contains (only) one Str instance.

Basically, I was thinking that scalar variables always are bound to item containers which contain the actual value. In fact, this was originally drilled into me: containers vs values! That variables always directly hold some kind of container. I suppose that's been changed at some point, perhaps long ago, but the synopses didn't dissuade me from that early belief.

Anyway, as for your (Henry) example from Rakudo:

   my $x = 1, 2, 3;

According to the synopses, this should be analogous to the previous example, where $x now is bound to an item that contains a Capture containing 3 Ints.

Assuming Capture vs Array is simply out of date implementation, just focus on the parameter passing. $x is bound to a Scalar. But What I Mean is for the formal parameter @y to get bound to the item in the container, the list of Ints.
===>    How does that happen?

Now back to straightening out my misconceptions about scalars _always_ holding item containers. If $x is bound to an Array, for example, the compiled code can't be doing the indirection innately.

So it follows that the method forwarding is a property of the object that the method is originally called on. That is, the Scalar (and any "tied" item container implementations) are written to forward all methods to the contained object. The compiler sees $x.foo() and doesn't know anything about $x other than that it's some object, so it codes a message dispatch to it. If $x holds a normal object, the foo method gets called via the normal dispatching rules. But Scalar implements something that catches all methods and forwards them to the contained item.

===>    Right?

That would imply that if a scalar happened to contain another scalar, e.g.
   my $x = Scalar.new;
($x is bound to a Scalar which contains a Scalar which contains undef)
then any method called on $x would trigger the same behavior when the contained object gets it, and be forwarded all the way down, no matter how many Scalars I nested in this manner.

So how does VAR work? It can't just wrap another level around the original object to cancel out the automatic indirection. It can't tell the compiler to generate different code, since the code knows nothing about this interesting property of scalars. Instead it must return a proxy that knows how to trigger the actual methods on the scalar, avoiding the forwarding behavior of normal method calls.

===>   Is that right?

Thanks for your help everyone. I hope to give back just as much, once I've caught back up. In any case, what I learn I will document for all who come later.


Reply via email to