Bug #11064
closed#singleton_methods for objects with special singleton_class returns an empty array
Added by rbjl (Jan Lelis) over 9 years ago. Updated over 1 year ago.
Description
def nil.bla
42
end
# works
nil.bla #=> 42
nil.singleton_method(:bla) #=> #<Method: NilClass#bla>
NilClass.instance_methods.include? :bla #=> true
# does not work
nil.singleton_methods #=> []
Updated by matz (Yukihiro Matsumoto) almost 3 years ago
nil
does not have its singleton class, but NilClass
plays the role of the singleton class (since nil
is the only instance of NilClass
).
So a singleton method definition defines a method in NilClass
. It's a kind of special treatment of singleton methods. Same for true
and false
.
We have several options:
- keep the behavior as it is, since
nil
does not have a singleton class -
nil.singleton_methods
should return methods defined inNilClass
(same forTrueClass
andFalseClass
)
Both have their own trade-offs. Either is OK for me but I slightly prefer the former, since it's easier.
Matz.
Updated by sawa (Tsuyoshi Sawada) almost 3 years ago
matz (Yukihiro Matsumoto) wrote in #note-1:
nil
does not have its singleton class, butNilClass
plays the role of the singleton class
I would appreciate it if @matz (Yukihiro Matsumoto) could kindly explain what the difference is between "being a singleton class" and "playing the role of a singleton class".
At the moment, I cannot understand at all how they are different. I am actually puzzled by a related comment by matz: https://bugs.ruby-lang.org/issues/12084#note-6. Why can we not simply say "NilClass
is the singleton class of nil
"?
Updated by Eregon (Benoit Daloze) over 2 years ago
- Related to Bug #11063: Special singleton class should return true for singleton_class? test added
Updated by matz (Yukihiro Matsumoto) almost 2 years ago
@sawa (Tsuyoshi Sawada) Singleton classes are in principle only accessed using the singleton_class
method or the singleton class notation. Implementation wise, FL_SINGLETON is set for singleton classes. Neither is true for NilClass (nor FalseClass nor TrueClass).
Matz.
Updated by sawa (Tsuyoshi Sawada) almost 2 years ago
Thank you, Matz for answering my question.
Singleton classes are in principle only accessed using the singleton_class method or the singleton class notation.
Since we already have the following results,
nil.singleton_class # => NilClass
class << nil; self; end # => NilClass
the crucial part is that they should be the only way to access. So in short, the fact that it can be accessed directly through the name NilClass
seems to be what is avoiding it from being a singleton class.
Implementation wise, FL_SINGLETON is set for singleton classes.
I see. But I do not think Ruby users should need to worry too much about its implementation details. From the point of view of a user, that should be irrelevant for whether calling a class a singleton class or not.
To summarize, it seems that just because NilClass
has a constant name, it cannot be regarded as a singleton class. I now understand how the distinction is made currently, but I do not think it makes sense. I might make a feature request to get rid of this distinction.
Updated by Eregon (Benoit Daloze) almost 2 years ago
It's not because it has a constant name.
It's because nil.class => NilClass
and nil.singleton_class => NilClass
.
That means both the class and singleton class of nil
is the same class object.
And it may be weird if obj.class.singleton_class?
is true but only for those nil/false/true.
Also if NilClass was really a singleton class (singleton_class?
=> true) then what would be the non-singleton class/the superclass? It could be Object
, but weird again.
If they were different class objects it would probably be confusing and incompatible.
AT this point it seems difficult to resolve and probably not worth it.
Updated by headius (Charles Nutter) over 1 year ago
The behavior for this is at least consistent in JRuby; singleton_method
does not see methods defined directly on nil
.
I think it should be made consistent, so either it shows up in both singleton_method
and singleton_methods
or it should show up in neither (the JRuby behavior currently). I don't have a strong opinion which way is better, but having it show up in both probably has less potential to break things.
Of course, it has never worked in JRuby, so if there's code out there depending on nil.singleton_method
returning a result, it hasn't been reported to us.
Updated by headius (Charles Nutter) over 1 year ago
Issue filed for JRuby's differing behavior; if we decide that the method should always be visible through the singleton_*
calls, we will change it in JRuby.
Updated by jeremyevans0 (Jeremy Evans) over 1 year ago
I discussed this with @headius (Charles Nutter) at RubyKaigi, and agree that it would be best to make singleton_method
consistent with singleton_methods
. As @matz (Yukihiro Matsumoto) indicated, NilClass/TrueClass/FalseClass instance methods should be considered as normal instance methods, not as singleton methods of nil, true, and false. I've submitted a pull request for that: https://github.com/ruby/ruby/pull/7973
Updated by matz (Yukihiro Matsumoto) over 1 year ago
Sorry for being late. I accept the behavior of the pul-request.
Matz.
Updated by jeremyevans (Jeremy Evans) over 1 year ago
- Status changed from Open to Closed
Applied in changeset git|786a864900ceee6ed89d7df81698bbbe7e7bd6ae.
Make {Nil,True,False}Class#singleton_method always raise NameError
{Nil,True,False}Class#singleton_methods always returns [] indicating
that there are no singleton methods defined, so #singleton_method
should be consistent with that.
Fixes [Bug #11064]