Aqui está o meu módulo que tenta definir uma variável de instância. Estou tentando inicializar e self.included, mas nenhum deles funciona quando faço a inclusão no lado externo (main
) escopo:
module Asd
def initialize
@asd = 0
end
def self.included(base)
@asd = 0
end
attr_reader :asd
end
Incluindo-o em uma classe funciona, e eu posso ler a variável de instância:
class Bsd
include Asd
end
Bsd.new.asd
# => 0
Mas fazer isso no nível global não funciona:
include Asd
@asd
# => nil
asd
# => nil
Eu sei que muitas vezes as pessoas questionam a motivação para colocar seu código em nível global. Neste caso, eu só quero ver como isso é feito.
Respostas:
2 para resposta № 1O @EricDuminil explicou por que sua abordagem não funcionou. Veja como você pode fazê-la funcionar neste contexto: defina a variável de instância diretamente, sem inicializador.
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 para resposta № 2
Espero que esse código o torne um pouco mais claro:
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
Basicamente, seu código é tarde demais para main
. Ele já foi inicializado antes do lançamento do script, portanto, nenhum código dentro initialize
será lançado para o main mais.