Issue #9005 has been updated by Jeremy Evans.


Scott Tamosunas wrote:
> This isn't fixed on 2.1.3. Has that changeset not made it into a release? 
> 
> `2.1.3 :001 > RUBY_VERSION
>  => "2.1.3" 
> 2.1.3 :002 > class Foo
> 2.1.3 :003?>   
> 2.1.3 :004 >       private
> 2.1.3 :005?>     
> 2.1.3 :006 >       define_method("bar") { puts "BAR" }
> 2.1.3 :007?>   end
>  => :bar 
> 2.1.3 :008 > 
> 2.1.3 :009 >   Foo.new.bar
> NoMethodError: private method `bar' called for #<Foo:0x007ff90b8e3198>
> 	from (irb):9
> 	from /Users/me/.rvm/rubies/ruby-2.1.3/bin/irb:11:in `<main>'`
> 
> Where this works on 2.0
> 
> `2.0.0-p451 :001 > RUBY_VERSION
>  => "2.0.0" 
> 2.0.0-p451 :002 > class Foo
> 2.0.0-p451 :003?>   
> 2.0.0-p451 :004 >       private
> 2.0.0-p451 :005?>     
> 2.0.0-p451 :006 >       define_method("bar") { puts "BAR" }
> 2.0.0-p451 :007?>   end
>  => #<Proc:0x0000010103cd00@(irb):6 (lambda)> 
> 2.0.0-p451 :008 > 
> 2.0.0-p451 :009 >   Foo.new.bar
> BAR
> `

The behavior change here is deliberate, since you are calling define_method inside the class definition after calling private.  This bug was that define_method when called outside the class definition was generating private methods, which was fixed before the release of 2.1.0.

----------------------------------------
Bug #9005: object.send(:define_method, ...){...} creates private method
https://bugs.ruby-lang.org/issues/9005#change-49648

* Author: Jeremy Evans
* Status: Closed
* Priority: Normal
* Assignee: Nobuyoshi Nakada
* Category: core
* Target version: 2.1.0
* ruby -v: ruby 2.1.0dev (2013-09-22 trunk 43011) [i386-openbsd]
* Backport: 1.9.3: DONTNEED, 2.0.0: DONTNEED, 2.1.0: REQUIRED
----------------------------------------
I assume this is caused by r40022, which made define_method consider visibility.  However, visibility should only be considered if define_method is called normally, not via send. When called via send, it should define a public method.  Here's example code showing the error:

$ ruby21 -ve "Object.send(:define_method, :foo){|*a| 1}.foo"
-e:1:in `<main>': private method `foo' called for :foo:Symbol (NoMethodError)

I apologize in advance if this has already been fixed (I tested 2.1.0-preview1, not trunk), but from the commit logs it doesn't appear to have been.



-- 
https://bugs.ruby-lang.org/