This code snippet is from plataformecs gem simple_form, wiki section about "adding custom inputs":
out << template.image_tag(object.send(attribute_name).tap {|o| break o.send(version) if version}.send('url'))
The question is simply what does the code block after .tap {} mean? Specifically the initial "break" which looks strange to me.
break argument in a block causes the block to return argument. By default, tap returns the same object as it is given, but the break will instead cause it to return whatever o.send(version) if version evaluates to.
#tap is a method that basically "passes along" the block to the next. It isn't supposed to "change" the flow of the method. For example
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}"}
It's sort of like a unix pipe, but has a chance to access the data as it goes along. like a tap.
It is supposed to take something and return the same thing to the next part of the pipe.
However, using break a will break out of the tap, and return a. That is, instead of returning what #tap would normally return (the same thing that it got), it would return a instead.
The use of #tap in this case is to pass values down the pipe "as normal", except when version is true; in that case it will send along o.send(version) instead.
Basically, the normal flow is
object.send(attribute_name).send('url')
and with tap, it's normally "unchanged". However, using break o.send(version), the flow is then instead
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With