Проблемы с использованием POSITIONS и Code объектов - PullRequest
5 голосов
/ 30 апреля 2019

Я пытаюсь создать объект, который реализует POSTIONS для нарезки

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

Эта ошибка с «Невозможно сделать объект Foo, используя .new».

Сделать его автономнымобъект просто не вызывает POSITIONS:

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

Главный вопрос здесь: Каковы условия для вызова POSITIONS для создания среза?

Но также, вторичный вопрос: почему может't Code объекты будут созданы?

1 Ответ

5 голосов
/ 30 апреля 2019

Я не думаю, что Code использует new для строительства объекта. Это очень базовый уровень класса. Согласно исходному коду , на самом деле нужен Callable, и это простая роль для применения любого класса. Лично я бы ожидал, что он позвонит CALL-ME

Для вашего второго примера мы можем найти

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

Так что, если тип не предусмотрен заранее, он просто попытается привести к Int, которого нет у вашего класса.

Ваш первый ДОЛЖЕН работать, просто изменив его на

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

Однако это ошибки, жалующиеся на то, что Foo не реализует .pos. Эта функция не документирована в источнике, который я вижу , но ее реализация заставляет вещи работать волшебным образом:

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]

Позиционный аргумент, который передается в pos, является списком, который нарезается ((a b c) в вашем примере), на случай, если вы хотите настроить срез на основе содержимого массива, стиль grep / map.

Edit:

На самом деле, глупо меня. pos был переименован в POSITIONS, а TIO (на котором я тестировал) не обновлялся. Из-за этого изменения я бы рекомендовал использовать pos и POSITIONS, просто вызывая POSITIONS внутри pos для всех, кто работает в старых реализациях.

...