2010-11-18 7 views

Antwort

10

Object#extendhat öffentlich zu sein, sonst würden Sie nicht in der Lage sein, es zu benutzen. Schließlich besteht sein Zweck darin, ein Modul in ein Objekt zu mischen, so dass Sie es im Allgemeinen wie obj.extend(Foo) nennen, was mit privaten Methoden nicht möglich ist.

Module#include der Regel nur in einem Modulkörper wie so verwendet:

class Bar 
    include Foo 
end 

D.h. es wird normalerweise ohne Empfänger aufgerufen, also muss es nicht öffentlich sein. Natürlich ist es auch nicht privat zu sein.

Meine Vermutung ist der Grund, warum es privat ist, dass es mehr invasiv ist, weil es das Verhalten von jede Instanz Bar ändert, während Object#extend nur ein einzelnes Objekt ändert. Daher ist Module#include in gewisser Weise "gefährlicher" und wird daher privat gemacht.

Ich weiß nicht, ob das der eigentliche Grund ist, aber es ist konsistent mit anderen ähnlichen Methoden wie Module#define_method.

+0

Es muss * nicht * sein. Sie könnten es verwenden, wenn es privat wäre: 'obj.send (: extend, Foo)', 'obj.instance_eval {extend Foo}', nicht einschließlich der Groß-/Kleinschreibung für Module 'class Bar; Erweitern Foo; Ende' –

+0

@ Marc-AndréLafortune: Oder 'class << obj; Erweitern Foo; Ende, natürlich. Wie ich schon sagte, es ist nur eine Vermutung. –

+0

Ich antwortete auf deinen ersten Satz "' Objekt # extend 'muss öffentlich sein, sonst könntest du es nicht benutzen. " –

1

Um Foo.include(Bar) an einem beliebigen Punkt ausführen zu können, würde höchstwahrscheinlich eine Quelle von sehr fiesen Bugs sein.

1

Um Jörg W Mittag Antwort, Objekt # erstrecken kann auch verwendet werden, um umfassen Modulinstanzmethoden zu ergänzen, um in der Klassenstufe verwendet werden (was auch für alle Instanzen dieser Klasse verfügbar sein wird):

module Foo 
    def bar (baz) 
    end 
end 

class Qux 
    extend Foo 

    bar 'asdf' 
end