Frage

Mit dynamischen Methodenaufrufen (#send oder #method) die Sichtbarkeit Methoden ignoriert.
Gibt es eine einfache Möglichkeit, dynamisch eine Methode aufzurufen, die fehlschlagen wird eine private Methode aufrufen?

War es hilfreich?

Lösung

Wie ich weiß - Sie müssen Methode public_send:

----------------------------------------------------- Object#public_send
     obj.public_send(symbol [, args...])  => obj

     From Ruby 1.9.1
------------------------------------------------------------------------
     Invokes the method identified by _symbol_, passing it any arguments
     specified. Unlike send, public_send calls public methods only.

        1.public_send(:puts, "hello")  # causes NoMethodError

Andere Tipps

Verwenden Sie public_send statt send :

my_object.public_send :method, *args

Es ist neu zu Ruby 1.9, so dass für ältere Ruby Sie können require 'backports/1.9.1/kernel/public_send' .

Wenn Sie rubin 1.9 verwenden, können Sie Object#public_send verwenden, die das tut, was Sie wollen.

Wenn Sie rubin 1.8.7 oder früher haben Sie Ihre eigene Object#public_send schreiben

class Object
  def public_send(name, *args)
    unless public_methods.include?(name.to_s)
      raise NoMethodError.new("undefined method `#{name}' for \"#{self.inspect}\":#{self.class}")
    end
    send(name, *args)
  end
end

Oder Sie könnten Ihre eigene Object#public_method schreiben, die wie Object#method verhält sich aber nur für öffentliche Methoden

class Object
  def public_method(name)
    unless public_methods.include?(name.to_s)
      raise NameError.new("undefined method `#{name}' for class `#{self.class}'")
    end
    method(name)
  end
end

Dachte, ich verstehe nicht, warum Sie dies tun möchten, können Sie eval verwenden.

class Klass
  private
    def private_method(arg)
    end
end

k = Klass.new
m = "private_method"
eval "k.#{m}('an arg')"

NoMethodError: private method `private_method' called for #<Klass:0x128a7c0>
    from (irb):15
    from (irb):15

Es ist zwar wahr, eval wirklich ich der einzige Weg, wirklich denken, es zu tun pre-1.9. Wenn Sie mehr über die Sichtbarkeit lesen möchten schrieb Jamis Buck einen ehrfürchtige Artikel rel="nofollow über welche Methode Sichtbarkeit bedeutet eigentlich in Ruby.

Ähnlich wie andere Dinge in Ruby Sicht immer so ist etwas anders als andere Sprachen.

Wenn Sie eval, send oder public_send zu vermeiden, oder Sie wollen besser Leistung , verwenden Sie die public_method Methode :

obj.public_method('my_method_name').call

Sie können Argumente wie folgt hinzu:

obj.public_method('my_method_name').call('some_argument_1', 'some_argument_2')

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top