Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there some model to use to understand containers, references, raw, rw, \ in Raku?

In perl5 you could think of \ as a pointer and dereference that pointer by prefixing with the specific sigil or ->. You had also typeglobs that made the symbol explicit. In perl5 the underlying C code structures would give a good model to relate to the syntax of the language.

In Raku you have a set of concepts like: containers (and non-containers?), binding, assignment with = and :=, different traits in arguments like raw and rw and \ (which seems not related to perl5's \ ?).

Is there some underlying model that I can use to determine what I am actually using at a certain point in code and which options I have?

like image 923
Konrad Eisele Avatar asked Jul 24 '20 09:07

Konrad Eisele


1 Answers

When you write this:

my $a = 'b';

$a = 'c';

say $a;

What happens is something that is sort-of like this:

my $a := Scalar.new( value => 'b' );

$a.set-value('c');

say $a.get-value();

Basically a new Scalar object is created and $a is a pointer to it.


Of course it isn't quite that simple as you can't even call .new on a Scalar and have it do anything.

There is also a lot more information stored inside of the Scalar object. For example the type information and any default.

Really what you think about $ variables is all contained inside of the Scalar object.

Normally this container tries to be completely transparent. You can however get at the Scalar object with the .VAR method/macro.

my Int $a is default(42) = 3;

my $var = $a.VAR;

say $var.name;    # $a
say $var.of;      # (Int)
say $var.default; # 42
say $var.self;    # 3

There are other ways that this transparency gets more translucent than transparent.

sub foo ( \v ){ # the \ is so it isn't seen as a Type name
  say v.VAR.name
  v = 22;
}
foo $a; # $a
say $a; # 22

That is because the Scalar gets passed to the subroutine, not the value inside of the Scalar. The Scalar is always passed to the function call, it's just that the function often decides to do something other than allowing you raw access to the original Scalar.

In the following, the value inside of the passed Scalar is copied to a new Scalar that doesn't allow modification.

sub bar ( $v ){
  # $v = 3; # ERROR
}
bar $a

If you had declared $v as is rw or is raw, $v would actually be a pointer to the Scalar container you passed in just like \v above. (\v is very similar to is raw.)

like image 83
Brad Gilbert Avatar answered Nov 14 '22 12:11

Brad Gilbert