Am 03.04.2012 17:10, schrieb Daniel Carrera:
(1..10).WHAT   # =>  Range()

@foo = 1..10;

@foo.WHAT     # =>  Array()


When you assign a range to @foo, the result is an array. Something
similar happens, for example, if you assign a scalar to @foo... The
context of the assignment causes Perl 6 to convert the value into an
array.

I was wondering if this sort of magic is limited to pre-defined types
(arrays, hashes, etc) or if it can be extended to any class that I
might create.

It's something inbetween. The distinction between the list assignment and scalar assignment is syntactic. In the case of list assignment, @foo.STORE(1..10) is called under the hood.

For example, imagine hat I create a 'Vector' class to do
basic linear algebra. Imagine that it works this way:

my @vec = Vector.new(  1,2,3,4 )

@vec * 3   # =>  ( 3,6,9,12 )

In other words, the '*' operator is overloaded to behave like scalar x
vector multiplication in linear algebra. I was thinking that it would
be neat if instead you could do this:


my Vector @vec;

@vec = 1,2,3,4;

@vec.WHAT   #  =>  Vector()


You can, very nearly. You just need to write

my @vec is Vector;

because you really want to change the type of the container, not just of the contents (my Vector @vec would be an array containing Vector objects).

This syntax doesn't quite work yet in Rakudo (though it wouldn't be too hard to get running), but this works:

use v6;

class Vector is Array {}
multi sub infix:<*>(Vector $a, Real $b) {
    Vector.new( $a.list X* $b );
}

my @vec := Vector.new(1, 2, 3, 4);
say @vec.WHAT;
say @vec * 3;

Output:

Vector()
3 6 9 12

Using binding := instead of assignment replaces the array container with a Vector object.

You can even write

my @vec := Vector.new;
@vec = 1, 2, 3, 4;

and get the same output.

(you can also override the .STORE method of a scalar, but that's a bit creepy if you ask me).

Cheers,
Moritz

Reply via email to