Oto mój moduł, który próbuje ustawić zmienną instancji. Próbuję zarówno zainicjować, jak i self.included, ale żadne z nich nie działa, gdy robię to na zewnętrznym (main
) zakres:
module Asd
def initialize
@asd = 0
end
def self.included(base)
@asd = 0
end
attr_reader :asd
end
Włączenie go do klasy działa i mogę odczytać zmienną instancji:
class Bsd
include Asd
end
Bsd.new.asd
# => 0
Ale robienie tego na poziomie globalnym nie działa:
include Asd
@asd
# => nil
asd
# => nil
Wiem, że często ludzie będą pytać o motywację do umieszczenia swojego kodu na poziomie globalnym. W tym przypadku chcę tylko zobaczyć, jak to się robi.
Odpowiedzi:
2 dla odpowiedzi № 1@EricDuminil wyjaśnił, dlaczego Twoje podejście nie zadziałało. Oto sposób, w jaki możesz to zrobić w tym kontekście: ustaw zmienną instancji bezpośrednio, bez inicjalizatora.
module Asd
def self.extended(base)
base.instance_variable_set(:@asd, "Another @asd")
end
attr_reader :asd
end
@asd # => nil # !> instance variable @asd not initialized
extend Asd # extend, not include.
@asd # => "Another @asd"
asd # => "Another @asd"
3 dla odpowiedzi № 2
Mam nadzieję, że ten kod będzie nieco jaśniejszy:
module Asd
def initialize
puts "# Initializing"
@asd = "One @asd"
end
def self.included(base)
puts "# Importing into #{base}"
@asd = "Another @asd"
end
attr_reader :asd
end
class Bsd
include Asd
# => # Importing into Bsd
end
puts Bsd.new.asd
# =>
# Initializing
# One @asd
puts Asd.instance_variable_get(:@asd)
# => Another @asd
include Asd
# => # Importing into Object
puts self.asd.inspect # Method is defined for main, @asd hasn"t been initialized because main was instantiated before the script was launched
# => nil
puts Object.new.asd
# =>
# Initializing
# One @asd
Zasadniczo Twój kod jest za późno main
. Został już zainicjowany przed uruchomieniem skryptu, więc nie ma w nim kodu initialize
zostanie już wprowadzone na rynek główny.