在map
中,我可以使用方便的&:
表示法调用传入值的方法:
nums = (0..10).to_a
strs = nums.map(&:to_s)
是否有类似的东西用于调用函数,并将值作为第一个参数传入?
nums = (0..10).to_a
nums.each(puts) # error!
答案 0 :(得分:11)
免责声明:这篇文章纯粹是教育性的。 nums.each {|n| puts n}
实际上是在一个真实项目中写的唯一合理的东西。
nums.map(&:to_s)
现有的简表非常简单。 &
在符号上调用to_proc
,符号上的to_proc
就像这样定义。
class Symbol
def to_proc
Proc.new { |*args| args.shift.__send__(self, *args) }
end
end
由于此proc将开始像传递给map的常规块一样,因此在这种情况下*args
实际上是我们迭代的每个元素。我们采用args中的第一个(因为*
将参数转换为数组),并向其发送self
,self
是实际符号,例如:to_s
。传入剩余的参数。所以就像说nums.map{ |*args| args.shift.__send__(:to_s, *args) }
。
nums.each(&:puts)
我们可以轻松地重新实施to_proc
以采取不同的行动。这是一个简单的例子。
class Symbol
def to_proc
Proc.new { |*args| __send__(self, *args) }
end
end
(1..10).each(&:print) # => 12345678910
这里不是将符号名作为消息发送给元素,而是将符号作为当前上下文的方法调用,只需将迭代元素作为参数传递给它。
所以这更像是在说(1..10).each{|*args| __send__(:print, *args)}
。
nums.each(&method(:puts))
那就是说,正如纳什所指出的,你可以打电话给nums.each(&method(:puts))
。会发生什么,你得到一个使用ruby的puts
方法表示方法method
的对象。然后&
调用方法对象上的.to_proc
,将其转换为proc,它本身开始扮演传递到each
(或map
)的块的角色。传递给proc的参数(你正在迭代的每个元素)然后成为该方法的参数。整齐。
xargs
为了避免覆盖标准行为,我们可以假设实现我们自己的xargs功能,就像在shell脚本中一样。 (不要在家里这样做,太聪明也不好。)
class Symbol
def to_xargs
Proc.new{ |*args| __send__(self, *args) }
end
end
def xargs(sym)
sym.to_xargs
end
(1..10).each(&xargs(:print)) # prints 12345678910
答案 1 :(得分:9)
使用它:
nums.each(&method(:puts))
但实际上它并不短得多:)
答案 2 :(得分:2)
不完全相似,但如何:
nums.each {|n| puts n}
答案 3 :(得分:0)
实际上,当puts
收到一个数组时,它会在一个新行中打印每个元素......
将给定对象写入ios,与IO#print一样。写一条记录 在任何尚未结束的分隔符之后的分隔符(通常是换行符) 换行序列。 如果使用数组参数调用,则写入每个参数 新行上的元素。如果不带参数调用,则输出一个 记录分隔符。
因此...
puts nums