/ / Definir variável de instância em main após incluir o módulo? - rubi

Definir variável de instância no principal depois de incluir o módulo? - rubi

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 № 1

O @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.