Project

General

Profile

Actions

Bug #20620

closed

singleton_method undefined for module using "extend self"

Added by dentarg (Patrik Ragnarsson) 10 months ago. Updated 7 months ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 3.4.0dev (2024-07-08T21:43:28Z master e500222de1) [x86_64-linux]
[ruby-core:118514]

Description

Is this a bug? I expected ExtendSelf.singleton_method(:foo) to work when ExtendSelf.singleton_methods worked and :foo was in the list returned.

# singleton_method.rb
class Klass
  def self.foo
  end
end

module ExtendSelf
  extend self

  def foo
  end
end

p RUBY_DESCRIPTION

p "Klass"
p Klass.singleton_methods      # => [:foo]
p Klass.singleton_method(:foo) # => #<Method: Klass.foo() singleton_method.rb:2>

p "ExtendSelf"
p ExtendSelf.singleton_methods      # => [:foo]
p ExtendSelf.singleton_method(:foo) # => singleton_method.rb:19:in `singleton_method': undefined singleton method `foo' for `ExtendSelf' (NameError)
$ docker run --rm -it -v $(pwd):/app -w /app rubylang/ruby:master-nightly-jammy
Unable to find image 'rubylang/ruby:master-nightly-jammy' locally
master-nightly-jammy: Pulling from rubylang/ruby
...
Digest: sha256:922037b184b897786a26b2460f70a66139f87dce67f20ddf760cd4186790ed9f

root@9807305c322a:/app# ruby -v
ruby 3.4.0dev (2024-07-08T21:43:28Z master e500222de1) [x86_64-linux]

root@9807305c322a:/app# ruby singleton_method.rb
"ruby 3.4.0dev (2024-07-08T21:43:28Z master e500222de1) [x86_64-linux]"
"Klass"
[:foo]
#<Method: Klass.foo() singleton_method.rb:2>
"ExtendSelf"
[:foo]
singleton_method.rb:21:in 'Kernel#singleton_method': undefined singleton method 'foo' for 'ExtendSelf' (NameError)

Updated by jeremyevans0 (Jeremy Evans) 10 months ago

I don't think this is a bug. It does seem inconsistent, but only because the all argument to singleton_methods defaults to true. If you call singleton_methods(false), then you get the behavior you would expect from the method name (only show actual singleton methods, not methods in modules that extend the object).

Updated by matz (Yukihiro Matsumoto) 10 months ago

I think singleton_method should traverse super-classes (as long as they are ICLASS) too. Probably we need to check for compatibility issues.

Matz.

Updated by jeremyevans0 (Jeremy Evans) 8 months ago

I submitted a pull request to implement this: https://github.com/ruby/ruby/pull/11605

In terms of compatibility issues:

  • For singleton classes that prepend a module, and have the method defined in both the singleton class and prepended module, singleton_method now returns the method in the prepended module.

  • Cases where a method is defined in a module prepended to or included in the singleton classes and not in the singleton class itself now result in a Method Object being returned, instead of raising NameError.

Use of singleton_method isn't that common in my experience, so I think we should make the change. There is still time to back it out of 3.4 if it causes issues.

Updated by matz (Yukihiro Matsumoto) 7 months ago

@jeremyevans0 (Jeremy Evans) Thank you. Let us merge the pull-request, and experiment with the preview.

Matz.

Actions #5

Updated by jeremyevans (Jeremy Evans) 7 months ago

  • Status changed from Open to Closed

Applied in changeset git|9986a7c3930437bc9d9b88736c22695585aa6c48.


Make Object#singleton_method return methods in modules included in or prepended to singleton class

To simplify the implementation, this makes Object#singleton_method
call the same method called by Object#method (rb_obj_method), then
check that the returned Method is defined before the superclass of the
object's singleton class. To keep the same error messages, it rescues
exceptions raised by rb_obj_method, and then raises its own exception.

Fixes [Bug #20620]

Actions

Also available in: Atom PDF

Like0
Like1Like0Like0Like0Like0