W języku Ruby, ciągłe wyszukiwanie nie jest tym samym, co wyszukiwanie metodą. W przypadku metody wyszukiwania wywołanie foo
jest zawsze takie samo jak wywołanie self.foo
(zakładając, że nie jest prywatne). Wywołanie stałej FOO
różni się bardzo od wartości self::FOO
lub .
Użycie nieokreślonej stałej (na przykład FOO
) spowoduje wyszukiwanie w aktualnie otwartych modułach. Moduł jest otwarty z module Mod
, class Klass
, class << obj
lub module_eval
i wariantami. Definiując m1
, są to: B
, a następnie B.singleton_class
. Podczas definiowania m2
otwierane jest tylko .
module Foo
X = 42
class Bar
def self.hello
X
end
end
end
W tym kodzie Foo::Bar.hello
powróci 42, chociaż X
nie jest stałą Bar
jego pojedyncza klasa lub przodek. Ponadto, jeśli później dodasz stałą wartość X
do Bar
, ta wartość zostanie zwrócona. Na koniec dodaje się definicja nie jest równoważne:
module Foo
X = 42
end
class Foo::Bar
def self.hello
X
end
end
Foo::Bar.hello # => uninitialized constant Foo::Bar::X
Rzeczywiście, kiedy hello
jest zdefiniowany tylko klasy Foo::Bar
jest otwarty, podczas gdy w poprzednim przykładzie, zarówno Foo
i Foo::Bar
gdzie otwarty.
ostatni przykład, aby pokazać różnicę wyraźny zakres może mieć z dziedziczenia:
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
W twoim przypadku, prawdopodobnie chcesz include
moduł, zamiast extending
to, nie?
W przeciwnym razie można użyć kodu singleton_class::VAR
, kod będzie działał zgodnie z oczekiwaniami.
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
co to są 'f1' i' f2'? czy możesz po prostu dodać kilka linii? Co to jest "obecnie otwarte moduły" '? –
@Priti: Odpowiedź edytowana, tks –