2011-11-28 56 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_*方法實際上爲你創建的方法。