Ruby Closures: How to return args and block as a single argument to pass to a method -


suppose have method takes args , block:

def yield_if_widget(*args, &block)   if args[0].is_a?(widget)     block.call   end end 

i can call method arguments , block:

yield_if_widget(widget.new)   puts "i widgets" end 

but if have method prepares arguments , block:

def widget_and_block   args = [widget.new]   block = proc{ puts "i widgets" }    [args, block] end 

and want able pass directly first method:

yield_if_widget(*widget_and_block) 

is possible? how? assume yield_if_widget defined in library , monkey-patching not option.

to make ruby understand parameter in call method block, commercial and must put in front of it.

def widget_and_block   args = [widget.new]   block = proc{ puts "i widgets" }   [args, block] end  wab = widget_and_block #                           ⇓ yield_if_widget(*wab.first, &wab.last) 

oneliner (it won’t return yiw returns):

widget_and_block.tap { |args, cb| yield_if_widget *args, &cb } 

upd basically, ampersand in method call used “hey, convert proc , use codeblock” ruby. it’s syntax part of language, have put array content inside square brackets, not curly. that’s why ampersand should exist in source code.

on other hand, whether free modify yield_if_widget and remove ampersand parameter list:

-def yield_if_widget(*args, &block) +def yield_if_widget(*args, block) 

the code work expected, since proc instance passed last parameter , calling call method on naturally permitted.

please note, prepending ampersand last parameter method call forces #to_proc method called on it, in:

[1,2,3].reduce &:+ #⇒ 6 

the magic above works because symbol class has it’s own implementation of #to_proc method.


Comments