Auf Rubin, was ist der Grund für include
ist privat, während Object#extend
öffentlich ist?Auf Ruby, warum include ist privat und extend ist öffentlich?
Antwort
Object#extend
hat ö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
.
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' –
@ Marc-AndréLafortune: Oder 'class << obj; Erweitern Foo; Ende, natürlich. Wie ich schon sagte, es ist nur eine Vermutung. –
Ich antwortete auf deinen ersten Satz "' Objekt # extend 'muss öffentlich sein, sonst könntest du es nicht benutzen. " –
Um Foo.include(Bar)
an einem beliebigen Punkt ausführen zu können, würde höchstwahrscheinlich eine Quelle von sehr fiesen Bugs sein.
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
Danke für deine Antworten! –