Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Module#module_eval defines all methods into private visibility #2089

Closed
kachick opened this Issue · 7 comments

3 participants

@kachick
Collaborator

SetupCode

Foo = Class.new

Foo.module_eval do
  def func; end
  public   ; def public_func; end
  protected; def protected_func; end
  private  ; def private_func; end
end

foo = Foo.new

MRI

  • ruby 1.8.7 (2012-06-29 patchlevel 370) [i686-darwin11.4.0]
  • ruby 1.9.3p332 (2012-11-15 revision 37660) [x86_64-darwin11.4.2]
foo.func #=> nil
foo.public_func #=> nil
foo.protected_func #=> NoMethodError: protected method `protected_func' called for #<Foo:0x10798a230>
foo.private_func #=> NoMethodError: private method `private_func' called for #<Foo:0x10798a230>

Rubinius

  • rubinius 2.0.0rc1 (1.8.7 5088b79 2012-11-02 JI) [x86_64-apple-darwin11.4.2]
  • rubinius 2.0.0rc1 (1.9.3 5088b79 2012-11-02 JI) [x86_64-apple-darwin11.4.2]
foo.func #=> NoMethodError: private method `func' called on an instance of Foo.
foo.public_func #=> NoMethodError: private method `public_func' called on an instance of Foo.
foo.protected_func #=> NoMethodError: private method `protected_func' called on an instance of Foo.
foo.private_func #=> NoMethodError: private method `private_func' called on an instance of Foo.
@dbussink
Owner

Hmm, I only see this happening inside IRB, not if I run this as a regular script.

@kachick
Collaborator

Sorry!
I guess, I tried on the IRB only.
Please replace example below.

Foo = Class.new

eval %q{
  Foo.module_eval do
    def func; __callee__ end
    public   ; def public_func; __callee__ end
    protected; def protected_func; __callee__ end
    private  ; def private_func; __callee__ end
  end
}

foo = Foo.new

p foo.func
p foo.public_func
p foo.protected_func
p foo.private_func
@Peeja

Here's a slightly more useful version, which rescues the errors so we can see the whole thing run:

Foo = Class.new

eval %q{
  Foo.module_eval do
    def func; __callee__ end
    public   ; def public_func; __callee__ end
    protected; def protected_func; __callee__ end
    private  ; def private_func; __callee__ end
  end
}

foo = Foo.new

def try
  yield
rescue Exception => e
  e
end

p(try { foo.func })
p(try { foo.public_func })
p(try { foo.protected_func })
p(try { foo.private_func })
@Peeja

On latest master, 7d908da:

peeja:rubinius/ (master✗) $ bin/ruby issue_2089.rb
#<NoMethodError: private method `func' called on an instance of Foo.>
#<NoMethodError: private method `public_func' called on an instance of Foo.>
#<NoMethodError: private method `protected_func' called on an instance of Foo.>
#<NoMethodError: private method `private_func' called on an instance of Foo.>
@kachick
Collaborator

@Peeja Looks good! Thanks :)

@Peeja

Same result in both 1.8 and 1.9 modes.

It's not clear to me why using #eval is necessary, but it is:

# issue_2089_wo_eval.rb
Foo = Class.new

# eval %q{
  Foo.module_eval do
    def func; __callee__ end
    public   ; def public_func; __callee__ end
    protected; def protected_func; __callee__ end
    private  ; def private_func; __callee__ end
  end
# }

foo = Foo.new

def try
  yield
rescue Exception => e
  e
end

p(try { foo.func })
p(try { foo.public_func })
p(try { foo.protected_func })
p(try { foo.private_func })
peeja:rubinius/ (master✗) $ bin/ruby -X19 issue_2089_wo_eval.rb
:func
:public_func
#<NoMethodError: protected method `protected_func' called on an instance of Foo.>
#<NoMethodError: private method `private_func' called on an instance of Foo.>
@dbussink dbussink referenced this issue from a commit
@dbussink dbussink Setup top level visibility and script attributes
This creates a tag for a call frame indicating it's a top level script
or the top level for visibility checks. For this we also support a
boolean value on call_under definining whether to open a new visibility
top level or not.

This can be used to fix visibility checks and have methods defined
inside blocks have the proper visibility in Rubinius.

Fixes #2316 and #2089
add25be
@dbussink
Owner

This issue should have been fixed.

@dbussink dbussink closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.