Project

General

Profile

Actions

Bug #11064

closed

#singleton_methods for objects with special singleton_class returns an empty array

Added by rbjl (Jan Lelis) almost 9 years ago. Updated 8 months ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-linux]
[ruby-core:<unknown>]

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 #=> []

Related issues 1 (0 open1 closed)

Related to Ruby master - Bug #11063: Special singleton class should return true for singleton_class? testRejectedActions

Updated by matz (Yukihiro Matsumoto) about 2 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 in NilClass (same for TrueClass and FalseClass)

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) about 2 years ago

matz (Yukihiro Matsumoto) wrote in #note-1:

nil does not have its singleton class, but NilClass 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"?

Actions #3

Updated by Eregon (Benoit Daloze) about 2 years ago

  • Related to Bug #11063: Special singleton class should return true for singleton_class? test added

Updated by matz (Yukihiro Matsumoto) about 1 year 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) about 1 year 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) about 1 year 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) 10 months 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) 10 months 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.

https://github.com/jruby/jruby/issues/7787

Updated by jeremyevans0 (Jeremy Evans) 9 months 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) 8 months ago

Sorry for being late. I accept the behavior of the pul-request.

Matz.

Actions #11

Updated by jeremyevans (Jeremy Evans) 8 months 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]

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like1Like0Like0Like1Like0Like0Like0Like0