Computer Science Canada

A tiny bit of metaprogramming magic

Author:  wtd [ Sun Dec 14, 2008 3:13 am ]
Post subject:  A tiny bit of metaprogramming magic

Ruby:
class <<Object
        define_method :delegate do |ivar, *mnames|
                mnames.each do |mname|
                        instance_eval do
                                define_method mname do |*args|
                                        instance_variable_get(:"@#{ivar}").send(mname, *args)
                                end
                        end
                end
        end
end


A simple demo:

Ruby:
class Foo
        delegate :bar, :abs

        def initialize
                @bar = -1
        end
end


Now:

Ruby:
Foo.new.abs


Will yield:

code:
1

Author:  gianni [ Sun Dec 14, 2008 3:19 am ]
Post subject:  RE:A tiny bit of metaprogramming magic

Tres cool, this kind of stuff makes me feel all warm and fuzzy inside.

Author:  gianni [ Sun Dec 14, 2008 3:44 am ]
Post subject:  Re: A tiny bit of metaprogramming magic

My small contribution based entirely off of wtd's code:

Ruby:
class <<Object
  define_method :delegalias do |ivar, alias_name, meth|
    instance_eval do
      define_method alias_name do |*args|
        instance_variable_get(:"@#{ivar}").send(meth, *args)
      end
    end
  end
end


Demo:
Ruby:
class Foo
  delegalias :person, :to_s, :inspect
 
  def initialize
    @person = {:name => "John Smith", :id => 1402, :email => "jsmith@domain.tld"}
  end
end


Ruby:
Foo.new.to_s


Yields:
code:
"{:name=>\"John Smith\", :email=>\"jsmith@domain.tld\", :id=>1402}"

Author:  wtd [ Sun Dec 14, 2008 3:48 am ]
Post subject:  RE:A tiny bit of metaprogramming magic

Most excellent.

Author:  Insectoid [ Sun Dec 14, 2008 4:40 pm ]
Post subject:  RE:A tiny bit of metaprogramming magic

tres confused.

I am completely lost, though with under a week (or has it been a week?) of Ruby experience, that is to be expected. What does class <<object do? What does 'delegate' do?

Author:  wtd [ Sun Dec 14, 2008 5:35 pm ]
Post subject:  RE:A tiny bit of metaprogramming magic

In Ruby classes are objects. By using "class <<Object" I am working within the context of the class rather than instances of it.

As for delegate, it is just a method, but one on the class, rather than instances of it. What it does is to define a method on instances of the class.

code:
>> class <<Object
>>         define_method :delegate do |ivar, *mnames|
?>                 mnames.each do |mname|
?>                         instance_eval do
?>                                 define_method mname do |*args|
?>                                         instance_variable_get(:"@#{ivar}").send(mname, *args)
>>                                 end
>>                         end
>>                 end
>>         end
>> end
=> #<Proc:0x082f0960@(irb):2>
>> class Foo
>>    def initialize
>>       @bar = -32
>>    end
>> end
=> nil
>> Foo.delegate(:bar, :abs)
=> [:abs]
>> a = Foo.new
=> #<Foo:0x82e9160 @bar=-32>
>> a.abs
=> 32
>>


The equivalent manual code would be:

code:
class Foo
   def abs(*args)
      @bar.abs(*args)
   end
end

Author:  Cowzero [ Mon Feb 18, 2019 2:33 am ]
Post subject:  RE:A tiny bit of metaprogramming magic

Is a great knowledge


: