truffleruby icon indicating copy to clipboard operation
truffleruby copied to clipboard

`binding` does not capture block

Open jonathanhefner opened this issue 2 years ago • 2 comments

@eregon Continuing from https://github.com/rails/sdoc/pull/314#issuecomment-1744589304...

Here is a reproduction stripped down from https://github.com/rails/sdoc/pull/314:

require "erb"

def render(template_string)
  ERB.new(template_string).result(binding)
end

render("<%= yield %>") { "x" }

The original test failure (before I added the workaround) was due to ERB#result raising LocalJumpError: no block given (yield). The tests all pass on CRuby >= 2.7.

jonathanhefner avatar Oct 03 '23 17:10 jonathanhefner

Thank you for the report. It can be simplified to just:

def render
  eval('yield', binding)
end

p render { "x" }

If we look at the stacktrace with eval('puts caller(0)', binding):

(eval):1:in `render' # block available here
bind.rb:2:in `eval'
bind.rb:2:in `render' # block passed here
bind.rb:5:in `<main>'

So the eval is treated like a block inside render. So there is probably an issue where we don't correctly look for the surrounding block with eval.

eregon avatar Oct 06 '23 13:10 eregon

FWIW, somewhat related: https://bugs.ruby-lang.org/issues/15554

warning: use yield in eval will not be supported in Ruby 3.

(although that's not the exact warning on CRuby master)

eregon avatar May 07 '24 13:05 eregon