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 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
@@ -1 +1,2 @@
1
1
  require 'binder/proc'
2
+ require 'binder/object'
@@ -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.1
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