Мне нужно передать некоторый код из внешней программы в класс.
В универсальном модуле, который у меня есть (для простоты сводится к глупости)
class A {
has &.hl;
submethod BUILD( :&!hl ) {}
}
В другом месте программы,У меня
use A;
my &hl = -> $st {
my $p = shell "hl $st", :in,:out;
$p.out.slurp
};
my $statement = 'my $perl6-variable = "Helloooo";'
my $first = &hl($statement);
my A $a .= new(:&hl);
my $second = $a.hl( $statement );
$first
будет обработан и будет содержать ожидаемые результаты.
При $second
я получу ошибку времени выполнения
Too many positionals passed; expected 1 argument but got 2
Очевидно, что подпрограмма в классе предоставляется как инвокантом, так и параметром $s
.
Переписывая класс, чтобы обеспечить пользовательский метод доступа:
class A {
has &!hl;
submethod BUILD( :&!hl ) {}
method process-it( Str $s --> Str ) { &!hl( $s ) }
}
# elsewhere
my $second = $a.process-it( $statement );
Затем оба $first
и $second
выполняется без ошибок и будет содержать те же результаты.
При обращении к hl
внутри класса инвокант не добавляется, но если он не объявлен как &.hl
, то он не виден внеclass.
Поэтому мой вопрос таков: есть ли другой способ создать переменную общедоступного объектного кода, которая автоматически не добавит инвокант в качестве переменной в код?Кроме создания отдельного метода доступа.
Вот короткий скрипт bash hl
для иллюстрации
#! /bin/bash
echo '<div class="statement">'$1'</div>'
Вот полная программа Perl 6
use v6.c;
class A {
has &!highlighter; # also tried with has &highlighter
submethod BUILD( :&!highlighter ) {}
method process-it( Str $s --> Str ) {
&!highlighter( $s )
}
}
sub MAIN() {
my @strings = 'my $v = "Hello World";', 'my $w = $v.perl;';
my $proc;
my $proc-supply;
my &highlighter = -> $s {
my $p = shell "./hl '$s' ", :in,:out;
$p.out.slurp
}
for @strings {
say .&highlighter
}
my A $a .= new(:&highlighter);
for @strings { say $a.highlighter($_) }
# own accessor
for @strings { say $a.process-it($_) }
}