Let's pick up this old mail before it gets completely warnocked ;-)

For the record, this discussion only applies to scalar implementation
types. For example for Arrays I expect things to work by overriding the
method postcircumfix:<[ ]>.

Also I'm far from being an expert on this field, so feel free to correct me.

Kyle Hasselbacher wrote:
> My patchwork readings lead me to believe I could test Perl 6's
> tie-like feature with something like the below code, which I don't
> expect to even compile, what with '???' in places.  My question is:
> am I on the right track?  Obviously there are details I haven't nailed
> down, and any guidance would be appreciated.

I think the you're on the right track, but I'm not sure about some details.
For one it scares me to think that we do a full-blown multi dispatch on
every FETCH/STORE operation, which might become quite expensive.

> # Scalar is Any does Container does Order
> 
> class ScalarTester is Scalar {
>     has @.log;
> 
>     multi STORE ( Any $thing ) {
>         @.log.push( STORE => $thing );

These non-operator routines should all be methods; 'multi' by itself
defaults to subs, not methods (iirc).

Also you'd have to quote STORE; otherwise it's interpreted as a named
argument, which Array.push doesn't know how to handle.

>         nextsame;
>     }
>     multi FETCH() {
>         @.log.push( 'FETCH' );
>         nextsame;
>     }
>     multi TEMP() {
>         @.log.push( 'TEMP' );
>         nextsame;
>     }
> 
>     multi infix:<=> ( ??? ) {
>         @.log.push( 'infix:<=>' );
>         nextsame;
>     }

If we do FETCH/STORE, then the assignment will call the STORE method for
you, so there's no reason to override infix:<=>.
Also note that
my $x = 3;
foo($x);
does dispatch based on the type of the stored thing (Int), not on the
type of the Scalar container

>     multi infix:<:=> ( ??? ) {
>         @.log.push( 'infix:<:=>' );
>         nextsame;
>     }

Binding replaces the container; the container implementation shouldn't
see this. (Not sure though)

>     multi infix:<::=> ( ??? ) {
>         @.log.push( 'infix:<::=>' );
>         nextsame;
>     }

Same here.

>     multi infix:<=:=> ( ??? ) {
>         @.log.push( 'infix:<=:=>' );
>         nextsame;
>     }

I also don't expect =:= to be handled by the container; but rather as a
very general sub that compares memory addresses at some point.

>     # since Scalar does Order, there are ~20 other methods to test.
> }
> 
> my $t is ScalarTester;
> is $t.log, (), 'log is empty';
> lives_ok { $t = 'bughunt' }, 'can assign to test scalar';
> is $t.log, ( 'STORE' => 'bughunt' ), 'log reflects assignment';
> lives_ok { my $discard = $t }, 'can access test scalar';
> is $t.log, ( 'STORE' => 'bughunt', 'FETCH' ), 'log reflects access';

Cheers,
Moritz

Reply via email to