variável Undefine em Ruby
-
18-09-2019 - |
Pergunta
Vamos dizer que eu estou usando irb
e tipo a = 5
. Como faço para remover a definição de a
para que a
digitação retorna um NameError
?
Alguns contexto: mais tarde, eu quero fazer isso:
context = Proc.new{}.binding
context.eval 'a = 5'
context.eval 'undef a' # though this doesn't work.
Solução
Há remove_class_variable , remove_instance_variable e remove_const métodos mas atualmente não há equivalente para as variáveis ??locais.
Outras dicas
Você pode evitar un-declarar a variável, reduzindo o escopo em que existe a variável:
def scope
yield
end
scope do
b = 1234
end
b # undefined local variable or method `b' for main:Object
Você pode sempre o registro do IRB 'claro' de variáveis ??locais, invocando um subshell IRB. Pense em como conchas festança de trabalhar com relação a variáveis ??de ambiente não exportadas. Desde que você metioned modo interativo, esta solução deve trabalhar para isso.
Quanto código de produção, eu não gostaria de variáveis ??locais undefine como parte de uma solução - hashes com chave provavelmente seria melhor para esse tipo de cenário
.Aqui está o que eu quero dizer:
$ irb
irb(main):001:0> a = "a"
=> "a"
irb(main):002:0> defined? a
=> "local-variable"
irb(main):003:0> irb # step into subshell with its own locals
irb#1(main):001:0> defined? a
=> nil
irb#1(main):002:0> a
NameError: undefined local variable or method `a' for main:Object
from /Users/dean/.irbrc:108:in `method_missing'
from (irb#1):2
irb#1(main):003:0> exit
=> #<IRB::Irb: @context=#<IRB::Context:0x1011b48b8>, @signal_status=:IN_EVAL, @scanner=#<RubyLex:0x1011b3df0>>
irb(main):004:0> a # now we're back and a exists again
=> "a"
Atualmente você não tem média para remover variáveis ??globais, variáveis ??locais e variáveis ??de classe. Você pode remover as constantes usando "remove_const" método embora
No espírito da questão, você pode limitar a variável para um escopo, supondo que você está bem com outras variáveis ??locais a ser bloqueada para o mesmo escopo. Isso é útil principalmente se você está definindo algo em uma classe e não quer que a variável local para ficar em torno da declaração da classe.
As únicas maneiras que eu posso pensar de fazer isso é com Integer#times
ou Array#each
assim:
1.times do |a|
a = 5
# code…
end
[5].each do |a|
# code…
end
Há provavelmente outras formas, mais limpas mesmo em limitar a um bloco além desta. Estes não são tão limpo como eu gostaria e eu adoraria ver se alguém tem um método mais limpo para usar para fazer isso.