2011-11-28 60 views
4

对于Ruby有没有像Python __getattr__的东西?在Python中,当引用未定义的属性(方法或属性)时,将调用obj.__getattr__。我在Ruby中发现了method_missing,但它不适用于属性。Python像__getattr__ for Ruby/JRuby

我的用例是: 我正在测试Mirah作为JRuby - > Java编译器。在标准JRuby中,Swing方法和属性是“Rubyfied”(例如:label.setText“x”=> label.text =“x”),但Mirah中没有,因为Mirah没有像JRuby这样的专有运行时库。然后,我想在运行时获取属性引用,并将每个调用映射到相应的Swing方法(label.text => label.getText()/ label.text =“x”=> label.setText(“x”)) 。

+0

可能的重复:http://stackoverflow.com/questions/786412/what-is-the-ruby-equivalent-of-pythons-getattr – jsalonen

+1

@jsalonen:无重复,getattr' <>'__getattr__'。 Python getattr类似于Ruby的“method”:obj.getattr(“value”)等同于obj.value。 '__getattr__'是一个'魔术'方法,当一个未定义的属性被引用时被调用 – PabloG

回答

1

JRuby在Java代码中执行此转换,方法是遍历反射类的方法并为Ruby名称添加别名。你也可以从Ruby做到这一点。 Mirah可以访问所有正在编译的类的实际java.lang.Class实例,因此可以在编译器阶段执行相同的别名别名。

上究竟是如何做到这一点的细节留给作为练习读者:)

+0

我想我可以使用'object.methods'然后像':add_method'(我是Ruby/Mirah新手,对不起如果我没有正确理解你)。但是我正在寻找一个动态的解决方案,因为如果在Python中解决这个问题,我会使用这种方法,并且Ruby与Python非常相似 - 至少对于我来说,当我找到'method_missing'时,我认为有一种方法可以做相同的属性。 无论如何,保持与JRuby的良好工作! – PabloG

3

我不知道这包括你的使用情况,但总的来说,使用method_missing应该做的伎俩。您如何期望Ruby类知道未定义的方法和未定义的“属性”之间的区别?它只知道它已经传递了一个它不认识的名字。它应该是一种方法还是一种财产?谁知道?除非你是在谈论二传手属性,在这种情况下,不存在附加到名称的=

class X 
    def method_missing name,*args 
    puts "missing '#{name}' called with #{args}" 
    end 
end 

> x = X.new 
=> #<X:0xe6b322> 
> x.unknown_method 
missing 'unknown_method' called with [] 
=> nil 
> x.unknown_property 
missing 'unknown_property' called with [] 
=> nil 
> x.unknown_property= 42 
missing 'unknown_property=' called with [42] 
=> 42  
0

Ruby中的对象没有“属性”。他们有实例变量(每个实例存储数据的私有变量)和可以访问这些变量的方法。

因为括号是Ruby的方法调用可选的,因为语法糖让你写obj.foo = 42作为调用方法obj.foo=(42)的更好的方式,你可以认为,这些特性。他们不是;它们是与其他方法无法区分的方法。

此代码:

class Foo 
    attr_accessor :bar 
end 
f = Foo.new 
f.bar = 42 
puts f.bar #=> 42 

是完全一样的,因为这(长得)代码:

class Foo 
    def bar 
    @bar 
    end 
    def bar=(val) 
    @bar = val 
    end 
end 
f = Foo.new 
f.bar=(42) 
puts(f.bar()) #=> 42 

attr_*方法实际上为你创建的方法。