Is there a ruby ​​method that returns the value of a block?


I know about Object#tap, which takes a value and returns that value. But is there a method that takes a block and returns the value evaluated by the block?

To improve my code in this answer (which is more complicated than the snippet below), I'd like to change

deck.index("A").tap {|index|
  STDERR.puts "Result of indexing for #{"A".inspect} is #{index.inspect}"

, which has "A" repeated, into

def my_method(*args)
  yield *args

deck = ['A', 'B', 'C']
my_method("A") {|value| deck.index(value).tap {|index|
  STDERR.puts "Result of indexing for #{value.inspect} is #{index.inspect}"
} }
# Result of indexing for "A" is 0
# => 0

What you're looking for is essentially the equivalent of let in Lisp or OCaml — something that allows you to temporarily bind a value to an identifier without introducing a new variable into the larger scope. There isn't anything that lets you do such a thing with that syntax in Ruby. The equivalent Ruby would be:

lambda {|value| deck.index(value).tap {|index|
  STDERR.puts "Result of indexing for #{value.inspect} is #{index.inspect}"
} }.call 'A'

You could of course just write a method like:

def let(*values)
  yield *values