Class: Wrapr::Wrapr

Inherits:
Object
  • Object
show all
Defined in:
lib/wrapr.rb

Overview

Allows method wrapping

Usage

 w = Wrapr::Wrapr.new(Exception)
 # #before can mutate the instance and args as well
 w.before(:initialize) do |this,*args|
   args[0].upcase!
   args
 end
 puts Exception.new("foo").to_s # FOO
 w.around(:to_s) do |this,method,*args|
   puts "Before to_s" 
   result = method.call() 
   result+=" "
end
puts Exception.new("foo").to_s  # FOO, "Before to_s OOF "
w.after(:to_s) do |this,result|
  result.downcase
end
puts Exception.new("foo").to_s  # FOO, "Before to_s foo"

Instance Method Summary collapse

Constructor Details

#initialize(klass) ⇒ Wrapr

Returns a new instance of Wrapr.



30
31
32
# File 'lib/wrapr.rb', line 30

def initialize(klass)
  @klass=klass 
end

Instance Method Details

#after(method, &block) ⇒ Object

Executes block after method is called Passes the response of method into block

Transparent after

Wrapr.new(Exception).after(:to_s) do |self,*result|
  return result
end


77
78
79
80
81
82
83
84
# File 'lib/wrapr.rb', line 77

def after(method,&block)
  unbound = @klass.instance_method(method)
  @klass.class_eval do
    define_method(method) do |*outer_args|
      block.call(self, *unbound.bind(self).call(*outer_args))
    end
  end
end

#around(method, &block) ⇒ Object

Executes block around Call of wrapped method is responsibility of the passed block

Transparently

Wrapr.new(Exception).around(:to_s) { |self,method,*outer_args|
  method.call(*outer_args) 
}


41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/wrapr.rb', line 41

def around(method,&block)
  # fetch the unbound instance method
  unbound = @klass.instance_method(method)
  @klass.class_eval do 
    # create a new method with the same name
    define_method(method) do |*outer_args|
      # we pass the current instance and overridden method
      block.call(self,unbound.bind(self),*outer_args)
      # We cannot do self.send(method,...) because we are redefining @method, causes recursion
    end
  end
end

#before(method, &block) ⇒ Object

Executes block before method is called Passes the return of the block to method

Transparent before

Wrapr.new(Exception).before(:to_s) { |self,*outer_args| 
  return outer_args  
}


61
62
63
64
65
66
67
68
# File 'lib/wrapr.rb', line 61

def before(method,&block)
  unbound = @klass.instance_method(method)
  @klass.class_eval do
    define_method(method) do |*outer_args|
      unbound.bind(self).call(*block.call(self,*outer_args)) 
    end
  end
end