natalie-lang / natalie

a work-in-progress Ruby compiler, written in Ruby and C++
https://natalie-lang.org
MIT License
931 stars 61 forks source link

Proc#ruby2_keywords should not capture self when used as a method #2209

Open seven1m opened 1 month ago

seven1m commented 1 month ago

Defining a method using a proc that had ruby2_keywords called on it should not capture self. I only found this because I'm working on adding delegate.rb which does this:

def Delegator.delegating_block(mid) # :nodoc:
  lambda do |*args, &block|
    target = self.__getobj__
    target.__send__(mid, *args, &block)
  end.ruby2_keywords
end

# ...

define_method(method, Delegator.delegating_block(method))

In that code, with our implementation, the self object is wrong.

Here is a test case if we ever get around to fixing this:

describe '#ruby2_keywords' do
  it 'does not capture self when used as a method' do
    x = 9
    klass = Class.new do
      define_method(:plain, ->(*) { [self, x] })
      define_method(:wrapped, ->(*) { [self, x] }.ruby2_keywords)
    end
    obj = klass.new
    obj.wrapped.first.should == obj
    obj.wrapped.last.should == 9
    obj.plain.should == obj.wrapped
  end
end

...but I have to admit, it feels like a waste to spend too much time on it since this is a remnant of by-gone era in Ruby. Maybe we'll get lucky and this method will get removed in a future Ruby version.