Project

General

Profile

Actions

Backport #8284

closed

Expected behavior of Module#public_class_method

Added by Anonymous about 11 years ago. Updated over 6 years ago.

Status:
Closed
[ruby-core:54404]

Description

It was pointed out by Myron Marston (here: https://gist.github.com/myronmarston/5401829) that calling public_class_method on an anonymous module makes the named method public on Object, etc.

Object.define_method => NoMethodError
Module.new.public_class_method(:define_method)
Object.define_method => ArgumentError

Also of note, the same is not true when calling it on a class:

Object.define_method => NoMethodError
Class.new.public_class_method(:define_method)
Object.define_method => NoMethodError

which seems inconsistent given:

Module.new.singleton_class.ancestors => [Module, Object, Kernel, BasicObject]
Class.new.singleton_class.ancestors => [Class, Module, Object, Kernel, BasicObject]

Is this a bug or expected behavior? If the latter, what is the correct explanation?

Actions #1

Updated by nobu (Nobuyoshi Nakada) about 11 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r40346.
Jack, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


vm_method.c: fix visibility on anonymous module

  • vm_method.c (rb_mod_public_method): fix visibility on anonymous
    module. set visibility of singleton method, not method in base
    class. [ruby-core:54404] [Bug #8284]
Actions #2

Updated by nobu (Nobuyoshi Nakada) about 11 years ago

  • Tracker changed from Bug to Backport
  • Project changed from Ruby master to Backport200
  • Status changed from Closed to Assigned
  • Assignee set to nagachika (Tomoyuki Chikanaga)

This is a very very longstanding, 16 years old bug, since 1.0.

Updated by moll (Andri Möll) about 11 years ago

Well, it was actually reported by me to the RSpec project (https://github.com/rspec/rspec-core/pull/873) and the example I gave there involved a regular, not an anonymous module. The patch you made, nobu, tests only with an anonymous module, but does the fix also solve the visibility leakage for non anonymous modules?

With Ruby v1.9.3p385:

Object.define_method
NoMethodError: private method define_method' called for Object:Class from (irb):1 from /usr/local/bin/irb:12:in '
module Foo
public_class_method :define_method
end
=> Foo
Object.define_method
ArgumentError: wrong number of arguments (0 for 1)
from (irb):3:in define_method' from (irb):3 from /usr/local/bin/irb:12:in '

Actions #4

Updated by Anonymous about 11 years ago

It does:

irb(main):001:0> RUBY_DESCRIPTION
=> "ruby 2.1.0dev (2013-04-19 trunk 40359) [i386-darwin10.8.0]"
irb(main):002:0> Object.define_method
NoMethodError: private method define_method' called for Object:Class from (irb):2 from /Users/jacknagel/.rubies/ruby-2.1.0-dev/bin/irb:12:in '
irb(main):003:0> module Foo; public_class_method :define_method; end
=> Foo
irb(main):004:0> Object.define_method
NoMethodError: private method define_method' called for Object:Class from (irb):4 from /Users/jacknagel/.rubies/ruby-2.1.0-dev/bin/irb:12:in '

Actions #5

Updated by Anonymous about 11 years ago

As an aside, I see that this is now marked Backport 200, but it would be great if it was backported to 1.9.3 as well.

Updated by marcandre (Marc-Andre Lafortune) about 11 years ago

jacknagel (Jack Nagel) wrote:

As an aside, I see that this is now marked Backport 200, but it would be great if it was backported to 1.9.3 as well.

I don't know if it will be, but in any case there is always singleton_class.send :public, :define_method instead or equivalent.

It's a bit more clear, IMO, as using "public_class_method" on a Module is a bit strange... Modules don't really have "class methods".

FWIW, there are no specs in RubySpec about "public_class_method" on a Module.

Updated by moll (Andri Möll) about 11 years ago

jacknagel (Jack Nagel) wrote:

It does:

That's good. Now there's only a test missing for that. :)

Updated by nagachika (Tomoyuki Chikanaga) about 11 years ago

I'll backport r40346 and r40371, and then move this ticket to Backport93.

Actions #9

Updated by nagachika (Tomoyuki Chikanaga) almost 11 years ago

  • Status changed from Assigned to Closed

This issue was solved with changeset r40427.
Jack, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


merge revision(s) 40346: [Backport #8284]

* vm_method.c (rb_mod_public_method): fix visibility on anonymous
  module. set visibility of singleton method, not method in base
  class.  [ruby-core:54404] [Bug #8284]
Actions #10

Updated by nagachika (Tomoyuki Chikanaga) almost 11 years ago

  • Project changed from Backport200 to Backport193
  • Status changed from Closed to Assigned
  • Assignee changed from nagachika (Tomoyuki Chikanaga) to usa (Usaku NAKAMURA)

Updated by usa (Usaku NAKAMURA) almost 11 years ago

Something is missing to backport the patch to ruby_1_9_3.
I'll check it later.

Updated by usa (Usaku NAKAMURA) over 6 years ago

  • Status changed from Assigned to Rejected

1.9.3 is out of date

Actions #13

Updated by marcandre (Marc-Andre Lafortune) over 6 years ago

  • Status changed from Rejected to Closed
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0