https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112013-03-08T11:53:18ZRuby Issue Tracking SystemRuby master - Feature #8046: allow Object#extend to take a blockhttps://bugs.ruby-lang.org/issues/8046?journal_id=373762013-03-08T11:53:18ZAnonymous
<ul></ul><p>=begin<br>
There are two ways to do this - make the extend block execute in the context of the receiver's singleton class, or make it execute in the context of a new module to be mixed in to the receiver's singleton class.</p>
<p>For example:</p>
<pre><code>def extend(&bk)
singleton_class.class_eval(&bk)
end
</code></pre>
<p>or</p>
<pre><code>def extend(&bk)
singleton_class.send(:include, Module.new(&bk))
end
</code></pre>
<p>Which should it be?<br>
=end</p> Ruby master - Feature #8046: allow Object#extend to take a blockhttps://bugs.ruby-lang.org/issues/8046?journal_id=373772013-03-08T13:05:09Zphluid61 (Matthew Kerwin)matthew@kerwin.net.au
<ul></ul><p>charliesome (Charlie Somerville) wrote:</p>
<blockquote>
<p>There are two ways to do this - make the extend block execute in the<br>
context of the receiver's singleton class, or make it execute in the<br>
context of a new module to be mixed in to the receiver's singleton class.<br>
...<br>
Which should it be?</p>
</blockquote>
<p>I'd think more like the former, as that doesn't inject a new anonymous Module into the singleton_class's #ancestors.</p>
<p>Does class_eval do anything dramatically different from module_eval (i.e. is the block handled differently in either case)?</p> Ruby master - Feature #8046: allow Object#extend to take a blockhttps://bugs.ruby-lang.org/issues/8046?journal_id=373792013-03-08T15:53:24Zdavid_macmahon (David MacMahon)davidm@astro.berkeley.edu
<ul></ul><p>On Mar 7, 2013, at 6:53 PM, charliesome (Charlie Somerville) wrote:</p>
<blockquote>
<p>There are two ways to do this</p>
<p>def extend(&bk)<br>
singleton_class.class_eval(&bk)<br>
end</p>
<p>or</p>
<p>def extend(&bk)<br>
singleton_class.send(:include, Module.new(&bk))<br>
end</p>
</blockquote>
<p>At the risk of being overly pedantic, since we're talking about Object#extend, I think it would be more like:</p>
<p>def extend(*modules, &bk)<br>
# extend singleton_class with modules, if any<br>
singleton_class.class_eval(&bk) if bk<br>
end</p>
<p>or</p>
<p>def extend(module=nil, &bk)<br>
# extend singleton_class with modules, if any<br>
singleton_class.send(:include, Module.new(&bk)) if bk<br>
end</p>
<p>Which raises another question: what would be the order of extending if #extend is passed one or more modules <em>and</em> given a block? IOW, should the passed in module(s) be included first thereby giving the block the opportunity to override them or vice versa (or should this be explicitly disallowed)? I guess I'd favor the first way (include module(s) first, then block can override).</p>
<p>On the original question I tend to agree with <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/6023">@phluid61 (Matthew Kerwin)</a> that it would be preferable to avoid inserting an anonymous Module in the singleton_class's ancestors. Would having the anonymous module provide any advantage over not having it?</p>
<p>Thanks,<br>
Dave</p>
<p>P.S. Why "singleton_class.send(:include, Module.new(&bk))" instead of just "singleton_class.include(Module.new(&bk))"? Are these somehow not equivalent?</p> Ruby master - Feature #8046: allow Object#extend to take a blockhttps://bugs.ruby-lang.org/issues/8046?journal_id=373822013-03-08T16:27:18Zphluid61 (Matthew Kerwin)matthew@kerwin.net.au
<ul></ul><p>david_macmahon (David MacMahon) wrote:</p>
<blockquote>
<p>Which raises another question: what would be the order of extending if<br>
#extend is passed one or more modules <em>and</em> given a block? IOW, should<br>
the passed in module(s) be included first thereby giving the block the<br>
opportunity to override them or vice versa (or should this be explicitly<br>
disallowed)? I guess I'd favor the first way (include module(s) first,<br>
then block can override).</p>
</blockquote>
<p>That's the order Facets uses: <a href="https://github.com/rubyworks/facets/blob/master/lib/core/facets/kernel/extend.rb" class="external">https://github.com/rubyworks/facets/blob/master/lib/core/facets/kernel/extend.rb</a></p>
<blockquote>
<p>On the original question I tend to agree with <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/6023">@phluid61 (Matthew Kerwin)</a> that it would be<br>
preferable to avoid inserting an anonymous Module in the<br>
singleton_class's ancestors. Would having the anonymous module provide<br>
any advantage over not having it?</p>
</blockquote>
<p>My reasoning against was that on calling it a second time, there would be a second anonymous module, and so on.</p>
<blockquote>
<p>P.S. Why "singleton_class.send(:include, Module.new(&bk))" instead of<br>
just "singleton_class.include(Module.new(&bk))"? Are these somehow not<br>
equivalent?</p>
</blockquote>
<p>#include is private, so can't be called directly from outside the singleton_class object.</p> Ruby master - Feature #8046: allow Object#extend to take a blockhttps://bugs.ruby-lang.org/issues/8046?journal_id=373902013-03-08T21:19:38Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>Without a module, it'd not be #extend but #singleton_class_eval.</p> Ruby master - Feature #8046: allow Object#extend to take a blockhttps://bugs.ruby-lang.org/issues/8046?journal_id=688992017-12-25T18:15:12Znaruse (Yui NARUSE)naruse@airemix.jp
<ul><li><strong>Target version</strong> deleted (<del><i>2.6</i></del>)</li></ul>