Issue #12113 has been updated by Benoit Daloze.


Would that solve the OP example code since some_func is defined in Object, not Kernel?

Using Kernel.method would be wrong, because the receiver would be the Kernel class, and not the delegated object (Klass.new(0).inspect would return "Kernel" for instance).

It would be quite tempting to make Delegator inherit from Object (or include the true Kernel) and redefine all the existing methods to try the delegate first,
but that would not work for methods added to Object/Kernel after require 'delegate', and those would just hide the methods of the delegate.
Maybe this could be worked around by hooking into #method_added, but that would not be very resilient if the user code redefines Object/Kernel#method_added.
If we had a way to hook into new method definition without the user accidentally break it, maybe this would be a good implementation. Or am I missing something?

----------------------------------------
Feature #12113: Global method inside Delegator causes NameError
https://bugs.ruby-lang.org/issues/12113#change-57186

* Author: Oleg Antonyan
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
~~~ruby
def some_func
  puts '12'
end

class Klass < Delegator
  def initialize(obj)
    @obj = obj
  end

  def __getobj__
    @obj
  end

  def func
    some_func #=> /home/oleg/.rbenv/versions/2.3.0/lib64/ruby/2.3.0/delegate.rb:85:in `instance_method': undefined method `some_func' for module `Kernel' (NameError)
  end
end

Klass.new(0).func
~~~
Delegator uses Kernel.instance_method (https://github.com/ruby/ruby/blob/trunk/lib/delegate.rb#L85) but:

~~~ruby
::Kernel.respond_to?(:some_func, true) #=> true
::Kernel.instance_method(:some_func)   #=> `instance_method': undefined method `some_func' for module `Kernel' (NameError)
::Kernel.method(:some_func)            #=> #<Method: Module(Object)#some_func>
~~~

I think there should be `Kernel.method` instead of `instance_method` (in Delegator). Otherwise you get `respond_to?` == `true`, but cannot use this method and get an error.



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

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>