我有一个变量,可以调用它@foo
。我希望它是一个字符串,所以我打电话给@foo.downcase
。有时它是零,我会得到这个错误:
NoMethodError: undefined method `downcase' for nil:NilClass
from (irb):4
from /Users/schneems/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>
我想要做的是写一些代码告诉我nil实际上是@foo
NoMethodError: undefined method `downcase' on variable @foo, variable is a nil:NilClass
from (irb):4
from /Users/schneems/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>
要做这样的事情,我需要以编程方式获取变量的名称。
问题:是否有可能以编程方式获取变量的名称?
我正在寻找能产生如下输出的东西:
@foo.magical_variable_method #=> '@foo'
bar.magical_variable_method #=> 'bar'
AweSome.magical_variable_method #=> 'AweSome'
$wat.magical_variable_method #=> '$wat'
我不想要变量的值,也不关心它是nil
。我想要变量的人类可读名称。是否有可能以编程方式获取变量的名称?
答案 0 :(得分:1)
你想要的是有点混乱。
这是执行此任务的正确方法:
@foo && @foo.downcase
或者你可以使用rails library:
require 'active_support'
@foo.try(:downcase)
答案 1 :(得分:1)
目前没有办法做到这一点。
变量只是引用,而不是对象本身。如果使用点表示法来调用方法(如downcase
),则该方法对对象而不是变量进行操作。你的例子中的对象是单身nil
;如果nil
在一个地方分配了一个属性来命名它所分配的变量,那么同一属性将适用于所有nil
。
更一般地说,一个对象可能有许多指向它的变量/引用,因此没有好的方法来确定应该在对象中保存哪个变量名。 然而,Ruby中存在某种特殊处理方法,用于将类分配给常量;在这种情况下,类对象会记住它所分配的第一个常量的名称,例如:
$ irb
1.9.3p194 :001 > Foo = Class.new do
1.9.3p194 :002 > attr_accessor :foo
1.9.3p194 :003?> end
=> Foo
1.9.3p194 :004 > Bar = Foo
=> Foo
1.9.3p194 :005 > Foo.name
=> "Foo"
1.9.3p194 :006 > Bar.name
=> "Foo"
答案 2 :(得分:1)
您可以使用instance_variable_get(:@ foo)从符号中获取实例变量 这只会给你价值。
但你可以这样做:
puts "I'm gonna call @foo now, people"
some_obj.instance_variable_get(:@foo)
您还可以为想要观看的attrs执行method_missing挂钩。不要为@foo创建访问器方法并在method_missing中捕获调用并将其转发到某些通用实现,例如instance_variable_get
未经测试的尝试:
def method_missing(method_name, *args)
super(method_name, *args) unless watched_attributes.include?(method_name)
attr = ":@#{method_name.to_str}"
log.debug "Calling watched attribute #{attr}"
val = instance_variable_get(method_name)
log.debug "#{attr} was nil omg!" unless val
val
end
答案 3 :(得分:0)
编辑:可能最好的方式(请参阅mu的评论)就是确保您使用的是字符串:
@foo.to_s.downcase
您无需获取“名称”即可。你可以使用条件:
# Downcased if @foo's a string, empty string otherwise:
(String === @foo)? @foo.downcase : ''
或者,如果您要在很多地方执行此操作,并且不希望必须将每个包装在有条件的猴子补丁NilClass
中并添加虚拟downcase
方法:
class NilClass
def downcase
return ''
end
end
希望有所帮助!