5 Stimmen

Warum kann ich mit Object#send in Ruby auf private/geschützte Methoden zugreifen?

Die Klasse

class A

  private
  def foo
    puts :foo
  end

  public
  def bar
    puts :bar
  end

  private
  def zim
    puts :zim
  end

  protected
  def dib
    puts :dib
  end
end

Instanz von A

a = A.new

Test

a.foo rescue puts :fail
a.bar rescue puts :fail
a.zim rescue puts :fail
a.dib rescue puts :fail
a.gaz rescue puts :fail

Testausgabe

fail
bar
fail
fail
fail

.send test

[:foo, :bar, :zim, :dib, :gaz].each { |m| a.send(m) rescue puts :fail }

.send Ausgabe

foo
bar
zim
dib
fail

Die Frage

Der Abschnitt mit der Bezeichnung "Testausgabe" ist das erwartete Ergebnis. Warum kann ich also auf eine private/geschützte Methode zugreifen, indem ich einfach Object#send ?

Vielleicht noch wichtiger:

Was ist der Unterschied zwischen public / private / protected in Ruby? Wann sollte man sie verwenden? Kann jemand Beispiele aus der Praxis geben für private y protected Verwendung?

8voto

Chuck Punkte 228137

Technisch gesehen: Denn send tut nichts, um die Sichtbarkeit der Methode zu überprüfen. (Es wäre mehr Arbeit, dies zu tun.)

Philosophisch: Ruby ist eine sehr freizügige Sprache. Sie können bereits eine Klasse öffnen und jede Methode, die Sie wollen, öffentlich machen. Die Sprachdesigner implementierten send auf eine Art und Weise, die es erlaubt, die Beschränkungen aufzuheben, die normalerweise durch private . Ruby 1.9 sollte ursprünglich zwei Varianten haben, eine private -respecting send und eine unsichere Variante namens send! aber dies wurde offenbar aus Gründen der Abwärtskompatibilität fallen gelassen.

Was die private , protected y public bedeuten:

  • public Methoden können von jedem Absender aufgerufen werden
  • protected Methoden können nicht außerhalb einer Instanz der Klasse der Methode oder einer Instanz einer Unterklasse aufgerufen werden
  • private Methoden können nicht mit einem expliziten Empfänger aufgerufen werden (mit einigen Ausnahmen, wie z. B. Setter-Methoden, die immer einen expliziten Empfänger haben müssen und daher innerhalb der Klasse auf diese Weise aufgerufen werden können)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X