method visibility is always private when defined in class_eval #2248

Closed
ConradIrwin opened this Issue Mar 31, 2013 · 2 comments

Projects

None yet

2 participants

@ConradIrwin
Contributor

There are two intertwined bugs:

  1. Method visibility is not public by default inside class_eval
  2. Method visibility set by public, protected or private is ignored in an eval binding inside a block

i.e. both of the following fail

Object.class_eval do
  def foo; 5; end
end
self.foo.should == 5
#=> NoMethodError: private method `foo' called on an instance of Object.
Object.class_eval do
  public
  def foo; 5; end
end
self.foo.should == 5
#=> NoMethodError: private method `foo' called on an instance of Object.

I think 1. can be fixed by passing a flag down from Kernel#module_eval through to wherever the variable scope is created, and 2. can be fixed by adding return @method_visibility if defined?(@method_visibility) to the top of VariableScope#method_visibility (it's a bit convoluted because public seems to be represented by nil).

@dbussink
Member

I just ran that code here locally and it works fine. I think this only happens inside irb. This is probably a duplicate of #2089

@ConradIrwin
Contributor

I noticed it with pry's method redefinition features (they also use TOPLEVEL_BINDING.eval) so it sounds like a duplicate, yes.

@havenwood havenwood pushed a commit to havenwood/pry that referenced this issue Nov 12, 2013
@ConradIrwin ConradIrwin Method::Patcher should preserve method visibility
(Works around rubinius/rubinius#2248)
ad655b7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment