nakajima-proxen 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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