Raku 方法可以作为常规子例程处理吗?

Raku 方法可以作为常规子例程处理吗?,raku,subroutine,Raku,Subroutine,是否可以将方法分配给变量,并将它们作为类内的参数传递,类似于子例程 我知道它们可以通过self.或self访问(或任何名为显式invocant的)在其他方法中,但我想知道是否可以将方法的代码对象作为参数传递给另一个方法。您是否考虑过传递方法的名称 class Foo { method bar($a) { dd $a } } my $name = "bar"; Foo."$name"(42); # 42 该语法需要使用字符串化和括号来表示要调用该方法。如果您真的想使用方法对象并传递它,

是否可以将方法分配给变量,并将它们作为类内的参数传递,类似于子例程


我知道它们可以通过
self.
self访问(或任何名为显式invocant的)在其他方法中,但我想知道是否可以将方法的代码对象作为参数传递给另一个方法。

您是否考虑过传递方法的名称

class Foo {
    method bar($a) { dd $a }
}
my $name = "bar";
Foo."$name"(42);  # 42
该语法需要使用字符串化括号来表示要调用该方法。如果您真的想使用
方法
对象并传递它,您可以,但没有真正好的语法:

class Foo {
    method bar($a) { dd $a }
}
constant &B = Foo.^find_method("bar");
B(Foo, 42)  # 42
在本例中,常量
&B
是在编译时创建的。但您也可以在运行时调用此方法,例如,当方法的名称位于变量中时:

my $name = "bar";
my $method = Foo.^find_method($name);
$method(Foo, 42);

但是,在这种情况下,使用
“$name”(
语法可能会更好。有关更多信息,请参阅。

根据方法的作用域(几乎所有方法都是)或
my
的作用域,有两种常用机制可以将方法作为参数传递

^find\u method…
查找
的方法具有作用域
绝大多数方法都保存在类中,并在没有显式范围声明器的情况下声明。这些都(隐式地)
的作用域都是包含它们的类

要将
has
作用域方法作为参数传递,需要找到它。查找操作必须相对于包含该方法或从包含该方法的类继承的某个类启动。即使您知道该方法就在启动查找操作的类中,这也是正确的。有三种选择:

  • 如ugexe++所述,是常用的工具。正如您所料,它在中搜索继承的类,从
    ^find\u方法的类开始

  • 在极少数情况下,您可能希望使用。这将在MRO上比发票人的类更高的位置开始搜索

  • 为了完整性,我还将包括一个方法:。但请阅读文件中的注意事项。您几乎肯定不应该使用此方法,尤其是如果您希望调用此方法。请改用
    ^find\u方法之一…
    方法

因此:

&foo
引用
my
作用域方法 一些方法没有
的作用域,而是用
my
声明

对于这些词法方法,将它们作为参数传递的机制是简单地使用前缀
&
sigil引用它们,就像对
sub
s所做的那样

因此:


perl6-e'classfoo{methodbar($a){say$a}};my&foosub=->{Foo.^find_方法(“bar”)(Foo,| c)}&foosub(42)
提醒self.$m为什么是必需的可能也不是一个坏主意:方法有一个invocant,所以仅仅调用
$m
不一定会像人们认为的那样工作。(我更多地向初学者提及这一点,因为他们可能看到了这个问题,并且没有完全掌握子/方法的区别,而子/方法的区别在
&
符号化变量中并不十分明显,这些变量通常包含更类似子的块。)
“$name”(
)正是我想要的。顺便说一句,对于其他人来说,它也适用于对象实例,例如,
classfoo{methodbar($a){dd$a};我的$name=“bar”;说Foo.new.“$name”(42);#42
。谢谢
.has-way given class {
  method has-way { my $m = self.^find_method: 'm'; self.m-as-arg: $m }
  method m-as-arg ($m) { say self.$m } # has way
  method m { 'has way' }
}
.my-way given class {
  method my-way { self.m-as-arg: &m }
  method m-as-arg ($m) { say self.$m }     # my way
  my method m { 'my way' }
}