4

Python __getattr__for Ruby のようなものはありますか? Python ではobj.__getattr__、未定義の属性 (メソッドまたはプロパティ) が参照されたときに呼び出されます。Rubyで見つけましmethod_missingたが、プロパティでは機能しません。

私の使用例は次のとおりです。Mirahを JRuby -> Java コンパイラとしてテストしています。標準の JRuby では、Swing のメソッドと属性は "Rubyfied" (例: label.setText "x" => label.text = "x") ですが、Mirah には JRuby のような独自のランタイム ライブラリがないため、Mirah ではそうではありません。 . 次に、実行時に属性参照を取得し、各呼び出しを対応する Swing メソッドにマップします (label.text => label.getText() / label.text = "x" => label.setText("x") ) .

4

3 に答える 3

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     
于 2011-11-28T19:42:58.080 に答える
1

JRuby は、反映されたクラスのメソッドをたどり、Ruby 名のエイリアスを追加することによって、Java コードでこの変換を行います。これは Ruby からも実行できます。Mirah は、コンパイル対象のすべてのクラスの実際の java.lang.Class インスタンスにアクセスできるため、コンパイラ フェーズの一部として、この同じ名前のエイリアスを実行できます。

これを正確に行う方法の詳細は、読者の演習として残されています:)

于 2011-11-28T19:22:06.017 に答える
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_*メソッドは実際にメソッドを作成します。

于 2011-11-28T19:58:17.400 に答える