From: ynnor@... Date: 2017-06-06T08:12:46+00:00 Subject: [ruby-core:81588] [Ruby trunk Misc#13634] NilClass is lying about respond_to?(:clone) Issue #13634 has been reported by rovf (Ronald Fischer). ---------------------------------------- Misc #13634: NilClass is lying about respond_to?(:clone) https://bugs.ruby-lang.org/issues/13634 * Author: rovf (Ronald Fischer) * Status: Open * Priority: Normal * Assignee: ---------------------------------------- I put this under "Misc", because I'm not sure, whether this is a bug, a feature request, or maybe a deliberate (but for me obscure) decision in language design: NilClass (and Fixnum) do not support clone. That's fine. However, nil.respons_to?(:clone) returns true. This means that we *can* ask nil to clone itself (we don't get a NoMethod error), it's just trying to do so throws an exception. I stumbled over this problem when I had an collection of objects of different types, and wanted to apply :clone to some of them. My code went approximately like this: object = collection[key] return object.respond_to?(:clone) ? object.clone : object This doesn't work, if object is nil, true, false, a Symbol or a Fixnum, because all of them claim to respond to :clone. Of course, there is a trivial workaround (I just have to rescue the exception), but I find this language design not really intuitive. I think there are two possibilites, how this can be made better: (1) If we decide, that nil is not clonable (because there can be only one nil), then respond_to?(:clone) should IMHO simply be false. (2) However, there might be even be a reason why :clone should be applicable. Note that the usual semantics of clone is to do a shallow copy (for instance, when we 'clone' a nested array). If we want to have a deep copy, the usual approach is Marshal.load(Marshal.dump(object)). Now the odd thing is that we can not "shallowly copy" nil, i.e. nil.clone is forbidden, but we can do a deep copy, i.e. Marshal.load(Marshal.dump(nil)) works. So, an alternative would be to have nil.clone simply return the identical object. Both (1) seems to me a sound solution. The solution (2) has the drawback that we can't guarantee anymore that x.clone has a different object id than x, but is probably the behaviour a programmer would intuitively expect. -- https://bugs.ruby-lang.org/ Unsubscribe: