5

Shouldn't this just work ?

use v6;

my $data1 = Buf.new(1, 2, 3);
my Buf $data2;

my $n = $data1.bytes;

for ^$n
{
  my $ch = $data1.shift;
  $data2.push($ch)
}             

I'm getting

$ raku bufpush.raku
Cannot resolve caller push(Buf:U: Int:D); none of these signatures matches:
    (Buf:D: int $got, *%_)
    (Buf:D: Int:D $got, *%_)
    (Buf:D: Mu:D $got, *%_)
    (Buf:D: Blob:D $buf, *%_)
    (Buf:D: **@values, *%_)
  in block <unit> at bufpush.raku line 11
zentrunix
  • 2,098
  • 12
  • 20

1 Answers1

5
Cannot resolve caller push(Buf:U: Int:D); none of these signatures matches:
    (Buf:D: int $got, *%_)
    (Buf:D: Int:D $got, *%_)
    (Buf:D: Mu:D $got, *%_)
    (Buf:D: Blob:D $buf, *%_)
    (Buf:D: **@values, *%_)
  in block <unit> at bufpush.raku line 11

Comparing the found signature with each of the suggested ones reveals a near-match:

(Buf:D: Int:D $got, *%_)

The only difference is that Buf:D vs Buf:U thing (called the invocant marker) at the front of the signature. It specifies the invocant (the object / thing the method can be invoked on). It's optional, by default it's allowed to call a method both on an object as well as the class. Most often the invocant marker is used to specify whether the method is only allowed to be called on type objects (e.g. Blob.allocate) or on concrete objects (e.g. Blob.gist). Buf:D means a Defined Buf object, Buf:U means an Undefined Buf type object.

So from the above we can learn that the code tried to call push on a type object, so $data2 is undefined. Changing my Buf $data2; to my Buf $data2 .= new; fixes the issue.

Patrick Böker
  • 3,173
  • 1
  • 18
  • 24
  • 1
    Thank, it's clear now. But shoudn't `my Buf $data2` create an empty Buf object ? That would be my understanding. – zentrunix Jun 11 '22 at 17:08
  • 1
    No, it doesn't. It creates a scalar with a constraint to `Buf`, and by default a `Buf` type object in it. `my $data = Buf.new` or `my Buf $data .= new` will create an empty `Buf` object. – Elizabeth Mattijsen Jun 11 '22 at 18:31
  • 1
    I tried with `$ raku -e "my Str $c; say $c"` and it works as @ElizabethMattijsen said ... I think it's against expectations, but anyway – zentrunix Jun 11 '22 at 21:21
  • Some people have said that Raku is "strangely consistent" :-) – Elizabeth Mattijsen Jun 11 '22 at 22:09