https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112014-06-21T07:19:24ZRuby Issue Tracking SystemRuby master - Bug #9967: `define_method(:name, &block)` breaks the use of the block on its ownhttps://bugs.ruby-lang.org/issues/9967?journal_id=473162014-06-21T07:19:24ZJonRowe (Jon Rowe)hello@jonrowe.co.uk
<ul></ul><p>I tried to work around this bug by duplicating the proc with <code>.dup</code> but it seems that dup doesn't actually duplicate the proc. So I went digging through the C code and discovered that <code>define_method</code> actually does try to dup the proc with <code>proc_dup(body)</code> (<a href="https://github.com/ruby/ruby/blob/trunk/proc.c#L1748" class="external">https://github.com/ruby/ruby/blob/trunk/proc.c#L1748</a>) but the proc dup code seems not do actually duplicate the block but just copy the pointers across (<a href="https://github.com/ruby/ruby/blob/trunk/proc.c#L106" class="external">https://github.com/ruby/ruby/blob/trunk/proc.c#L106</a>), in Ruby 1.8.7 (where this bug does not occur) the implementation of proc dup is completely different and seems to actually dup the proc. (<a href="https://github.com/ruby/ruby/blob/v1_8_7_374/eval.c#L8596" class="external">https://github.com/ruby/ruby/blob/v1_8_7_374/eval.c#L8596</a>)</p> Ruby master - Bug #9967: `define_method(:name, &block)` breaks the use of the block on its ownhttps://bugs.ruby-lang.org/issues/9967?journal_id=792682019-07-11T02:38:42Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Closed</i></li></ul><p>This was fixed between Ruby 2.2 and 2.3:</p>
<pre><code>$ ruby22 s3.rb
ruby 2.2.10p489 (2018-03-28 revision 63023) [x86_64-openbsd]
Without define_method: foo
With define_method: s3.rb:11:in `block in foo': super called outside of method (NoMethodError)
from s3.rb:18:in `bar'
from s3.rb:11:in `foo'
from s3.rb:27:in `<main>'
$ ruby23 s3.rb
ruby 2.3.8p459 (2018-10-18 revision 65136) [x86_64-openbsd]
Without define_method: foo
With define_method: foo
</code></pre>