1

Is it possible to make the Forwardable#def_delegator method respect that the target method is private?

In the following code, when def_delegator is used, Foo#hello is called even though it's private, because the implementation of Forwardable#def_delegator (actually, def_instance_delegator) uses __send__, which doesn't respect a method being private.

require "forwardable"

class Foo
  def hello
    "Hello"
  end
  private :hello
end

class Bar
  extend Forwardable

  def_delegator :@foo, :hello

  def initialize
    @foo = Foo.new
  end

  def bar
    hello
  end
end

foo = Foo.new
foo.hello # => NoMethodError: private method `hello' called for #<Foo:0x007f57c3cd1c80>

bar = Bar.new
bar.bar # => "Hello"

I'm using Ruby 2.0.

Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
  • 1
    What version of Ruby are you using? If >= 1.9, you could redefine `Forwardable#def_delegator` to use [Object#public_send](http://ruby-doc.org/core-1.9.3/Object.html#method-i-public_send) – lmars Sep 17 '13 at 01:25

1 Answers1

1

Not directly. If you're using Active Support core extensions 4.0 or newer, you can use Module#delegate instead:

require "active_support/core_ext/module/delegation"

class Foo
  def hello
    "Hello"
  end
  private :hello
end

class Bar
  delegate :hello, :to => :@foo

  def initialize
    @foo = Foo.new
  end

  def bar
    hello
  end
end
PH.
  • 378
  • 2
  • 6