Ruby中未定义的变量

55

假设我正在使用irb,并键入a = 5。如何删除a的定义,以便键入a会返回NameError

一些背景信息:稍后我想要执行以下操作:

context = Proc.new{}.binding
context.eval 'a = 5'
context.eval 'undef a'  # though this doesn't work.
5个回答

57

嗯,很烦人没有这样的方法。我想现在我只能使用实例变量了。 - Peter
这些链接看起来似乎不再指向正确的位置了。 - jcollum
2
@jcollum 谢谢。remove_instance_variableremove_const 是私有方法,所以似乎不再包含在 ruby-doc.org 的文档中了。我已经更新了答案,使用了等效的链接到 apidock.com。 - mikej

29

通过减少变量存在的范围,您可以避免未声明变量:

def scope 
  yield
end

scope do 
  b = 1234
end

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

3
这就是我想看到的答案。 - Boris Stitnicky
3
有一种名为Proc.new的标准 scope 函数: Proc.new { b = 1 } ; b - ribamar
2
值得注意的是,Proc.new 与给定的 scope 不同之处在于它并不会实际调用代码块。相当于这段代码:Proc.new { b = 1 }.call; b。你也可以使用 lambda { b = 1 }.call - Asherah

15
你可以通过调用irb子shell来始终“清除”irb的本地变量注册表。可以将Bash shell与未导出的环境变量相关联。由于你提到了交互模式,这个解决方案应该适用于它。
至于生产代码,我不想将取消定义本地变量作为解决方案的一部分-针对这种类型的情况,键入哈希可能会更好。
这是我的意思:
$ 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"

返回以下内容:"NotImplementedError: ruby 引擎只能在主线程中初始化" - Sapphire_Brick

0

目前你无法删除全局变量、局部变量和类变量。但你可以使用 "remove_const" 方法来删除常量。


3
对于类变量来说并不正确——应该使用remove_class_variable。 - mikej

0

根据问题的精神,您可以将变量限制在作用域内,假设您不介意其他本地变量被锁定到相同的作用域。这特别有用,尤其是如果您正在类中定义某些内容,并且不希望局部变量留在类声明中。

我能想到的唯一方法是使用Integer#timesArray#each,如下所示:

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

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

除了这种方法,可能还有其他更简洁的限制块的方法。这些方法不如我所希望的那样干净,我很想看看是否有更干净的方法可以用来实现这一点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接