In Ruby ist das konstante Nachschlagen nicht das gleiche wie das Nachschlagen nach Methoden. Bei Methodenabfragen ist das Aufrufen von foo
immer dasselbe wie das Aufrufen von self.foo
(vorausgesetzt, es ist nicht privat). Der Aufruf einer Konstanten FOO
ist sehr unterschiedlich zu self::FOO
oder singleton_class::FOO
.
Mit einer nicht qualifizierten Konstante (z. B. FOO
) wird in den aktuell geöffneten Modulen nachgeschlagen. Ein Modul wird mit module Mod
, class Klass
, class << obj
oder module_eval
und Varianten geöffnet. Bei der Definition von m1
sind dies B
und dann B.singleton_class
. Bei der Definition von m2
wird nur B
geöffnet.
module Foo
X = 42
class Bar
def self.hello
X
end
end
end
In diesem Code wird Foo::Bar.hello
42 zurückkehren, obwohl X
keine Konstante von Bar
, seine Singletonklasse oder Vorfahr ist. Wenn Sie später eine Konstante X
zu Bar
hinzufügen, wird dieser Wert zurückgegeben. Schließlich ist die folgende Definition nicht äquivalent:
module Foo
X = 42
end
class Foo::Bar
def self.hello
X
end
end
Foo::Bar.hello # => uninitialized constant Foo::Bar::X
der Tat, wenn hello
definiert ist, nur die Klasse Foo::Bar
geöffnet ist, während in dem vorherigen Beispiel, sowohl Foo
und Foo::Bar
wo geöffnet.
Ein letztes Beispiel den Unterschied ein expliziter Umfang zu zeigen mit Vererbung haben:
class Base
X = 42
def self.foo
X
end
def self.bar
self::X
end
end
class Parent < Base
X = :other
end
Parent.foo # => 42
Parent.bar # => :other
In Ihrem Fall Sie wahrscheinlich Ihr Modul include
wollen, statt extending
es, nicht wahr?
Andernfalls könnten Sie singleton_class::VAR
verwenden, Ihr Code wird so funktionieren, wie Sie es erwarten.
module A
VAR = 'some_constant'
end
class B
extend A
class << self
def m1
puts singleton_class::VAR # not necessary here, as singleton_class is opened
end
end
def self.m2
puts singleton_class::VAR # necessary here!
end
end
B.m1 # => OK
B.m2 # => OK
was ist 'f1' und' f2'? Kannst du da einfach ein paar Zeilen hinzufügen? Was ist "momentan geöffnete Module"? –
@Priti: Antwort bearbeitet, tks –