Python как __getattr__ для Ruby / JRuby - PullRequest
4 голосов
/ 28 ноября 2011

Есть ли что-то вроде Python __getattr__ для Ruby?В Python obj.__getattr__ вызывается при обращении к неопределенному атрибуту (методу или свойству).Я нашел method_missing в Ruby, но он не работает для свойств.

Мой пример использования: я тестирую 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 ]

3 голосов
/ 28 ноября 2011

Я не уверен, что это относится к вашему случаю использования, но в общем случае 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     
1 голос
/ 28 ноября 2011

JRuby выполняет это преобразование в коде Java, обходя методы отраженного класса и добавляя псевдонимы для имен Ruby.Вы можете сделать это и из Ruby.Mirah имеет доступ к фактическим экземплярам java.lang.Class для всех классов, с которыми вы компилируете, и в результате мог бы делать то же имя с псевдонимом как часть фаз компилятора.

Подробно о том, как именносделать это оставлено в качестве упражнения для читателя:)

0 голосов
/ 28 ноября 2011

Объекты в 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_* фактически создают методы для вас.

...