对于Ruby / JRuby,Python就像__getattr__

时间:2011-11-28 19:09:43

标签: ruby jruby mirah

对于Ruby,有类似Python __getattr__的东西吗?在Python中,当引用未定义的属性(方法或属性)时,将调用obj.__getattr__。我在Ruby中找到method_missing但它不适用于属性。

我的用例是: 我正在测试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”) ))。

3 个答案:

答案 0 :(得分:3)

我不确定这是否涵盖了您的用例,但一般来说,method_missing应该可以解决问题。您如何期望Ruby类知道未定义方法和未定义“属性”之间的区别?它所知道的是它已经传递了一个它无法识别的名称。它应该是一种方法还是财产?谁知道?除非您在谈论setter属性,否则在名称后面会附加=

 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     

答案 1 :(得分:1)

JRuby通过遍历反射类的方法并为Ruby名称添加别名,在Java代码中进行此转换。您也可以从Ruby执行此操作。 Mirah可以访问您正在编译的所有类的实际java.lang.Class实例,因此可以在编译器阶段中使用相同的名称别名。

关于如何做到这一点的详细信息留给读者练习:)

答案 2 :(得分: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_*方法实际上为您创建了方法。