Python как __getattr__ для Ruby / JRuby

Есть ли что-то вроде Python __getattr__ для Руби? В 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 ответа

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

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

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

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

Другие вопросы по тегам