nakajima-proxen 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/proxen.rb +79 -12
  2. metadata +1 -1
data/lib/proxen.rb CHANGED
@@ -1,25 +1,92 @@
1
1
  module Proxen
2
- def proxy_to(target, options={})
3
- if options[:blank_slate]
4
- class_eval do
2
+ class Proxy
3
+ class << self
4
+ def add(klass, *args)
5
+ store[klass] = new(klass, *args)
6
+ end
7
+
8
+ def handle(instance, sym, *args, &block)
9
+ klass = Object.instance_method(:class).bind(instance).call
10
+ if proxy = store[klass]
11
+ proxy.handle(instance, sym, *args, &block)
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def store
18
+ @store ||= {}
19
+ end
20
+ end
21
+
22
+ def initialize(klass, *args)
23
+ @klass = klass
24
+ @options = args.last.is_a?(Hash) ? args.pop : {}
25
+ @targets = Array(args).flatten
26
+
27
+ blankify! if @options[:blank_slate]
28
+ end
29
+
30
+ def handle(instance, sym, *args, &block)
31
+ if target = target_for(instance, sym) and should?(instance, sym)
32
+ instance.__send__(target).__send__(sym, *args, &block)
33
+ end
34
+ end
35
+
36
+ def blankify!
37
+ @klass.class_eval do
5
38
  instance_methods.each do |sym|
6
39
  undef_method(sym) unless sym.to_s =~ /__/
7
40
  end
8
41
  end
9
42
  end
10
-
11
- cond = options[:if] ? "sym.to_s =~ #{options[:if].inspect}" : "true"
12
-
43
+
44
+ private
45
+
46
+ def should?(instance, sym)
47
+ case @options[:if] || @options[:unless]
48
+ when Proc then calls?(sym)
49
+ when Regexp then match?(sym)
50
+ when Symbol then sends?(instance, sym)
51
+ else true
52
+ end
53
+ end
54
+
55
+ def calls?(sym)
56
+ case
57
+ when fn = @options[:if] then fn.call(sym)
58
+ when fn = @options[:unless] then not fn.call(sym)
59
+ end
60
+ end
61
+
62
+ def sends?(instance, sym)
63
+ case
64
+ when cond = @options[:if] then instance.__send__(cond, sym)
65
+ when cond = @options[:unless] then not instance.__send__(cond, sym)
66
+ end
67
+ end
68
+
69
+ def match?(sym)
70
+ case
71
+ when regex = @options[:if] then sym.to_s =~ regex
72
+ when regex = @options[:unless] then not sym.to_s =~ regex
73
+ end
74
+ end
75
+
76
+ def target_for(instance, sym)
77
+ @targets.detect { |t| instance.__send__(t).respond_to?(sym) }
78
+ end
79
+ end
80
+
81
+ def proxy_to(*targets)
82
+ Proxen::Proxy.add(self, *targets)
83
+
13
84
  class_eval(<<-END, __FILE__, __LINE__)
14
85
  def method_missing(sym, *args, &block)
15
- if #{cond}
16
- #{target}.send(sym, *args, &block)
17
- else
18
- super
19
- end
86
+ Proxen::Proxy.handle(self, sym, *args, &block) || super
20
87
  end
21
88
  END
22
89
  end
23
90
  end
24
91
 
25
- Class.send :include, Proxen
92
+ Class.send :include, Proxen
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nakajima-proxen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pat Nakajima