我需要将一些代码从外部程序传递到一个类中。
在我拥有的通用模块中(为简单起见简化为愚蠢)
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 $raku-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
那么它在类外是不可见的。因此,我的问题是:是否有另一种方法来创建一个不会自动将调用者作为变量添加到代码中的公共(public)对象代码变量?除了创建一个单独的访问器方法。
这是简短的 bash 脚本
hl
用于说明#! /bin/bash
echo '<div class="statement">'$1'</div>'
这是一个完整的 Raku 程序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.raku;';
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($_) }
}
最佳答案
问题是访问器返回的属性恰好是 Callable
.只有这样你才想用参数调用访问器的返回值。这本质上就是您通过创建自己的访问器所做的事情。
您不必实际创建自己的访问器。只需添加一个额外的括号(表示您正在调用没有任何额外参数的访问器),然后是您实际想要传递的值的括号:
class A {
has &.a = *.say; # quick way to make a Callable: { .say }
}
A.new.a()(42); # 42
或者,如果您不太喜欢括号,请考虑方法调用语法,正如 timotimo 指出的那样:
A.new.a.(42); # 42
关于class - 正确地将例程传递给对象变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54033524/