红宝石世界的初学者,我想做点什么:
[1,2.0,"a",2].select(&:is_a?(Integer))
但是这样肯定不起作用......
有什么想法吗?
答案 0 :(得分:2)
您无法满足要求,因为当您使用&
语法时,必须使用不带参数的方法。
但是,如果你出于某些原因想要做类似的事情,你需要制作一个不带参数的方法:
class Object
def is_an_integer?
is_a? Integer
end
end
然后你可以这样做:
[1,2.0,"a",2].select(&:is_an_integer)
答案 1 :(得分:1)
&: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,然后使用传递的args在生成的接收器上调用给定的方法。我们可以通过向Symbol类添加一个方法来实现:
class Symbol
def with_args(*args)
proc {|receiver| receiver.send(self, *args) }
end
end
[1, "a"].select &:is_a?.with_args(Integer)
虽然它可能不是很干净,但确实有效。