我有一个实例变量@foo
,我想编写一些代码以便获得字符串'foo'
任何提示?
如果您所拥有的只是对该对象的引用,那么您就不能真正做到干净利落。
def foo
bar @something
end
def bar(value)
value # no clean way to know this is @something
end
我能想到的唯一技巧是遍历所有实例变量self
,寻找匹配项。但这是一种非常混乱的方法,可能会很慢。
def bar(value)
instance_variables.each do |ivar_name|
if instance_variable_get(ivar_name) == value
return ivar_name.to_s.sub(/^@/, '') # change '@something' to 'something'
end
end
# return nil if no match was found
nil
end
@something = 'abc123'
bar @something # returns 'something'
# But passing the same value, will return a value it's equal to as well
bar 'abc123' # returns 'something'
这是有效的,因为instance_variables
返回一个符号数组,这些符号是实例变量的名称。
instance_variables
#=> [:@something, :@whatever]
并instance_variable_get
允许您按名称获取值。
instance_variable_get :@something # note the @
#=> 'abc123'
结合这两种方法,你可以接近你想要的。
只要明智地使用它。在使用基于此的解决方案之前,请查看您是否可以通过某种方式重构事物以使其不再需要。元编程就像一门武术。您应该知道它是如何工作的,但要有纪律,尽可能避免使用它。
您可以调用该方法instance_variables
来获取对象的所有实例变量的名称。请注意,尽管实例变量仅在初始化后才包含在该列表中。
>> class A; attr_accessor :foo; end
=> nil
>> a = A.new
=> #<A:0x103b310b0>
>> a.instance_variables
=> []
>> a.foo = 42
=> 42
>> a.instance_variables
=> ["@foo"]
在 Ruby 中,您只能操作对象。变量(包括实例变量)不是对象。
此外,在这种情况下,您希望您的魔术方法返回什么:
foo = Object.new
bar = foo
@baz = bar
@qux = bar
magic_method(foo) # what should the return value be and how would it know?
class Object
def get_name
line_number = caller[0].split(':')[1].to_i
line_exectued = File.readlines( __FILE__)[line_number-1]
line_exectued.match(/(\S+).get_name/)[1]
end
end
inconceivable = true
p inconceivable.get_name