当我调用不存在的方法时,method_missing
将告诉我方法的名称。当我尝试访问一个未设置的变量时,其值就是简单的 nil
。
我正在尝试动态拦截访问 nil 实例变量并根据所访问的变量名称返回一个值。最接近的等效功能将是 PHP 的 __get
。Ruby 中是否有任何等效该功能的方法?
当我调用不存在的方法时,method_missing
将告诉我方法的名称。当我尝试访问一个未设置的变量时,其值就是简单的 nil
。
我正在尝试动态拦截访问 nil 实例变量并根据所访问的变量名称返回一个值。最接近的等效功能将是 PHP 的 __get
。Ruby 中是否有任何等效该功能的方法?
instance_variable_get
似乎是最接近 PHP 的 __get
的 Ruby 等效物(尽管我不是 PHP 用户)。const_missing
,没有实例变量。目前我不知道有 instance_variable_missing
这个方法。
但是你为什么要随意访问命名的实例变量呢?如果你通过方法调用来访问对象状态(正如你应该做的那样),那么你就不需要这个方法了。
如果你想要定义一些神奇的东西,而又不想干扰方法查找,你可以使用 const_missing
。
@user.name
这样的内容,而没有设置@user
。我想我可以在第一次读取时动态生成FactoryGirl对象,以便为@user
等内容提供支持。 - user229044method_missing
)。这很遗憾,因为Ruby甚至“知道”您何时访问未定义的变量并会给出警告。 - riffraffinstance_variable_missing
在某种程度上与method_missing
相同...看下面的类:class Test
def method_missing(*args)
puts args.inspect
end
end
t = Test.new
t.pineapples #=> [:pineapples]
t.pineapples = 5 #=> [:pineapples=,5]
t = SomeClass.new
t.property.child = 1
那么让我们尝试从之前的示例中返回一个Test
对象:
class Test
def method_missing(*args)
puts args.inspect
return Test.new
end
end
当我们调用时会发生什么:
t = Test.new
t.property.child = 1
#=>[:property]
#=>[:child=,1]
OpenStruct
使用相同的技术来动态设置实例变量。在下面的示例中,我创建了EternalStruct
,它正是您想要的:require 'ostruct'
class EternalStruct < OpenStruct
def method_missing(*args)
ret = super(*args)
if !ret
newES = EternalStruct.new
self.__send__((args[0].to_s + "=").to_sym, newES)
return newES
end
end
end
EternalStruct
的使用方法:
t = EternalStruct.new
t.foo.bar.baz = "Store me!"
t.foo.bar.baz #=> "Store me!"
t.foo #=> #<EternalStruct bar=#<EternalStruct baz="Store me!">>
t.a = 1
t.a #=> 1
t.b #=> #<EternalStruct:...>
t.b = {}
t.b #=> {}
def t.c(arg)
puts arg
end
t.c("hi there") #=> "hi there"