Meta Programming

Content

  • What is meta programming?
  • Method Dynamism
  • Runtime class instantiation
  • Opening a class
  • Method Missing
  • Reflection

Meta Programming

  • is a programming technique in which computer programs have the ability to treat programs as their data.
  • It means that a program can be designed to read, generate, analyse or transform other programs, and even modify itself while running
  • allows programmers to minimize the number of lines of code to express a solution, and thus reducing the development time
  • allows programs greater flexibility to efficiently handle new situations without recompilation.

Dynamic method Calling

class MethodCaller
  def initialize(foo)
    @foo = foo
  end

  def perform(action)
    @foo.send action
  end
end

method_caller = MethodCaller.new(9)
method_caller.perform("to_f")

Private method calling



class Friend
  def initialize(friend)
    @friend = friend
  end
   
  private
  def all
    friends 
  end
end

new_friend = Friend.new
new_friend.send(:all)

Dynamic methods Generation


class Notification
  %w{ create update delete }.each do |action|
    define_method("emit_#{action}".gsub(/e$/, 'ing')) do |something|
      "#{action} is performed on #{something.class}"
    end
  end
end

notification = Notification.new
puts notification.emit_creating user
# create is performed on User
puts notification.emit_deleting account

Alias method

class Timeline
  attr_reader :tweets 
  alias_method :contents, :tweets 

  def initialize(tweets = []) 
    @tweets = tweets
  end  
end

method removal

 

Module#undef_method

-  removes method, including the inherited ones.

 

Module#remove_method( )

- removes the method from the receiver, but it leaves inherited methods alone.
 

undef_method example

Example 1 using undef_method
class A 
    def x
        puts "x from A class"
    end
end

class B < A
    def x
        puts "x from B Class"
    end
    undef_method :x
end

obj = B.new
obj.x
result: undefined methodx' for # (NoMethodError)

remove_method example

class A 
    def x
        puts "x from A class"
    end
end

class B < A
    def x
        puts "x from B Class"
    end
    remove_method :x
end

obj = B.new
obj.x
x from A class

const_get

  • It is often used to instantiate classes at runtime

 

klass = Object.const_get('String') 
obj = klass.new
obj.length

Opening a class

  • An existing class can be opened in ruby to add a new behaviour.
  • e.g. add new method or override existing method.

 

class String  
  def write_size  
    self.size  
  end  
end  
size_writer = "Tell me my size!"  
puts size_writer.write_size

class_eval

  • Adds instance method to the class

 

class Person
end
Person.class_eval do
  def say_hello
    "Hello!" 
  end
end
jimmy = Person.new
jimmy.say_hello # "Hello!"

instance_eval

  • Adds class method to the class

 

class Person 
end

Person.instance_eval do 
  def human?
    true 
  end
end

Person.human? # true

method_missing

  • Handle if a method is missing for an object

 


class Greeting
  def method_missing(sym, *args, &block)
    puts "#{sym} was called with #{args} and #{block.call}"
  end
end

Greeting.new.hello("world") { p "bye!" }

Introspection or Reflection

  • In Ruby it's possible to read information about a class or object at runtime. We could use some of the methods

 

defined? var_name
# nil or true


obj = String.new
if obj.respond_to?(:program)
  obj.program
else
  puts "Sorry, the object doesn't understand the 'program' message."
end

Questions?

Thanks

Meta Programming in Ruby

By Datt Dongare

Meta Programming in Ruby

Meta programming in ruby

  • 541