binder 0.0.3 → 0.0.4
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.
- data/README.rdoc +135 -98
- data/lib/binder/object.rb +15 -1
- data/spec/binder/object_spec.rb +24 -1
- metadata +1 -1
data/README.rdoc
CHANGED
@@ -11,121 +11,158 @@ binder allows you to change the closure in which a proc is executed. This is hel
|
|
11
11
|
|
12
12
|
The #bind_to method on a proc instance allows you to change the closure in which the proc is run:
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
require 'binder'
|
15
|
+
# ==> true
|
16
|
+
|
17
|
+
def speak
|
18
|
+
"why should i?"
|
19
|
+
end
|
17
20
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
==> #<Proc:0x012c6a04@(irb):28>
|
32
|
-
|
33
|
-
>> command.call
|
34
|
-
==> "why should i?"
|
35
|
-
|
36
|
-
>> command.bind_to(Dog.new).call
|
37
|
-
==> "ruff!"
|
21
|
+
class Dog
|
22
|
+
def speak
|
23
|
+
"ruff!"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
command = proc { speak }
|
28
|
+
|
29
|
+
command.call
|
30
|
+
# ==> "why should i?"
|
31
|
+
|
32
|
+
command.bind_to(Dog.new).call
|
33
|
+
# ==> "ruff!"
|
38
34
|
|
35
|
+
== Object#tell (or #ask, #beg, or #teach)
|
36
|
+
|
37
|
+
The "tell"/"ask"/"beg"/"teach" method is essentially short hand for an instance_eval on an object - it simply presents you with a more human readable way of using this language feature:
|
38
|
+
|
39
|
+
class Dog
|
40
|
+
def speak
|
41
|
+
puts "ruff!"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
fido = Dog.new
|
46
|
+
|
47
|
+
fido.instance_eval do
|
48
|
+
speak
|
49
|
+
end
|
50
|
+
|
51
|
+
# ==> would print "ruff!"
|
52
|
+
|
53
|
+
tell fido do
|
54
|
+
speak
|
55
|
+
end
|
56
|
+
|
57
|
+
# or
|
58
|
+
|
59
|
+
tell(fido) { speak }
|
60
|
+
|
61
|
+
# or
|
62
|
+
|
63
|
+
tell(fido, :to) { speak }
|
64
|
+
|
65
|
+
# ==> would all print "ruff!" - and these are all equivalent to the instance eval above
|
66
|
+
|
67
|
+
commands = proc { speak }
|
68
|
+
|
69
|
+
fido.instance_eval(&commands)
|
70
|
+
# ==> would print "ruff"
|
71
|
+
|
72
|
+
tell fido, commands
|
73
|
+
# ==> would also print "ruff!"
|
39
74
|
|
40
75
|
== Object##bind
|
41
76
|
|
42
77
|
binder also provides the "#bind" object class method to DRY up your DSL instance methods:
|
43
78
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
>> Dog.new.do_trick { speak }
|
54
|
-
==> "ruff!"
|
79
|
+
class Dog
|
80
|
+
# binds a "do_trick" instance method to the instance of Dog
|
81
|
+
bind :do_trick, :self
|
82
|
+
|
83
|
+
def speak
|
84
|
+
"ruff!"
|
85
|
+
end
|
86
|
+
end
|
55
87
|
|
56
|
-
|
57
|
-
|
58
|
-
>>
|
59
|
-
>> class << self
|
60
|
-
>> def speak
|
61
|
-
>> "screw you"
|
62
|
-
>> end
|
63
|
-
>> end
|
64
|
-
>>
|
65
|
-
>> def speak
|
66
|
-
>> "bugger off"
|
67
|
-
>> end
|
68
|
-
>> end
|
69
|
-
==> nil
|
88
|
+
Dog.new.do_trick { speak }
|
89
|
+
# ==> "ruff!"
|
70
90
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
91
|
+
class Cat
|
92
|
+
# binds a block passed to a "do_trick" instance method to the Cat class
|
93
|
+
bind :do_trick, :class
|
94
|
+
|
95
|
+
class << self
|
96
|
+
def speak
|
97
|
+
"screw you"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def speak
|
102
|
+
"bugger off"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
Cat.new.do_trick { speak }
|
107
|
+
# ==> "screw you"
|
82
108
|
|
83
|
-
|
84
|
-
|
109
|
+
class Kitten
|
110
|
+
bind :do_trick, :mother # binds to @mother instance variable
|
111
|
+
|
112
|
+
def initialize(mom)
|
113
|
+
@mother = mom
|
114
|
+
end
|
115
|
+
end
|
85
116
|
|
86
|
-
|
87
|
-
|
117
|
+
Kitten.new(Cat).do_trick { speak }
|
118
|
+
# ==> "screw you"
|
88
119
|
|
89
|
-
|
90
|
-
|
120
|
+
Kitten.new(Cat.new).do_trick { speak }
|
121
|
+
# ==> "bugger off"
|
91
122
|
|
123
|
+
Kitten.new(Dog.new).do_trick { speak }
|
124
|
+
# ==> "ruff!"
|
125
|
+
|
92
126
|
== Object##bind_class_method
|
93
127
|
|
94
128
|
Whereas the Object##bind method created instance methods, Object##bind_class_method creates class methods:
|
95
129
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
>> class << self
|
100
|
-
>> def speak
|
101
|
-
>> "screw you"
|
102
|
-
>> end
|
103
|
-
>> end
|
104
|
-
>>
|
105
|
-
>> def speak
|
106
|
-
>> "bugger off"
|
107
|
-
>> end
|
108
|
-
>> end
|
109
|
-
==> nil
|
130
|
+
class Cat
|
131
|
+
# binds to Cat class, not an instance of Cat
|
132
|
+
bind :do_trick, :class
|
110
133
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
134
|
+
class << self
|
135
|
+
def speak
|
136
|
+
"screw you"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def speak
|
141
|
+
"bugger off"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
class Lion
|
146
|
+
# binds to Lion, since "self" will be evaluated in the context
|
147
|
+
# of a class method
|
148
|
+
bind_class_method :tame, :self
|
149
|
+
|
150
|
+
# binds to value returned by method "child"
|
151
|
+
bind_class_method :do_trick, :child
|
152
|
+
|
153
|
+
class << self
|
154
|
+
def down_kitty
|
155
|
+
"meow"
|
156
|
+
end
|
157
|
+
|
158
|
+
def child
|
159
|
+
@child ||= Cat
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
126
163
|
|
127
|
-
|
128
|
-
|
164
|
+
Lion.tame { down_kitty }
|
165
|
+
# ==> "meow"
|
129
166
|
|
130
|
-
|
131
|
-
|
167
|
+
Lion.do_trick { speak }
|
168
|
+
# ==> "screw you"
|
data/lib/binder/object.rb
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
class Object
|
2
|
-
|
2
|
+
def tell(closure, relayed_message=nil, &message)
|
3
|
+
if relayed_message && relayed_message.kind_of?(Proc)
|
4
|
+
closure.instance_eval(&relayed_message)
|
5
|
+
elsif message
|
6
|
+
closure.instance_eval(&message)
|
7
|
+
else
|
8
|
+
raise StandardError, "What is your command?"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
alias ask tell
|
13
|
+
alias teach tell
|
14
|
+
alias beg tell
|
15
|
+
|
16
|
+
class << self
|
3
17
|
def bind_in_context(method_name, closure, eval_context=:class_eval)
|
4
18
|
raise ArgumentError, "You may only pass symbols to #bind and #bind_class_method" unless closure.kind_of?(Symbol)
|
5
19
|
if closure == :self
|
data/spec/binder/object_spec.rb
CHANGED
@@ -1,7 +1,30 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Object do
|
4
|
-
describe "#
|
4
|
+
describe "#tell" do
|
5
|
+
it "should run the given block or proc inside the requested object closure" do
|
6
|
+
class Baby
|
7
|
+
def say_dada
|
8
|
+
"waaaa"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
Object.new.tell(Baby.new) { say_dada }.should == "waaaa"
|
13
|
+
Object.tell(Baby.new) { say_dada }.should == "waaaa"
|
14
|
+
tell(Baby.new) { say_dada }.should == "waaaa"
|
15
|
+
|
16
|
+
tell Baby.new, :to do
|
17
|
+
say_dada
|
18
|
+
end
|
19
|
+
|
20
|
+
to_say_dada = proc { say_dada }
|
21
|
+
Object.new.tell(Baby.new, to_say_dada).should == "waaaa"
|
22
|
+
Object.tell(Baby.new, to_say_dada).should == "waaaa"
|
23
|
+
tell(Baby.new, to_say_dada).should == "waaaa"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "##bind" do
|
5
28
|
it "should create a new instance method that evaluates the block passed it within the requested closure" do
|
6
29
|
proc do
|
7
30
|
class Platypus
|