红宝石世界的初学者,我想做类似的事情:
[1,2.0,"a",2].select(&:is_a?(Integer))
但像这样它绝对行不通......
有任何想法吗?
红宝石世界的初学者,我想做类似的事情:
[1,2.0,"a",2].select(&:is_a?(Integer))
但像这样它绝对行不通......
有任何想法吗?
你不能做你要求的事情,因为当你使用&
语法时,你必须使用不带参数的方法。
但是,如果您出于某种原因确实想做这样的事情,则需要创建一个不采用如下参数的方法:
class Object
def is_an_integer?
is_a? Integer
end
end
然后你可以这样做:
[1,2.0,"a",2].select(&:is_an_integer)
&:method_name
是 . 的语法糖&:method.to_proc
。枚举器喜欢select
和不接受一个块并将枚举器的每个元素产生给传递的块。那是:
[1,2,3].select &:even?
相当于:
p = :even.to_proc
[1,2,3].select {|val| p.yield(val) }
由于只有枚举器产生的参数才会产生给 proc,因此您必须将它们包含在源列表中。也就是说,我们可能期望:
[[1, Integer]].select &:is_a?
以导致:
select {|*args|, p.yield(*args) }
但是,请记住,这p
不是绑定到任何特定类的方法!它将尝试在传递的参数上调用给定的方法。因此,它将尝试Array#is_a?
不带参数调用,而不是把参数喷出来并调用Integer#is_a?(Integer)
.
因此,为了实现这一点,我们必须以某种方式创建一个绑定传递参数的 proc,然后使用传递的参数调用产生的接收器上的给定方法。我们可以通过向 Symbol 类添加一个方法来做到这一点:
class Symbol
def with_args(*args)
proc {|receiver| receiver.send(self, *args) }
end
end
[1, "a"].select &:is_a?.with_args(Integer)
虽然它可能不是非常干净,但它确实有效。