我想使用
remove_instance_variable(instance_variable)
,其中 instance_variable
包含 :@some_variable
形式的符号,但首先我想验证实例变量(例如 @some_variable
是否存在。
defined? instance_variable
当然会返回“局部变量”,所以这对我没有好处。
即使我可以抓取
instance_variable
的内容,有效地使用 defined? :@some_variable
也会返回“表达式”,因为它告诉我符号已定义。 (所有符号,即使是您以前从未使用过的符号,都会在这种情况下返回“表达式”。)
如果我使用
eval
,则该符号可以方便地替换为实际实例变量,并且它可以工作,返回 nil
或“实例变量”。
eval("defined? #{instance_variable}")
但是鉴于对
eval
的强烈厌恶(这在变量可能包含用户提交的值的情况下当然是合理的),如果可能的话,我宁愿找到不同的解决方案。即使我彻底确保instance_variable
不可能包含任何用户提交的数据,每个在我之后查看代码的人都会停下来问“为什么在这里使用eval
?”。
是否有另一种方法来检查
instance_variable
内的符号引用的实例变量是否已定义?
Object
实现了 5 种获取、设置、检查、列出和删除实例变量的方法:
Object#instance_variable_get
– 返回实例变量的值Object#instance_variable_set
– 设置实例变量的值Object#instance_variable_defined?
- 检查是否定义了实例变量Object#instance_variables
– 返回所有实例变量名称的数组Object#remove_instance_variable
– 删除实例变量instance_variable_defined?
就是您正在寻找的:
name = :@foo
instance_variable_defined?(name) #=> false
@foo = nil
instance_variable_defined?(name) #=> true
该方法对于实现值的记忆也很有用,这些值可能是
nil
:
def foo
return @foo if instance_variable_defined?(:@foo)
@foo = expensive_operation_that_could_return_nil
end