binder 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -39,30 +39,30 @@ The #bind_to method on a proc instance allows you to change the closure in which
39
39
 
40
40
  == Object##bind
41
41
 
42
- binder also provides the "#bind" object class method to DRY up your DSL instance methodsmethods:
42
+ binder also provides the "#bind" object class method to DRY up your DSL instance methods:
43
43
 
44
44
  >> class Dog
45
- >> bind :do_trick, :self
45
+ >> bind :do_trick, :self # binds to the instance of Dog
46
46
  >>
47
- ?> def speak
48
- >> "ruff!"
49
- >> end
47
+ >> def speak
48
+ >> "ruff!"
50
49
  >> end
50
+ >> end
51
51
  ==> nil
52
52
 
53
53
  >> Dog.new.do_trick { speak }
54
54
  ==> "ruff!"
55
55
 
56
56
  >> class Cat
57
- >> bind :do_trick, Cat
57
+ >> bind :do_trick, :class # binds to Cat, not an instance of Cat
58
58
  >>
59
- ?> class << self
59
+ >> class << self
60
60
  >> def speak
61
61
  >> "screw you"
62
62
  >> end
63
63
  >> end
64
64
  >>
65
- ?> def speak
65
+ >> def speak
66
66
  >> "bugger off"
67
67
  >> end
68
68
  >> end
@@ -72,9 +72,9 @@ binder also provides the "#bind" object class method to DRY up your DSL instance
72
72
  ==> "screw you"
73
73
 
74
74
  >> class Kitten
75
- >> bind :do_trick, :mother
75
+ >> bind :do_trick, :mother # binds to @mother instance variable
76
76
  >>
77
- ?> def initialize(mom)
77
+ >> def initialize(mom)
78
78
  >> @mother = mom
79
79
  >> end
80
80
  >> end
@@ -94,36 +94,37 @@ binder also provides the "#bind" object class method to DRY up your DSL instance
94
94
  Whereas the Object##bind method created instance methods, Object##bind_class_method creates class methods:
95
95
 
96
96
  >> class Cat
97
- >> bind :do_trick, Cat
97
+ >> bind :do_trick, :class # binds to Cat class, not an instance of Cat
98
98
  >>
99
- ?> class << self
99
+ >> class << self
100
100
  >> def speak
101
- >> "screw you"
102
- >> end
101
+ >> "screw you"
102
+ >> end
103
103
  >> end
104
104
  >>
105
- ?> def speak
105
+ >> def speak
106
106
  >> "bugger off"
107
107
  >> end
108
108
  >> end
109
109
  ==> nil
110
110
 
111
111
  >> class Lion
112
- >> bind_class_method :tame, :self
113
- >> bind_class_method :do_trick, :child
112
+ >> bind_class_method :tame, :self # binds to Lion, since "self" will be evaluated in the context
113
+ >> # of a class method
114
+ >> bind_class_method :do_trick, :child # binds to value returned by method "child"
114
115
  >> class << self
115
116
  >> def down_kitty
116
117
  >> "meow"
117
118
  >> end
118
119
  >>
119
- ?> def child
120
+ >> def child
120
121
  >> @child ||= Cat
121
122
  >> end
122
123
  >> end
123
124
  >> end
124
125
  ==> nil
125
126
 
126
- >> Lion.tame {down_kitty}
127
+ >> Lion.tame { down_kitty }
127
128
  ==> "meow"
128
129
 
129
130
  >> Lion.do_trick { speak }
data/lib/binder/object.rb CHANGED
@@ -1,43 +1,44 @@
1
1
  class Object
2
2
  class << self
3
- def bind(method_name, closure)
4
- if !closure.kind_of?(Symbol)
5
- closure = closure.to_s
6
- else
7
- closure = closure == :self ? "self" : "@#{closure}"
8
- end
9
-
10
- self.class_eval do
11
- eval(
12
- "
3
+ def bind_in_context(method_name, closure, eval_context=:class_eval)
4
+ raise ArgumentError, "You may only pass symbols to #bind and #bind_class_method" unless closure.kind_of?(Symbol)
5
+ if closure == :self
6
+ self.send(eval_context) do
7
+ eval(
8
+ "
13
9
  def #{method_name}(&block)
14
- raise ArgumentError, \"You must pass a block to ##{method_name}.\" unless block
15
- block.bind_to(#{closure}).call
10
+ if block
11
+ block.bind_to(self).call
12
+ end
13
+ end
14
+ "
15
+ )
16
+ end
17
+ else
18
+ self.send(eval_context) do
19
+ eval(
20
+ "
21
+ def #{method_name}(&block)
22
+ if block
23
+ if self.respond_to?(:#{closure})
24
+ block.bind_to(self.#{closure}).call
25
+ elsif @#{closure}
26
+ block.bind_to(@#{closure}).call
27
+ else
28
+ block.bind_to(self.#{closure}).call
29
+ end
30
+ end
16
31
  end
17
- "
18
- )
19
- end
32
+ "
33
+ )
34
+ end
35
+ end
20
36
  end
21
37
 
38
+ alias_method :bind, :bind_in_context
39
+
22
40
  def bind_class_method(method_name, closure)
23
- if !closure.kind_of?(Symbol)
24
- closure = closure.to_s
25
- else
26
- closure = closure == :self ? "self" : "#{closure}"
27
- end
28
-
29
- self.class_eval do
30
- eval(
31
- "
32
- class << self
33
- def #{method_name}(&block)
34
- raise ArgumentError, \"You must pass a block to ##{method_name}.\" unless block
35
- block.bind_to(#{closure}).call
36
- end
37
- end
38
- "
39
- )
40
- end
41
+ bind_in_context method_name, closure, :instance_eval
41
42
  end
42
43
  end
43
- end
44
+ end
@@ -3,6 +3,12 @@ require 'spec_helper'
3
3
  describe Object do
4
4
  describe "#bind" do
5
5
  it "should create a new instance method that evaluates the block passed it within the requested closure" do
6
+ proc do
7
+ class Platypus
8
+ bind :do_trick, "invalid argument"
9
+ end
10
+ end.should raise_error(ArgumentError, "You may only pass symbols to #bind and #bind_class_method")
11
+
6
12
  class Dog
7
13
  bind :do_trick, :self
8
14
 
@@ -14,7 +20,7 @@ describe Object do
14
20
  Dog.new.do_trick { speak }.should == "ruff!"
15
21
 
16
22
  class Cat
17
- bind :do_trick, Cat
23
+ bind :do_trick, :class
18
24
 
19
25
  class << self
20
26
  def speak
@@ -46,7 +52,7 @@ describe Object do
46
52
  describe "#bind_class_method" do
47
53
  it "should create a class method responder that binds to either a new class or the return value of a class method" do
48
54
  class Cat
49
- bind :do_trick, Cat
55
+ bind :do_trick, :class
50
56
 
51
57
  class << self
52
58
  def speak
@@ -78,4 +84,4 @@ describe Object do
78
84
  end
79
85
  end
80
86
  end
81
- end
87
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: binder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Parker
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-20 00:00:00 -05:00
12
+ date: 2010-02-21 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies: []
15
15