就像你想的那樣, 在類的定義中可以聲明和定義方法。你期望不高的甚至文檔中都很少提及是用 my
關鍵字聲明的免費浮點方法。現在為什么你想要:
my method foo(SomeClass:D:) { self }
明顯的答案是元對象協議中的 add_method 方法, 在 Rakudo 里你能找到它:
src/core/Bool.pm
32: Bool.^add_method('pred', my method pred() { Bool::False });
33: Bool.^add_method('succ', my method succ() { Bool::True });
35: Bool.^add_method('enums', my method enums() { self.^enum_values });
這種方法還有另外一種更詭異的用法。你可能很想知道在鏈式方法調用中究竟發生了什么。我們可以扯開最上面的那個表達式并插入一個短的變量, 輸出我們的調試, 并且繼續鏈式調用。好的名字很重要并且把它們浪費在一個短變量上沒有必要。
<a b c>.&(my method ::(List:D) { dd self; self } ).say;
# output
# ("a", "b", "c")
# (a b c)
沒有顯式調用我們就不能沒有名字, 因為 Perl 6 不允許我們這樣做, 所以我們使用了空的作用域 ::
以使解析器高興。使用一個合適的調用, 我們就不需要它了。還有, 那個匿名方法不是 List 中的一員。我們需要使用后綴 .&
來調用它。如果我們需要多次使用那個方法我們可以把它拉出來并給它一個名字。
my multi method debug(List:D:) { dd self; self };
<a b c>.&debug.say;
# output
("a", "b", "c")
(a b c)
或者, 如果我們想允許回調的話, 我們可以把它作為默認參數賦值。
sub f(@l, :&debug = my method (List:D:){self}) { @l.&debug.say };
f <a b c>, debug => my method ::(List:D){dd self; self};
# output
#("a", "b", "c")
# (a b c)
在 Perl 6 中基本上所有的東西都是類, 包括方法。 如果它是類它可以是一個對象并且我們能在我們喜歡的任何地方溜進去。