binder 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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