Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems using POSITIONS and Code objects

Tags:

raku

I am trying to create an object that implements POSTIONS for slicing

class Foo is Code { 
    multi method POSITIONS( Foo:D $foo: \pos) { 1,2 }
}; 
say <a b c>[Foo.new]

This errors with "Cannot make a Foo object using .new".

Making it a standalone object simply does not call POSITIONS:

class Foo { method POSITIONS { 1 } };
my Foo $foo .= new; 
say <a b c>[$foo] # No such method 'Int' for invocant of type 'Foo'␤ 

Main question here is: What are the conditions to get POSITIONS called to create a slice?

But also, the secondary question is: why can't Code objects be instantiated?

like image 856
jjmerelo Avatar asked Apr 30 '19 08:04

jjmerelo


1 Answers

I don't think that Code using new for object construction. It's a very base level class. Per the source code, what's actually needed is a Callable, and that's a simple role to apply any class. Personally I would have expected it to call CALL-ME

For your second example, we can find

multi sub postcircumfix:<[ ]>( \SELF, Any:D \pos ) is raw {
    SELF.AT-POS(pos.Int);
}

So if the type isn't contemplated in advance, it will just try to coerce to Int which your class doesn't have.

Your first one SHOULD work by simply changing it to

class Foo does Callable { 
  method POSITIONS(\foo) { 1 }
};
my Foo $foo .= new; 
say <a b c>[$foo]

However this errors, complaining that Foo doesn't implement .pos. That function isn't documented in source that I can see but implementing it does make things magically work:

class Foo does Callable { 
  method POSITIONS(|c)   { (0,1,2,(0,1),(0,2),(1,2),(0,1,2),(0..2)).pick }
  method pos(|c)         { self.POSITIONS: c }
};
my Foo $foo .= new; 
say <a b c>[$foo]

The positional argument that's passed to pos is the list that's being sliced ( (a b c) in your example), in case you want to adjust the slice based on the array contents, grep/map style.

Edit:

Actually, foolish me. pos was renamed to POSITIONS and TIO (that I was testing on) isn't updated. Because of that change, I would recommend using both pos and POSITIONS, just calling POSITIONS inside of pos for anyone on older implementations.

like image 78
user0721090601 Avatar answered Oct 21 '22 07:10

user0721090601