此代码片段来自plataformecs gem simple_form,wiki部分关于“添加自定义输入”:
out << template.image_tag(object.send(attribute_name).tap {|o| break o.send(version) if version}.send('url'))
问题在于.tap {}后代码阻塞了什么?特别是最初的“休息”对我来说很奇怪。
答案 0 :(得分:7)
break argument
会导致块返回argument
。默认情况下,tap
返回与给定的对象相同的对象,但中断将导致它返回o.send(version) if version
求值的任何内容。
答案 1 :(得分:3)
#tap
是一种基本上将“传递”到下一个块的方法。它不应该“改变”方法的流程。例如
http://ruby-doc.org/core-2.0/Object.html#method-i-tap
(1..10) .tap {|x| puts "original: #{x.inspect}"}
.to_a .tap {|x| puts "array: #{x.inspect}"}
.select {|x| x%2==0} .tap {|x| puts "evens: #{x.inspect}"}
.map { |x| x*x } .tap {|x| puts "squares: #{x.inspect}"}
它有点像unix管道,但有机会随时访问数据。像一个水龙头。
它应该采取一些东西并将相同的东西返回到管道的下一部分。
但是,使用break a
将突破点击,返回。也就是说,它不会返回#tap
通常会返回的内容(与之相同),而是返回a
。
在这种情况下,#tap
的使用是将值“正常”传递给管道,除时version
为真;在这种情况下,它将发送o.send(version)
代替。
基本上,正常流程是
object.send(attribute_name).send('url')
和tap
,通常“不变”。但是,使用break o.send(version)
,则代之以
intermediate = object.send(attribute_name);
if version
return intermediate.send(version).send('url'); # ignore the result of intermediate
# and replace it with o.send(version)
else
return intermediate.send('url'); # maintain normal flow...it's like nothing
# was ever tapped
end
答案 2 :(得分:1)
来自文档:
The break terminates a method with an associated block
if called within the block.
因此,代码的含义是在某些条件下更改tap
的值:
break
会将o.send(version)
的结果带到下一个链。tap
。