Frage

Auf der obersten Ebene, Methodendefinition sollte in privaten Methoden auf Object führen, und Tests scheinen diese heraus zu tragen:

def hello; "hello world"; end

Object.private_instance_methods.include?(:hello) #=> true
Object.new.send(:hello) #=> "hello world"

Allerdings funktioniert das folgende auch auf höchster Ebene (self.meta die Eigenklasse von main ist):

self.meta.private_instance_methods(false).include?(:hello) #=> true

Es scheint, dass die hello Verfahren gleichzeitig auf die Eigenklasse des Haupt definiert sowie auf Object. Was ist los? Beachten Sie, dass die false Parameter private_instance_methods schließt Superklasse Methoden aus der Methodenliste.

War es hilfreich?

Lösung

Zunächst einmal dieses Verhalten und die zugrunde liegende Argumentation hat es immer gegeben; es ist nichts Neues auf 1,9. Der technische Grund, es passiert ist, weil main speziell und anders als jedes andere Objekt behandelt. Es gibt keine Lust Erklärung zur Verfügung. Es so verhält, weil es entworfen wurde, auf diese Weise

Okay, aber warum? Was ist die Begründung für main magisch zu sein? Da Rubys Designer Yukihiro Matsumoto denkt, dass es macht die Sprache besser um dieses Verhalten zu haben:

  
    

Sind ja, warum Top-Level-Methoden sind nicht Singleton-Methoden für dieses Objekt hergestellt,     statt in als Instanzmethoden auf der Objektklasse gezogen wird     selbst     (Und damit auch in allen anderen Klassen das heißt mehr Namespace Verschmutzung ist, als     in der Regel beabsichtigt). Dies würde nach wie vor Top-Level-Methoden ermöglichen es andere zu nennen     Top-Level-Verfahren. Und wenn das Objekt der obersten Ebene wurden bezeichnet durch     etwas     konstant wie Main, dann könnten diese Methoden von überall aufgerufen werden     mit     Main.method (...).

  
     

Haben Sie wirklich Art wünschen   "Main.print" überall?

Im weiteren Verlauf der Diskussion, er erklärt, dass es auf diese Weise verhält, weil er glaubt, die „Annahme natürlich ist.“

EDIT:

Als Antwort auf Ihren Kommentar, wird Ihre Frage gerichtet, warum Haupt der Eigenklasse scheint Bericht hello als private Instanzmethode. Der Haken ist, dass keiner der Top-Level-Funktionen werden main tatsächlich hinzugefügt, sondern direkt an Object. Wenn mit eigenclasses arbeiten, verhält sich die instance_methods Familie von Funktionen immer, als ob die Eigenklasse ist immer noch die ursprüngliche Klasse. Das heißt, in der Klasse definierten Methoden behandelt werden, als direkt in der Eigenklasse definiert ist. Zum Beispiel:

class Object
  private
  def foo
    "foo"
  end
end

self.send :foo  # => "foo"
Object.private_instance_methods(false).include? :foo  # => true
self.meta.private_instance_methods(false).include? :foo  # => true

class Bar
  private
  def bar
    "bar"
  end
end

bar = Bar.new
bar.send :bar  # => "bar"
Bar.private_instance_methods(false).include? :bar  # => true
bar.meta.private_instance_methods(false).include? :bar  # => true

Wir können eine Methode direkt an main der Eigenklasse hinzufügen, though. Vergleichen Sie das Original Beispiel mit diesem:

def self.hello; "hello world"; end

Object.instance_methods.include? :hello  # => false
self.meta.instance_methods.include? :hello  # => true

Okay, aber was, wenn wir wirklich wissen wollen, dass eine gegebene Funktion auf der Eigenklasse definiert ist, nicht die ursprüngliche Klasse?

def foo; "foo"; end  #Remember, this defines it in Object, not on main
def self.bar; "bar"; end  #This is defined on main, not Object

foo  # => "foo"
bar  # => "bar"

self.singleton_methods.include? :foo  # => false
self.singleton_methods.include? :bar  # => true
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top