https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112009-07-31T06:16:11ZRuby Issue Tracking SystemRuby master - Feature #1844: Immediates Should Not Respond to :duphttps://redmine.ruby-lang.org/issues/1844?journal_id=50132009-07-31T06:16:11Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul></ul><p>=begin</p>
<a name="This-is-a-bit-radical-opinion-I-admit"></a>
<h1 >This is a bit radical opinion, I admit.<a href="#This-is-a-bit-radical-opinion-I-admit" class="wiki-anchor">¶</a></h1>
<p>From my point of view, "determining" whether an object has a method is a wrong idea.<br>
Instead you should just call that method. Which is:</p>
<p>begin<br>
obj.method<br>
rescue<br>
...<br>
end</p>
<p>instead of:</p>
<p>if obj.respond_to? :method then<br>
obj.method<br>
else<br>
...<br>
end</p>
<p>Why you should avoid respond_to? is that it is nothing special; just a method which can be overridden. So respond_to? is sometimes not realiable for various reasons. If you want to make sure, the safest way is to see if it actually quacks like a duck.<br>
=end</p> Ruby master - Feature #1844: Immediates Should Not Respond to :duphttps://redmine.ruby-lang.org/issues/1844?journal_id=50192009-07-31T08:56:38Zhongli (Hongli Lai)hongli@phusion.nl
<ul></ul><p>=begin<br>
I disagree.</p>
<ul>
<li>Exceptions are expensive.</li>
<li>Rescuing a specific exception requires a multi-line statement, while respond_to? allows one to write "bar.foo if bar.respond_to?(:foo)"</li>
<li>How do you know the exception was raised by the method itself and not by a method called by the method?</li>
</ul>
<p>You say respond_to? is not always reliable. I think it should be reliable.<br>
=end</p> Ruby master - Feature #1844: Immediates Should Not Respond to :duphttps://redmine.ruby-lang.org/issues/1844?journal_id=50202009-07-31T09:01:56Zbitsweat (Jeremy Daer)jeremydaer@gmail.com
<ul></ul><p>=begin<br>
I agree that simply calling the method is ideal. However, rescuing an exception for such a common case may be very expensive in an inner loop.</p>
<p>Rails introduced Object#duplicable? for this reason: <a href="http://github.com/rails/rails/blob/2c2ca833a531d825d9b46e501b564a52a8a69358/activesupport/lib/active_support/core_ext/object/duplicable.rb" class="external">http://github.com/rails/rails/blob/2c2ca833a531d825d9b46e501b564a52a8a69358/activesupport/lib/active_support/core_ext/object/duplicable.rb</a></p>
<p>So you say:</p>
<p>if obj.duplicable?<br>
obj.dup<br>
else<br>
...<br>
end</p>
<p>I would prefer that dup simply returned self for immediate objects, though. It's almost always what I'd prefer.<br>
=end</p> Ruby master - Feature #1844: Immediates Should Not Respond to :duphttps://redmine.ruby-lang.org/issues/1844?journal_id=50212009-07-31T09:07:26Zbitsweat (Jeremy Daer)jeremydaer@gmail.com
<ul></ul><p>=begin<br>
Hongli, respond_to? may not be reliable in the case of proxy objects. Also, calling respond_to? adds an implicit API requirement that simply calling the method does not. For example: <a href="http://github.com/rails/rails/commit/78af2710695973bbd747738d175fb3b1f488df6c" class="external">http://github.com/rails/rails/commit/78af2710695973bbd747738d175fb3b1f488df6c</a><br>
=end</p> Ruby master - Feature #1844: Immediates Should Not Respond to :duphttps://redmine.ruby-lang.org/issues/1844?journal_id=50242009-07-31T09:46:40Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul></ul><p>=begin<br>
Well, I was about to write the case of Rake::TaskArguments :p I agree that respond_to? should be reliable, but doing wrong here is fairly easy, especially when you write your method_missing to tweak method dispatches.</p>
<p>Anyway when getting back to :dup story, I'm not against to make it more "reliable". But there seems to be several menu here:</p>
<ul>
<li>respond_to?(:dup) to be false and calling dup to raise exception. Runpaint's original suggestion.</li>
<li>respond_to?(:dup) to be true and dup to return self. Jeremy's idea.</li>
</ul>
<p>Maybe we need some more discussion for it?<br>
=end</p> Ruby master - Feature #1844: Immediates Should Not Respond to :duphttps://redmine.ruby-lang.org/issues/1844?journal_id=50252009-07-31T10:03:50Zdblack (David Black)dblack@rubypal.com
<ul></ul><p>=begin<br>
Hi --</p>
<p>On Fri, 31 Jul 2009, Hongli Lai wrote:</p>
<blockquote>
<p>Issue <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Immediates Should Not Respond to :dup (Rejected)" href="https://redmine.ruby-lang.org/issues/1844">#1844</a> has been updated by Hongli Lai.</p>
<p>I disagree.</p>
<ul>
<li>Exceptions are expensive.</li>
<li>Rescuing a specific exception requires a multi-line statement,<br>
while respond_to? allows one to write "bar.foo if<br>
bar.respond_to?(:foo)"</li>
</ul>
</blockquote>
<p>But you probably wouldn't do:</p>
<pre><code>x = y.dup if y.respond_to?(:dup)
</code></pre>
<p>because if it didn't, you'd end up with nil.</p>
<blockquote>
<ul>
<li>How do you know the exception was raised by the method itself and<br>
not by a method called by the method?</li>
</ul>
</blockquote>
<p>That's always a risk with exceptions, though, isn't it?</p>
<blockquote>
<p>You say respond_to? is not always reliable. I think it should be reliable.</p>
</blockquote>
<p>I think that the exceptions and their messages can be useful in cases<br>
like:</p>
<pre><code>(0.0..10.0).each {} # TypeError: can't iterate from float
</code></pre>
<p>as opposed to having float ranges not respond to #each, and having to<br>
ask each range whether it responds to #each. I tend to see the<br>
immediate.dup thing as similar to that.</p>
<p>David</p>
<p>--<br>
David A. Black / Ruby Power and Light, LLC / <a href="http://www.rubypal.com" class="external">http://www.rubypal.com</a><br>
Q: What's the best way to get a really solid knowledge of Ruby?<br>
A: Come to our Ruby training in Edison, New Jersey, September 14-17!<br>
Instructors: David A. Black and Erik Kastner<br>
More info and registration: <a href="http://rubyurl.com/vmzN" class="external">http://rubyurl.com/vmzN</a></p>
<p>=end</p> Ruby master - Feature #1844: Immediates Should Not Respond to :duphttps://redmine.ruby-lang.org/issues/1844?journal_id=50262009-07-31T10:10:21Zdblack (David Black)dblack@rubypal.com
<ul></ul><p>=begin<br>
Hi --</p>
<p>On Fri, 31 Jul 2009, Shyouhei Urabe wrote:</p>
<blockquote>
<p>Issue <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Immediates Should Not Respond to :dup (Rejected)" href="https://redmine.ruby-lang.org/issues/1844">#1844</a> has been updated by Shyouhei Urabe.</p>
<p>Anyway when getting back to :dup story, I'm not against to make it<br>
more "reliable". But there seems to be several menu here:</p>
<ul>
<li>respond_to?(:dup) to be false and calling dup to raise exception.<br>
Runpaint's original suggestion.</li>
<li>respond_to?(:dup) to be true and dup to return self. Jeremy's idea.</li>
</ul>
</blockquote>
<p>My own difficulty with Jeremy's idea is that 1 isn't a duplicate of 1.<br>
In general, if x.dup returns x, it's not returning a duplicate of x,<br>
so the method name becomes problematic.</p>
<p>In other words, I'm not sure about having dup be a no-op. On the other<br>
hand, I would very much <em>not</em> like to start seeing #respond_to? every<br>
time dup is used.</p>
<p>David</p>
<p>--<br>
David A. Black / Ruby Power and Light, LLC / <a href="http://www.rubypal.com" class="external">http://www.rubypal.com</a><br>
Q: What's the best way to get a really solid knowledge of Ruby?<br>
A: Come to our Ruby training in Edison, New Jersey, September 14-17!<br>
Instructors: David A. Black and Erik Kastner<br>
More info and registration: <a href="http://rubyurl.com/vmzN" class="external">http://rubyurl.com/vmzN</a></p>
<p>=end</p> Ruby master - Feature #1844: Immediates Should Not Respond to :duphttps://redmine.ruby-lang.org/issues/1844?journal_id=50272009-07-31T10:19:10Ztmat (Tomas Matousek)tomas.matousek@microsoft.com
<ul></ul><p>=begin<br>
What about adding Kernel#dup? method that is an alias of Kernel#dup: a class that cannot be duplicated would implement dup that throws an exception and dup? that returns nil or self?</p>
<p>Tomas</p>
<p>-----Original Message-----<br>
From: David A. Black [<a href="mailto:dblack@rubypal.com" class="email">mailto:dblack@rubypal.com</a>]<br>
Sent: Thursday, July 30, 2009 6:10 PM<br>
To: <a href="mailto:ruby-core@ruby-lang.org" class="email">ruby-core@ruby-lang.org</a><br>
Subject: <a href="https://blade.ruby-lang.org/ruby-core/24635">[ruby-core:24635]</a> Re: [Bug <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Immediates Should Not Respond to :dup (Rejected)" href="https://redmine.ruby-lang.org/issues/1844">#1844</a>] Immediates Should Not Respond to :dup</p>
<p>Hi --</p>
<p>On Fri, 31 Jul 2009, Shyouhei Urabe wrote:</p>
<blockquote>
<p>Issue <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Immediates Should Not Respond to :dup (Rejected)" href="https://redmine.ruby-lang.org/issues/1844">#1844</a> has been updated by Shyouhei Urabe.</p>
<p>Anyway when getting back to :dup story, I'm not against to make it<br>
more "reliable". But there seems to be several menu here:</p>
<ul>
<li>respond_to?(:dup) to be false and calling dup to raise exception.<br>
Runpaint's original suggestion.</li>
<li>respond_to?(:dup) to be true and dup to return self. Jeremy's idea.</li>
</ul>
</blockquote>
<p>My own difficulty with Jeremy's idea is that 1 isn't a duplicate of 1.<br>
In general, if x.dup returns x, it's not returning a duplicate of x, so the method name becomes problematic.</p>
<p>In other words, I'm not sure about having dup be a no-op. On the other hand, I would very much <em>not</em> like to start seeing #respond_to? every time dup is used.</p>
<p>David</p>
<p>--<br>
David A. Black / Ruby Power and Light, LLC / <a href="http://www.rubypal.com" class="external">http://www.rubypal.com</a><br>
Q: What's the best way to get a really solid knowledge of Ruby?<br>
A: Come to our Ruby training in Edison, New Jersey, September 14-17!<br>
Instructors: David A. Black and Erik Kastner<br>
More info and registration: <a href="http://rubyurl.com/vmzN" class="external">http://rubyurl.com/vmzN</a></p>
<p>=end</p> Ruby master - Feature #1844: Immediates Should Not Respond to :duphttps://redmine.ruby-lang.org/issues/1844?journal_id=50302009-07-31T17:07:38Zgodfat (Lin Jen-Shin)godfat@godfat.org
<ul></ul><p>=begin<br>
There's try_dup in extlib [0], which returns self in various class,<br>
i.e. NilClass, Symbol, TrueClass, FalseClass, Numeric, and Module.<br>
I am not sure, but I think this is used to prevent from side-effect.</p>
<p>I am wondering, if what we want is not duplicate something,<br>
but ensure there's no side-effect, why not use another method?<br>
For example, dup_or_freeze [1] or so...</p>
<p>My two cents.</p>
<p>[0] <a href="http://github.com/datamapper/extlib/" class="external">http://github.com/datamapper/extlib/</a><br>
[1] I know that immediates aree not frozen in the beginning.<br>
=end</p> Ruby master - Feature #1844: Immediates Should Not Respond to :duphttps://redmine.ruby-lang.org/issues/1844?journal_id=50552009-08-02T15:10:14Zrunpaint (Run Paint Run Run)runrun@runpaint.org
<ul></ul><p>=begin</p>
<blockquote>
<blockquote>
<ul>
<li>Exceptions are expensive.</li>
<li>Rescuing a specific exception requires a multi-line statement,<br>
while respond_to? allows one to write "bar.foo if<br>
bar.respond_to?(:foo)"</li>
</ul>
</blockquote>
<p>But you probably wouldn't do:</p>
<p>x = y.dup if y.respond_to?(:dup)</p>
<p>because if it didn't, you'd end up with nil.</p>
</blockquote>
<p>The reason that I noticed this behaviour was because I had an Array that contained Fixnums, Floats, and Symbols, along with other objects. I wanted to #dup those that could be duplicated so I could process them safely. My instictual way to code this was ary.select{|e| e.respond_to?(:dup)}... Which failed.</p>
<p>That Rails and other libraries implement their own approaches to this problem suggests that it needs fixing in the core.</p>
<blockquote>
<blockquote>
<p>You say respond_to? is not always reliable. I think it should be reliable.</p>
</blockquote>
<p>I think that the exceptions and their messages can be useful in cases<br>
like:</p>
<p>(0.0..10.0).each {} # TypeError: can't iterate from float</p>
<p>as opposed to having float ranges not respond to #each, and having to<br>
ask each range whether it responds to #each. I tend to see the<br>
immediate.dup thing as similar to that.</p>
</blockquote>
<p>I disagree. This isn't about a specific invocation of an object, as is the case for Range objects with Float values; it's whole classes that never allow #dup to be called claiming that it can be, then raising when it is. These are two rather distinct cases.</p>
<p>Either Jeremy's suggestion or fixing #respond_to? is fine by me.<br>
=end</p> Ruby master - Feature #1844: Immediates Should Not Respond to :duphttps://redmine.ruby-lang.org/issues/1844?journal_id=50672009-08-03T03:01:47Zdblack (David Black)dblack@rubypal.com
<ul></ul><p>=begin<br>
Hi --</p>
<p>On Sun, 2 Aug 2009, Run Paint Run Run wrote:</p>
<blockquote>
<p>I wrote:</p>
<blockquote>
<p>I think that the exceptions and their messages can be useful in cases<br>
like:</p>
<p>(0.0..10.0).each {} # TypeError: can't iterate from float</p>
<p>as opposed to having float ranges not respond to #each, and having to<br>
ask each range whether it responds to #each. I tend to see the<br>
immediate.dup thing as similar to that.</p>
</blockquote>
<p>I disagree. This isn't about a specific invocation of an object, as<br>
is the case for Range objects with Float values; it's whole classes<br>
that never allow #dup to be called claiming that it can be, then<br>
raising when it is. These are two rather distinct cases.</p>
</blockquote>
<p>Yes and no. There could be a FloatRange class that doesn't mix in<br>
Enumerable, or something like that. It doesn't really matter how it's<br>
implemented; the point is that you can't do:</p>
<pre><code>ranges.each {|r| r.map ... }
</code></pre>
<p>with an array of ranges, without risking an exception, just as you<br>
can't dup each of an array of arbitrary objects without that risk.</p>
<blockquote>
<p>Either Jeremy's suggestion or fixing #respond_to? is fine by me.</p>
</blockquote>
<p>It's not really fixing #respond_to? (which is correctly reporting that<br>
these objects can resolve the message "dup"). It would be a matter of<br>
undef'ing #dup for certain classes. I have mixed emotions about it. On<br>
the one hand, if (say) nil can't be duped, there's no really<br>
compelling reason for it to respond to #dup. On the other hand,<br>
there's a pretty common pattern of methods defined in Object that<br>
exist mainly to be overridden (to_s, inspect, ==, ===, etc.). Usually<br>
they're not overridden to raise an exception, but there's no<br>
underlying reason why they shouldn't be.</p>
<p>David</p>
<p>--<br>
David A. Black / Ruby Power and Light, LLC / <a href="http://www.rubypal.com" class="external">http://www.rubypal.com</a><br>
Q: What's the best way to get a really solid knowledge of Ruby?<br>
A: Come to our Ruby training in Edison, New Jersey, September 14-17!<br>
Instructors: David A. Black and Erik Kastner<br>
More info and registration: <a href="http://rubyurl.com/vmzN" class="external">http://rubyurl.com/vmzN</a></p>
<p>=end</p> Ruby master - Feature #1844: Immediates Should Not Respond to :duphttps://redmine.ruby-lang.org/issues/1844?journal_id=104002010-04-21T21:43:18Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul><li><strong>Assignee</strong> set to <i>matz (Yukihiro Matsumoto)</i></li><li><strong>Target version</strong> set to <i>2.0.0</i></li></ul><p>=begin<br>
Hi,</p>
<p>This is apparently not a bug but feature request.<br>
I move this to Feature tracker.</p>
<p>--<br>
Yusuke Endoh <a href="mailto:mame@tsg.ne.jp" class="email">mame@tsg.ne.jp</a><br>
=end</p> Ruby master - Feature #1844: Immediates Should Not Respond to :duphttps://redmine.ruby-lang.org/issues/1844?journal_id=104102010-04-21T23:41:07ZRickDeNatale (Rick DeNatale)rick.denatale@gmail.com
<ul></ul><p>=begin<br>
On Thu, Jul 30, 2009 at 9:10 PM, David A. Black <a href="mailto:dblack@rubypal.com" class="email">dblack@rubypal.com</a> wrote:</p>
<blockquote>
<p>Hi --</p>
<p>On Fri, 31 Jul 2009, Shyouhei Urabe wrote:</p>
<blockquote>
<p>Issue <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Immediates Should Not Respond to :dup (Rejected)" href="https://redmine.ruby-lang.org/issues/1844">#1844</a> has been updated by Shyouhei Urabe.</p>
<p>Anyway when getting back to :dup story, I'm not against to make it<br>
more "reliable". But there seems to be several menu here:</p>
<ul>
<li>respond_to?(:dup) to be false and calling dup to raise exception.<br>
Runpaint's original suggestion.</li>
<li>respond_to?(:dup) to be true and dup to return self. Jeremy's idea.</li>
</ul>
</blockquote>
<p>My own difficulty with Jeremy's idea is that 1 isn't a duplicate of 1.<br>
In general, if x.dup returns x, it's not returning a duplicate of x,<br>
so the method name becomes problematic.</p>
</blockquote>
<p>I agree with Jeremy.</p>
<p>The reason I dup an object is so that if I can change the state of the<br>
duplicate without affecting the original object.</p>
<p>Since immediate objects are immutable, I can't change their state so<br>
having dup return the original is not an issue.</p>
<p>Having to code around the possibility that dup will throw an error<br>
seems worse than just having immediates just handle them in what seems<br>
a reasonable fashion.</p>
<p>As a reference point, in Smalltalk the SmallInteger copy method<br>
returns the receiver, this is a direct analogy to Fixnum#dup</p>
<p>--<br>
Rick DeNatale</p>
<p>Blog: <a href="http://talklikeaduck.denhaven2.com/" class="external">http://talklikeaduck.denhaven2.com/</a><br>
Github: <a href="http://github.com/rubyredrick" class="external">http://github.com/rubyredrick</a><br>
Twitter: <a class="user active user-mention" href="https://redmine.ruby-lang.org/users/386">@RickDeNatale (Rick DeNatale)</a><br>
WWR: <a href="http://www.workingwithrails.com/person/9021-rick-denatale" class="external">http://www.workingwithrails.com/person/9021-rick-denatale</a><br>
LinkedIn: <a href="http://www.linkedin.com/in/rickdenatale" class="external">http://www.linkedin.com/in/rickdenatale</a></p>
<p>=end</p> Ruby master - Feature #1844: Immediates Should Not Respond to :duphttps://redmine.ruby-lang.org/issues/1844?journal_id=104232010-04-22T05:11:13Zspatulasnout (B Kelly)billk@cts.com
<ul></ul><p>=begin</p>
<p>Rick DeNatale wrote:</p>
<blockquote>
<p>On Thu, Jul 30, 2009 at 9:10 PM, David A. Black <a href="mailto:dblack@rubypal.com" class="email">dblack@rubypal.com</a> wrote:</p>
<blockquote>
<p>My own difficulty with Jeremy's idea is that 1 isn't a duplicate of 1.<br>
In general, if x.dup returns x, it's not returning a duplicate of x,<br>
so the method name becomes problematic.</p>
</blockquote>
<p>I agree with Jeremy.</p>
<p>The reason I dup an object is so that if I can change the state of the<br>
duplicate without affecting the original object.</p>
</blockquote>
<p>Agreed. I don't recall ever having dup'd an object to satisfy<br>
an abstract desire to "create a duplicate". Rather, I use #dup<br>
as a means to an end, and in my experience it's an end that would<br>
be best served by having immediate objects simply return their<br>
immutable selves.</p>
<p>I'm having trouble even inventing a contrived example where<br>
having #dup succeed for immediates would lead to an undesirable<br>
or unexpected result, in terms of how we would then put the<br>
dup'd values to use.</p>
<p>I don't find it useful to adhere extremely rigidly to the<br>
dictionary definition of the word 'dup', as i don't use #dup for<br>
the end purpose of making duplicates, but to ensure that potential<br>
modifications to the dup'd object won't modify the original.</p>
<p>Having #dup succeed for immediate objects would match my intent,<br>
and if pressed about adherence to the definition of the word 'dup',<br>
I'd want to call this a case of DWIMNWIS. (Do What I Mean Not What<br>
I Say.)</p>
<p>Regards,</p>
<p>Bill</p>
<p>=end</p> Ruby master - Feature #1844: Immediates Should Not Respond to :duphttps://redmine.ruby-lang.org/issues/1844?journal_id=133582010-09-14T16:25:45Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Assigned</i></li></ul><p>=begin</p>
<p>=end</p> Ruby master - Feature #1844: Immediates Should Not Respond to :duphttps://redmine.ruby-lang.org/issues/1844?journal_id=238482012-02-14T22:16:04Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Rejected</i></li></ul><p>I'm rejecting this feature ticket because no progress has been<br>
made for a long time. See <a href="https://blade.ruby-lang.org/ruby-core/42391">[ruby-core:42391]</a>.</p>
<p>My personal opinion.</p>
<p>I might miss somthing, but I cannot understand the motivation<br>
well. When we duplicate an object, we then usually modify the<br>
object, don't we? To modify them, we must eventually check the<br>
type. I wonder why this feature is needed.</p>
<p>It makes no sense (to me) to compare a method that raises<br>
NotImplementedError with Immediate.dup. They are different.<br>
In an extreme case, Kernel#raise always raise an exception.<br>
Do you think respond_to?(:raise) should return false?</p>
<p>--<br>
Yusuke Endoh <a href="mailto:mame@tsg.ne.jp" class="email">mame@tsg.ne.jp</a></p>