Python as __getattr__ for Ruby / JRuby

Is there something like Python __getattr__ for Ruby? In Python, obj.__getattr__ is called when an undefined attribute (method or property) is referenced. I found method_missing in Ruby, but it does not work for properties.

My use case: I am testing Mirah as a JRuby β†’ Java compiler. In standard JRuby, Swing methods and attributes are "Rubyfied" (for example: label.setText "x" => label.text = "x"), but not in Mirah, because Mirah does not have a proprietary runtime library such as JRuby, Then I want to get attribute references at runtime and map each call to the corresponding Swing method (label.text => label.getText () / label.text = "x" => label.setText ("x")),

+4
source share
3 answers

I'm not sure if this applies to your use case, but overall the method_missing should do the trick. How would you expect the Ruby class to recognize the difference between the undefined method and the undefined property? All that it knows is that it has been given a name that it does not recognize. Was it assumed by method or property? Who knows? If you don't talk about setter attributes, in this case = added to the name:

  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 
+3
source

JRuby does this conversion in Java code by skipping the methods of the mirrored class and adding aliases for Ruby names. You can do this with Ruby. Mirah has access to the actual java.lang.Class instances for all the classes you compile, and as a result, can execute the same name aliases as part of the compiler phases.

Details of exactly how to do this are left as an exercise for the reader :)

+1
source

Ruby objects have no "properties." They have instance variables (private variables that store data for each instance) and methods that can access these variables.

Since brackets are optional in calls to the Ruby method, and since syntax sugar allows you to write obj.foo = 42 as a more convenient way to call the obj.foo=( 42 ) method, you might think that these are properties. They are not; they are methods indistinguishable from others.

This code:

 class Foo attr_accessor :bar end f = Foo.new f.bar = 42 puts f.bar #=> 42 

exactly the same as this (much longer) code:

 class Foo def bar @bar end def bar=( val ) @bar = val end end f = Foo.new f.bar=( 42 ) puts( f.bar() ) #=> 42 

The attr_* methods actually create methods for you.

0
source

Source: https://habr.com/ru/post/1383492/


All Articles