web-dev-qa-db-ja.com

Ruby

irbを使用していて、a = 5と入力するとします。 aと入力するとaが返されるように、NameErrorの定義を削除するにはどうすればよいですか?

いくつかのコンテキスト:後でこれを実行したい:

context = Proc.new{}.binding
context.eval 'a = 5'
context.eval 'undef a'  # though this doesn't work.
48
Peter

remove_class_variableremove_instance_variable 、および remove_const メソッドがありますが、現在、ローカル変数に相当するものはありません。

47
mikej

変数が存在するスコープを減らすことにより、変数の宣言を解除することを回避できます。

def scope 
  yield
end

scope do 
  b = 1234
end

b  # undefined local variable or method `b' for main:Object
23
Daniel

Irbサブシェルを呼び出すことにより、ローカル変数のirbのレジストリをいつでも「クリア」できます。エクスポートされていない環境変数に関してBashシェルがどのように機能するかを考えてください。インタラクティブモードについて言及したので、このソリューションはそのために機能するはずです。

量産コードに関しては、ソリューションの一部としてローカル変数の定義を解除したくありません。そのようなシナリオでは、キー付きハッシュの方が良いでしょう。

これが私の意味です:

$ 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"
13
Dean Radcliffe

現在、グローバル変数、ローカル変数、クラス変数を削除する手段はありません。 「remove_const」メソッドを使用して定数を削除できますが

0
Nakul

質問の趣旨では、他のローカル変数が同じスコープにロックされていることを前提として、変数をスコープに制限することができます。これは特に、クラスで何かを定義していて、ローカル変数をクラス宣言内に残したくない場合に役立ちます。

私がこれを行うと考えることができる唯一の方法は、Integer#timesまたはArray#each そのようです:

1.times do |a|
  a = 5
  # code…
end

[5].each do |a|
  # code…
end

これ以外にも、ブロックに限定するための、他のよりクリーンな方法がおそらくあります。これらは私が望んでいるほどきれいではありません。誰かがこれを行うために使用できるよりクリーンな方法があるかどうかを確認したいと思います。

0
RWDJ