我如何参考新的?
How do I take a reference to new?
假设我有以下代码:
my constant @suits = <Clubs Hearts Spades Diamonds>;
my constant @values = 2..14;
class Card {
has $.suit;
has $.value;
# order is mnemonic of "$value of $suit", i.e. "3 of Clubs"
multi method new($value, $suit) {
return self.bless(:$suit, :$value);
}
}
它定义了一些花色和一些价值,以及成为一张牌的意义。
现在,要构建一副牌,我基本上需要将花色和值的叉积应用于构造函数。
执行此操作的天真的方法当然是使用循环进行迭代:
my @deck = gather for @values X @suits -> ($v, $c) {
take Card.new($v, $c);
}
但这是 Raku,我们有 a cross
function that can take a function as an optional argument!,所以我当然会这样做!
my @deck = cross(@values, @suits, :with(Card.new));
# Unexpected named argument 'with' passed
# in block <unit> at .\example.raku line 36
...等等,不。
这个呢?
my @deck = cross(@values, @suits):with(Card.new);
# Unexpected named argument 'with' passed
# in block <unit> at .\example.raku line 36
仍然没有。也许参考?
my @deck = cross(@values, @suits):with(&Card.new);
# ===SORRY!=== Error while compiling D:\Code\Raku/.\example.raku
# Illegally post-declared type:
# Card used at line 36
我在某处读到我可以使用 []
将函数转换为中缀运算符
my @deck = cross(@values, @suits):with([Card.new]);
# Unexpected named argument 'with' passed
# in block <unit> at .\example.raku line 36
那也不行。
如果 类 应该只是模块,那么我不应该能够传递函数引用吗?
另外为什么说'with'是出乎意料的?如果我的直觉是正确的,那么它实际上抱怨的是输入的类型,而不是命名参数。
报错信息确实令人费解
:with
参数需要一个 Callable。 Card.new
不是 可调用对象。如果你把它写成 :with( { Card.new($^number, $^suit) } )
,它似乎可以工作。
请注意,我没有使用 $^value, $^suit
,因为它们按字母顺序排列的顺序不同,因此会以错误的顺序生成值。有关该语法的更多信息,请参阅 The ^ twigil。
错误是 LTA,this使它稍微好一点。
回到你的问题:你可以找到对应于Card.new
和^find_method
的代码对象。然而,那是行不通的,因为 Card.new
实际上需要 3 个参数:调用者(又名 self
)、$value
和 $suit
.而 cross
函数只会传递值和花色。
你的问题的标题是“我如何引用新的?”,但这并不是你真正想要做的。
Raku 就是 Raku,你实际上可以参考 new
。
my $ref = Card.^lookup('new');
虽然你不能随心所欲地使用它。
$ref(2,'Clubs'); # ERROR
问题是方法将 class 或实例作为第一个参数。
$ref(Card, 2,'Clubs');
您可以使用 .assuming
添加它。
$ref .= assuming(Card);
$ref(2,'Clubs');
但这并不比创建块 lambda 好多少
$ref = { Card.new( |@_ ) }
$ref(2,'Clubs');
所有这些工作:
cross( @values, @suits ) :with({Card.new(|@_)}) # adverb outside
cross( @values, @suits, :with({Card.new(|@_)}) ) # inside at end
cross( :with({Card.new(|@_)}), @values, @suits ) # inside at beginning
@values X[&( {Card.new(|@_)} )] @suits # cross meta-op with fake infix op
do {
sub new-card ($value,$suit) { Card.new(:$value,:$suit) }
@values X[&new-card] @suits
}
do {
sub with ($value,$suit) { Card.new(:$value,:$suit) }
cross(@values,@suits):&with
}
假设我有以下代码:
my constant @suits = <Clubs Hearts Spades Diamonds>;
my constant @values = 2..14;
class Card {
has $.suit;
has $.value;
# order is mnemonic of "$value of $suit", i.e. "3 of Clubs"
multi method new($value, $suit) {
return self.bless(:$suit, :$value);
}
}
它定义了一些花色和一些价值,以及成为一张牌的意义。
现在,要构建一副牌,我基本上需要将花色和值的叉积应用于构造函数。
执行此操作的天真的方法当然是使用循环进行迭代:
my @deck = gather for @values X @suits -> ($v, $c) {
take Card.new($v, $c);
}
但这是 Raku,我们有 a cross
function that can take a function as an optional argument!,所以我当然会这样做!
my @deck = cross(@values, @suits, :with(Card.new));
# Unexpected named argument 'with' passed
# in block <unit> at .\example.raku line 36
...等等,不。 这个呢?
my @deck = cross(@values, @suits):with(Card.new);
# Unexpected named argument 'with' passed
# in block <unit> at .\example.raku line 36
仍然没有。也许参考?
my @deck = cross(@values, @suits):with(&Card.new);
# ===SORRY!=== Error while compiling D:\Code\Raku/.\example.raku
# Illegally post-declared type:
# Card used at line 36
我在某处读到我可以使用 []
my @deck = cross(@values, @suits):with([Card.new]);
# Unexpected named argument 'with' passed
# in block <unit> at .\example.raku line 36
那也不行。
如果 类 应该只是模块,那么我不应该能够传递函数引用吗?
另外为什么说'with'是出乎意料的?如果我的直觉是正确的,那么它实际上抱怨的是输入的类型,而不是命名参数。
报错信息确实令人费解
:with
参数需要一个 Callable。 Card.new
不是 可调用对象。如果你把它写成 :with( { Card.new($^number, $^suit) } )
,它似乎可以工作。
请注意,我没有使用 $^value, $^suit
,因为它们按字母顺序排列的顺序不同,因此会以错误的顺序生成值。有关该语法的更多信息,请参阅 The ^ twigil。
错误是 LTA,this使它稍微好一点。
回到你的问题:你可以找到对应于Card.new
和^find_method
的代码对象。然而,那是行不通的,因为 Card.new
实际上需要 3 个参数:调用者(又名 self
)、$value
和 $suit
.而 cross
函数只会传递值和花色。
你的问题的标题是“我如何引用新的?”,但这并不是你真正想要做的。
Raku 就是 Raku,你实际上可以参考 new
。
my $ref = Card.^lookup('new');
虽然你不能随心所欲地使用它。
$ref(2,'Clubs'); # ERROR
问题是方法将 class 或实例作为第一个参数。
$ref(Card, 2,'Clubs');
您可以使用 .assuming
添加它。
$ref .= assuming(Card);
$ref(2,'Clubs');
但这并不比创建块 lambda 好多少
$ref = { Card.new( |@_ ) }
$ref(2,'Clubs');
所有这些工作:
cross( @values, @suits ) :with({Card.new(|@_)}) # adverb outside
cross( @values, @suits, :with({Card.new(|@_)}) ) # inside at end
cross( :with({Card.new(|@_)}), @values, @suits ) # inside at beginning
@values X[&( {Card.new(|@_)} )] @suits # cross meta-op with fake infix op
do {
sub new-card ($value,$suit) { Card.new(:$value,:$suit) }
@values X[&new-card] @suits
}
do {
sub with ($value,$suit) { Card.new(:$value,:$suit) }
cross(@values,@suits):&with
}