Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Yielding in an anonymous block

Tags:

ruby

I'm not making sense of the following behavior (see also in this SO thread):

def def_test
  puts 'def_test.in'
  yield if block_given?
  puts 'def_test.out'
end

def_test do
  puts 'def_test ok'
end

block_test = proc do |&block|
  puts 'block_test.in'
  block.call if block
  puts 'block_test.out'
end

block_test.call do
  puts 'block_test'
end

proc_test = proc do
  puts 'proc_test.in'
  yield if block_given?
  puts 'proc_test.out'
end

proc_test.call do
  puts 'proc_test ok'
end

Output:

def_test.in
def_test ok
def_test.out
block_test.in
block_test ok
block_test.out
proc_test.in
proc_test.out

I don't mind resorting to explicitly declaring the &block variable and calling it directly, but I'd more ideally like to make some sense of why I end up needing to.

like image 789
Denis de Bernardy Avatar asked Jul 07 '11 15:07

Denis de Bernardy


1 Answers

block_given? considers def scope, not lambda scope:

def test
  l = lambda do
    yield if block_given?
  end
  l.call
end

test { puts "In block" }
like image 86
Victor Moroz Avatar answered Oct 17 '22 11:10

Victor Moroz