gist: 1724 Download_button fork
public
Description:
Decorator for Ruby, inspired by Python
Public Clone URL: git://gist.github.com/1724.git
Text
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
class Module
  def declare(decorator, *args)
    orig_method_added = method(:method_added)
    metaclass = (class << self; self end)
    defined_methods = []
    metaclass.send(:define_method, :method_added) do |name|
      orig_method_added.call(name)
      defined_methods << name
    end
    begin
      yield
    ensure
      metaclass.send(:remove_method, :method_added)
      if orig_method_added.owner == metaclass
        metaclass.send(:define_method, :method_added, orig_method_added)
      end
    end
    decorator = method(decorator) unless decorator.respond_to?(:call)
    defined_methods.each do |name|
      method_body = decorator.call(name, *args)
      define_method(name, method_body)
    end
  end
  def before(name)
    orig = instance_method(name)
    proc {|*args|
      yield(name, args)
      orig.bind(self).call(*args)
    }
  end
  def after(name)
    orig = instance_method(name)
    proc {|*args|
      result = orig.bind(self).call(*args)
      yield(name, args, result)
    }
  end
  def around(name)
    orig = instance_method(name)
    proc {|*args|
      yield(:before, name, args)
      result = orig.bind(self).call(*args)
      yield(:after, name, args, result)
    }
  end
 
  def type(name, types)
    before(name) do |name, args|
      args.zip(types).each_with_index do |(arg, type), i|
        raise TypeError, "#{i}th argument #{arg} should be #{type}" unless arg.instance_of?(type)
      end
    end
  end
end
 
if $0 == __FILE__
  class Calc
    declare :type, [Float, Float] do
      def add(x,y); x+y end
      def sub(x,y); x-y end
      def mul(x,y); x*y end
      def div(x,y); x/y end
    end
  end
 
  calc = Calc.new
  p calc.add(1.0,2.0)
  p calc.sub(1.0,2)
end

Owner

yugui

Revisions