binder 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.
- data/README.rdoc +101 -1
- data/lib/binder/object.rb +43 -0
- data/lib/binder.rb +1 -0
- data/spec/binder/object_spec.rb +81 -0
- metadata +4 -2
data/README.rdoc
CHANGED
@@ -3,6 +3,13 @@
|
|
3
3
|
# gem install binder
|
4
4
|
|
5
5
|
= Use
|
6
|
+
|
7
|
+
binder allows you to change the closure in which a proc is executed. This is helpful for anyone developing their own domain specific language in ruby. For more information about proc binding, check out this post I wrote which in turn inspired me to write this gem: http://moonmaster9000.tumblr.com/post/398991873/creating-cleaner-apis
|
8
|
+
|
9
|
+
|
10
|
+
== Proc#bind_to
|
11
|
+
|
12
|
+
The #bind_to method on a proc instance allows you to change the closure in which the proc is run:
|
6
13
|
|
7
14
|
# irb
|
8
15
|
>> require 'binder'
|
@@ -27,4 +34,97 @@
|
|
27
34
|
==> "why should i?"
|
28
35
|
|
29
36
|
>> command.bind_to(Dog.new).call
|
30
|
-
==> "ruff!"
|
37
|
+
==> "ruff!"
|
38
|
+
|
39
|
+
|
40
|
+
== Object##bind
|
41
|
+
|
42
|
+
binder also provides the "#bind" object class method to DRY up your DSL instance methodsmethods:
|
43
|
+
|
44
|
+
>> class Dog
|
45
|
+
>> bind :do_trick, :self
|
46
|
+
>>
|
47
|
+
?> def speak
|
48
|
+
>> "ruff!"
|
49
|
+
>> end
|
50
|
+
>> end
|
51
|
+
==> nil
|
52
|
+
|
53
|
+
>> Dog.new.do_trick { speak }
|
54
|
+
==> "ruff!"
|
55
|
+
|
56
|
+
>> class Cat
|
57
|
+
>> bind :do_trick, Cat
|
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
|
70
|
+
|
71
|
+
>> Cat.new.do_trick { speak }
|
72
|
+
==> "screw you"
|
73
|
+
|
74
|
+
>> class Kitten
|
75
|
+
>> bind :do_trick, :mother
|
76
|
+
>>
|
77
|
+
?> def initialize(mom)
|
78
|
+
>> @mother = mom
|
79
|
+
>> end
|
80
|
+
>> end
|
81
|
+
==> nil
|
82
|
+
|
83
|
+
>> Kitten.new(Cat).do_trick { speak }
|
84
|
+
==> "screw you"
|
85
|
+
|
86
|
+
>> Kitten.new(Cat.new).do_trick { speak }
|
87
|
+
==> "bugger off"
|
88
|
+
|
89
|
+
>> Kitten.new(Dog.new).do_trick { speak }
|
90
|
+
==> "ruff!"
|
91
|
+
|
92
|
+
== Object##bind_class_method
|
93
|
+
|
94
|
+
Whereas the Object##bind method created instance methods, Object##bind_class_method creates class methods:
|
95
|
+
|
96
|
+
>> class Cat
|
97
|
+
>> bind :do_trick, Cat
|
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
|
110
|
+
|
111
|
+
>> class Lion
|
112
|
+
>> bind_class_method :tame, :self
|
113
|
+
>> bind_class_method :do_trick, :child
|
114
|
+
>> class << self
|
115
|
+
>> def down_kitty
|
116
|
+
>> "meow"
|
117
|
+
>> end
|
118
|
+
>>
|
119
|
+
?> def child
|
120
|
+
>> @child ||= Cat
|
121
|
+
>> end
|
122
|
+
>> end
|
123
|
+
>> end
|
124
|
+
==> nil
|
125
|
+
|
126
|
+
>> Lion.tame {down_kitty}
|
127
|
+
==> "meow"
|
128
|
+
|
129
|
+
>> Lion.do_trick { speak }
|
130
|
+
==> "screw you"
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class Object
|
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
|
+
"
|
13
|
+
def #{method_name}(&block)
|
14
|
+
raise ArgumentError, \"You must pass a block to ##{method_name}.\" unless block
|
15
|
+
block.bind_to(#{closure}).call
|
16
|
+
end
|
17
|
+
"
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
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
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/binder.rb
CHANGED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Object do
|
4
|
+
describe "#bind" do
|
5
|
+
it "should create a new instance method that evaluates the block passed it within the requested closure" do
|
6
|
+
class Dog
|
7
|
+
bind :do_trick, :self
|
8
|
+
|
9
|
+
def speak
|
10
|
+
"ruff!"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
Dog.new.do_trick { speak }.should == "ruff!"
|
15
|
+
|
16
|
+
class Cat
|
17
|
+
bind :do_trick, Cat
|
18
|
+
|
19
|
+
class << self
|
20
|
+
def speak
|
21
|
+
"screw you"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def speak
|
26
|
+
"bugger off"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Cat.new.do_trick { speak }.should == "screw you"
|
31
|
+
|
32
|
+
class Kitten
|
33
|
+
bind :do_trick, :mother
|
34
|
+
|
35
|
+
def initialize(mom)
|
36
|
+
@mother = mom
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
Kitten.new(Cat).do_trick { speak }.should == "screw you"
|
41
|
+
Kitten.new(Cat.new).do_trick { speak }.should == "bugger off"
|
42
|
+
Kitten.new(Dog.new).do_trick { speak }.should == "ruff!"
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#bind_class_method" do
|
47
|
+
it "should create a class method responder that binds to either a new class or the return value of a class method" do
|
48
|
+
class Cat
|
49
|
+
bind :do_trick, Cat
|
50
|
+
|
51
|
+
class << self
|
52
|
+
def speak
|
53
|
+
"screw you"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def speak
|
58
|
+
"bugger off"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class Lion
|
63
|
+
bind_class_method :tame, :self
|
64
|
+
bind_class_method :do_trick, :child
|
65
|
+
class << self
|
66
|
+
def down_kitty
|
67
|
+
"meow"
|
68
|
+
end
|
69
|
+
|
70
|
+
def child
|
71
|
+
@child ||= Cat
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
Lion.tame {down_kitty}.should == "meow"
|
77
|
+
Lion.do_trick { speak }.should == "screw you"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
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.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Parker
|
@@ -13,7 +13,7 @@ date: 2010-02-20 00:00:00 -05:00
|
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
|
-
description: Binder allows to evaluate a proc in a closure other than the one in which it was created. It also includes a method :bind to DRY up code for anyone creating a domain specific language.
|
16
|
+
description: Binder allows you to evaluate a proc in a closure other than the one in which it was created. It also includes a method :bind to DRY up code for anyone creating a domain specific language.
|
17
17
|
email: moonmaster9000@gmail.com
|
18
18
|
executables: []
|
19
19
|
|
@@ -24,6 +24,7 @@ extra_rdoc_files:
|
|
24
24
|
files:
|
25
25
|
- README.rdoc
|
26
26
|
- lib/binder.rb
|
27
|
+
- lib/binder/object.rb
|
27
28
|
- lib/binder/proc.rb
|
28
29
|
has_rdoc: true
|
29
30
|
homepage: http://github.com/moonmaster9000/binder
|
@@ -54,5 +55,6 @@ signing_key:
|
|
54
55
|
specification_version: 3
|
55
56
|
summary: A tool for rebinding your ruby procs, with a helper for DSL creaters.
|
56
57
|
test_files:
|
58
|
+
- spec/binder/object_spec.rb
|
57
59
|
- spec/binder/proc_spec.rb
|
58
60
|
- spec/spec_helper.rb
|