methodchain 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -7,20 +7,6 @@ Copyright (c) 2008 Greg Weber, http://gregweber.info
7
7
  Licensed under the MIT license
8
8
 
9
9
  == Examples
10
- === ##tap
11
- if you don't already know about this method, look it up on the net. The tap included here allows message sending.
12
-
13
- ==== old way
14
- arr = [1]
15
- arr.compact! # => nil
16
- arr.first # => 1
17
-
18
- ==== normal ##tap (still valid)
19
- [1].tap {|arr| arr.compact!}.first # => 1
20
-
21
- ==== new ##tap
22
- [1].tap(:compact!).first # => 1
23
-
24
10
  === ##then and ##else
25
11
  ==== old way
26
12
  person = nil
@@ -36,8 +22,8 @@ not a huge savings. But sometimes the person variable is actually a function cal
36
22
  # do some expensive database queries
37
23
  end
38
24
 
39
- location = find(:first)
40
- @phone = location && location.phone # => nil
25
+ person = find(:first)
26
+ @phone = person && person.phone # => nil
41
27
 
42
28
  ==== new way
43
29
  @phone = find(:first).then {phone} # => nil
@@ -48,7 +34,36 @@ We have reduced a line of code and removed a local variable.
48
34
  'a'.then('b') #=> 'b'
49
35
  nil.then('b').else('c') #=> 'c'
50
36
 
37
+ === ##tap
38
+ if you don't already know about this method, look it up on the net. The tap included here allows message sending.
39
+
40
+ ==== old way
41
+ arr = [1]
42
+ arr.compact! # => nil
43
+ arr.first # => 1
44
+
45
+ ==== normal ##tap (still valid)
46
+ [1].tap {|arr| arr.compact!}.first # => 1
47
+
48
+ ==== new ##tap
49
+ [1].tap(:compact!).first # => 1
50
+
51
+ ==== normal ##tap (still valid)
52
+ [1].tap {|arr| arr.compact!}.tap {|arr| arr * 2}.first # => 1
53
+
54
+ ==== new ##tap
55
+ [1].tap( :compact!, [:*, 2] ).first # => 1
56
+
57
+ You can also pass Procs as arguments
58
+ [1].tap( :compact!, lambda{|arr| arr * 2} ).first # => 1
59
+
60
+
51
61
  === ##chain
62
+ chain is like tap, but instead of always returning self, it will return the result of the method call.
63
+ [1].chain(:first) == [1].first
64
+
65
+ But there is an important difference- chain guards against certain results (by default it guards against nil and false)
66
+
52
67
  ==== old way
53
68
  customer = nil
54
69
  customer && customer.order && customer.order.id
@@ -60,7 +75,7 @@ note that this is equivalent to
60
75
 
61
76
  customer.then {order}.then {id}
62
77
 
63
- === ##chain - Custom guards, multiple arguments, and procs
78
+ === ##chain - Custom guards, multiple arguments, and Procs
64
79
  ==== old way - guarding against zero
65
80
  value = 0
66
81
 
@@ -76,7 +91,7 @@ note that this is equivalent to
76
91
  ==== new way
77
92
  value.chain(:abs, [:*, 20]) {|s| s == 0 } # => 0
78
93
 
79
- procs can be used, so this is equivalent to
94
+ Procs can be used, so this is equivalent to
80
95
  value.chain(:abs, lambda {|n| n * 20 }) {|s| s == 0 } # => 0
81
96
 
82
97
  == Usage
@@ -88,14 +103,45 @@ procs can be used, so this is equivalent to
88
103
 
89
104
  === selectively import MethodChain methods
90
105
 
91
- require 'methodchain/not_included'
106
+ require 'methodchain/not-included'
107
+
108
+ You can then include methodchain into selected classes, or you can use the module-import gem to include only certain methods
109
+
110
+ gem install module-import
111
+
112
+ require 'module-import'
113
+ class Object
114
+ import MethodChain, :chain # I only want Object#chain
115
+ end
116
+
117
+ import will still load all the private methods from the module:
118
+ - yield_or_eval
119
+ - send_as_function
120
+ - send_as_functions
121
+
122
+
123
+ ==== not into Object
124
+ To import nothing into the Object namespace
125
+ require 'methodchain/no-import'
126
+
127
+ Then include where needed:
128
+ class MyObject
129
+ include MethodChain
130
+ end
92
131
 
93
- not_included will load the MethodChain module without including it anywhere.
94
- Already have your own version of tap? use the module-import gem to decide what to include
95
132
 
96
133
  == Implementation
97
- * There are no proxy objects and no use of method_missing- these are simply function calls, so it should be fast.
98
- * A helper method called yield_or_eval is also exposed. This method allows the two different block forms {|p| p.name} and {name}, where the first form yields self and the second form is called using instance_eval.
134
+ There are no proxy objects and no use of method_missing- these are simply function calls, so it should be fast.
135
+
136
+ private methods:
137
+ * yield_or_eval: allows the two different block forms {|p| p.name} and {name}, where the first form yields self and the second form is called using instance_eval.
138
+ * send_as_function: allows symbols and arrays to be sent as messages, and calls yield_or_eval on Proc arguments
139
+ * send_as_functions:
140
+
141
+ def send_arguments_as_functions *args
142
+ args.each {|arg| send_as_function arg}
143
+ self
144
+ end
99
145
 
100
146
  == Install
101
147
  gem install methodchain
@@ -66,7 +66,7 @@ task :release => [:test,:record,:rdoc,:website,:package] do
66
66
  end
67
67
 
68
68
  desc "update website"
69
- file :website => ['README','rakefile'] do
69
+ file :website => ['README','Rakefile'] do
70
70
  Dir.chdir '/home/greg/sites/projects/' do
71
71
  (puts (run 'rake projects:update'))
72
72
  (puts (run 'rake deploy:rsync'))
@@ -99,13 +99,13 @@ namespace :readme do
99
99
  task :test do
100
100
  # grab example code from README
101
101
  cd_tmp do
102
- example_file = "#{__DIR__}/example.rb"
102
+ example_file = "#{Dir.pwd}/example.rb"
103
103
 
104
104
  File.write(example_file, (
105
- File.read("#{__DIR__}/lib/methodchain/not_included.rb") <<
105
+ File.read("#{__DIR__}/lib/methodchain/not-included.rb") <<
106
106
  "class Object; include MethodChain end\n" <<
107
107
  File.readlines('../README').grep(/^ / ).
108
- reject {|l| l =~ /^\s*require/ or l.include?('Error')}.
108
+ reject {|l| l =~ /^\s*require/ or l.include?('Error') or l.include? 'gem install'}.
109
109
  join ))
110
110
 
111
111
  command = "ruby ../bin/xmpfilter -c #{example_file}"
@@ -122,7 +122,7 @@ task :record do
122
122
  unless `git diff`.chomp.empty?
123
123
  ARGV.clear
124
124
  puts "enter commit message"
125
- (puts (run "git commit -a -m #{Kernel.gets}"))
125
+ (puts (run "git commit -a -m '#{Kernel.gets}'"))
126
126
  puts "committed! now pushing.. "
127
127
  (puts (run 'git push origin master'))
128
128
  end
@@ -134,13 +134,15 @@ require 'rake/gempackagetask'
134
134
  spec = Gem::Specification.new do |s|
135
135
  s.name = project
136
136
  s.rubyforge_project = project
137
- s.version = "0.2.2"
137
+ s.version = "0.3.0"
138
138
  s.author = "Greg Weber"
139
139
  s.email = "greg@gregweber.info"
140
140
  s.homepage = "http://projects.gregweber.info/#{project}"
141
141
  s.platform = Gem::Platform::RUBY
142
142
  s.summary = "convenience methods for method chaining"
143
- s.files = Dir['./**'] + Dir['*/**']
143
+ s.files = FileList.new('./**', '*/**') do |fl|
144
+ fl.exclude('pkg','pkg/*','tmp','tmp/*')
145
+ end
144
146
  s.require_path = "lib"
145
147
  s.has_rdoc = true
146
148
  s.extra_rdoc_files = ["README"]
@@ -556,7 +556,7 @@ span.run100 {
556
556
  </head>
557
557
  <body>
558
558
  <h3>C0 code coverage information</h3>
559
- <p>Generated on Mon Mar 10 10:31:09 -0500 2008 with <a href='http://eigenclass.org/hiki.rb?rcov'>rcov 0.8.0</a>
559
+ <p>Generated on Thu Mar 13 11:28:30 -0500 2008 with <a href='http://eigenclass.org/hiki.rb?rcov'>rcov 0.8.0</a>
560
560
  </p>
561
561
  <hr /><pre><span class='marked0'>Code reported as executed by Ruby looks like this...
562
562
  </span><span class='marked1'>and this: this line is also marked as covered.
data/coverage/index.html CHANGED
@@ -151,7 +151,7 @@ table.report tr.dark {
151
151
  </head>
152
152
  <body>
153
153
  <h3>C0 code coverage information</h3>
154
- <p>Generated on Mon Mar 10 10:31:09 -0500 2008 with <a href='http://eigenclass.org/hiki.rb?rcov'>rcov 0.8.0</a>
154
+ <p>Generated on Thu Mar 13 11:28:29 -0500 2008 with <a href='http://eigenclass.org/hiki.rb?rcov'>rcov 0.8.0</a>
155
155
  </p>
156
156
  <hr /> <table class='report'>
157
157
  <thead>
@@ -167,21 +167,21 @@ table.report tr.dark {
167
167
  <tr class='light'>
168
168
  <td>TOTAL</td>
169
169
  <td class='lines_total'>
170
- <tt>1038</tt>
170
+ <tt>1047</tt>
171
171
  </td>
172
172
  <td class='lines_code'>
173
- <tt>637</tt>
173
+ <tt>645</tt>
174
174
  </td>
175
175
  <td>
176
176
  <table cellspacing='0' cellpadding='0' align='right'>
177
177
  <tr>
178
178
  <td>
179
- <tt class='coverage_total'>9.2%</tt>&nbsp;</td>
179
+ <tt class='coverage_total'>9.9%</tt>&nbsp;</td>
180
180
  <td>
181
181
  <table cellspacing='0' class='percent_graph' cellpadding='0' width='100'>
182
182
  <tr>
183
- <td class='covered' width='9' />
184
- <td class='uncovered' width='91' />
183
+ <td class='covered' width='10' />
184
+ <td class='uncovered' width='90' />
185
185
  </tr>
186
186
  </table>
187
187
  </td>
@@ -192,12 +192,12 @@ table.report tr.dark {
192
192
  <table cellspacing='0' cellpadding='0' align='right'>
193
193
  <tr>
194
194
  <td>
195
- <tt class='coverage_code'>9.3%</tt>&nbsp;</td>
195
+ <tt class='coverage_code'>10.4%</tt>&nbsp;</td>
196
196
  <td>
197
197
  <table cellspacing='0' class='percent_graph' cellpadding='0' width='100'>
198
198
  <tr>
199
- <td class='covered' width='9' />
200
- <td class='uncovered' width='91' />
199
+ <td class='covered' width='10' />
200
+ <td class='uncovered' width='90' />
201
201
  </tr>
202
202
  </table>
203
203
  </td>
@@ -296,10 +296,10 @@ table.report tr.dark {
296
296
  <a href='lib-methodchain-not_included_rb.html'>lib/methodchain/not_included.rb</a>
297
297
  </td>
298
298
  <td class='lines_total'>
299
- <tt>58</tt>
299
+ <tt>67</tt>
300
300
  </td>
301
301
  <td class='lines_code'>
302
- <tt>39</tt>
302
+ <tt>47</tt>
303
303
  </td>
304
304
  <td>
305
305
  <table cellspacing='0' cellpadding='0' align='right'>
@@ -556,7 +556,7 @@ span.run100 {
556
556
  </head>
557
557
  <body>
558
558
  <h3>C0 code coverage information</h3>
559
- <p>Generated on Mon Mar 10 10:31:09 -0500 2008 with <a href='http://eigenclass.org/hiki.rb?rcov'>rcov 0.8.0</a>
559
+ <p>Generated on Thu Mar 13 11:28:30 -0500 2008 with <a href='http://eigenclass.org/hiki.rb?rcov'>rcov 0.8.0</a>
560
560
  </p>
561
561
  <hr /><pre><span class='marked0'>Code reported as executed by Ruby looks like this...
562
562
  </span><span class='marked1'>and this: this line is also marked as covered.
@@ -580,10 +580,10 @@ span.run100 {
580
580
  <a href='lib-methodchain-not_included_rb.html'>lib/methodchain/not_included.rb</a>
581
581
  </td>
582
582
  <td class='lines_total'>
583
- <tt>58</tt>
583
+ <tt>67</tt>
584
584
  </td>
585
585
  <td class='lines_code'>
586
- <tt>39</tt>
586
+ <tt>47</tt>
587
587
  </td>
588
588
  <td>
589
589
  <table cellspacing='0' cellpadding='0' align='right'>
@@ -622,61 +622,70 @@ span.run100 {
622
622
  </table><pre><span class="inferred1"><a name="line1" /> 1 # :main: README
623
623
  </span><span class="marked0"><a name="line2" /> 2 module MethodChain
624
624
  </span><span class="inferred1"><a name="line3" /> 3
625
- </span><span class="inferred0"><a name="line4" /> 4 # send a method, evaluate a block, but always return self
626
- </span><span class="marked1"><a name="line5" /> 5 def tap meth=nil, &amp;block
627
- </span><span class="marked0"><a name="line6" /> 6 __send__ meth if meth
628
- </span><span class="marked1"><a name="line7" /> 7 yield_or_eval &amp;block if block_given?
629
- </span><span class="marked0"><a name="line8" /> 8 self
630
- </span><span class="inferred1"><a name="line9" /> 9 end
631
- </span><span class="inferred0"><a name="line10" />10
632
- </span><span class="inferred1"><a name="line11" />11 # method chaining with a guard.
633
- </span><span class="inferred0"><a name="line12" />12 # If no guard block is given then guard against nil and false
634
- </span><span class="inferred1"><a name="line13" />13 # *methods = [method] where
635
- </span><span class="inferred0"><a name="line14" />14 # method = Message | Code
636
- </span><span class="inferred1"><a name="line15" />15 # Message = Symbol | [Symbol, *arguments]
637
- </span><span class="inferred0"><a name="line16" />16 # Code.to_proc = Proc
638
- </span><span class="marked1"><a name="line17" />17 def chain *methods, &amp;guard
639
- </span><span class="inferred0"><a name="line18" />18 return self if methods.empty? or not(
640
- </span><span class="marked1"><a name="line19" />19 (block_given? ? (yield_or_eval &amp;guard) : self))
641
- </span><span class="inferred0"><a name="line20" />20
642
- </span><span class="marked1"><a name="line21" />21 case(meth = methods.shift)
643
- </span><span class="marked0"><a name="line22" />22 when Symbol then __send__ meth
644
- </span><span class="marked1"><a name="line23" />23 when Array then __send__ *meth
645
- </span><span class="marked0"><a name="line24" />24 else yield_or_eval &amp;meth
646
- </span><span class="marked1"><a name="line25" />25 end.chain(*methods, &amp;guard)
647
- </span><span class="inferred0"><a name="line26" />26 end
648
- </span><span class="inferred1"><a name="line27" />27
649
- </span><span class="inferred0"><a name="line28" />28 # yield or eval based on the block arity
650
- </span><span class="marked1"><a name="line29" />29 def yield_or_eval &amp;block
651
- </span><span class="marked0"><a name="line30" />30 case block.arity
652
- </span><span class="inferred1"><a name="line31" />31 # ruby bug for -1
653
- </span><span class="marked0"><a name="line32" />32 when 0, -1 then instance_eval(&amp;block)
654
- </span><span class="marked1"><a name="line33" />33 when 1 then yield(self)
655
- </span><span class="marked0"><a name="line34" />34 else raise ArgumentError, &quot;too many arguments required by block&quot;
656
- </span><span class="inferred1"><a name="line35" />35 end
657
- </span><span class="inferred0"><a name="line36" />36 end
658
- </span><span class="inferred1"><a name="line37" />37
659
- </span><span class="inferred0"><a name="line38" />38 # return self if self evaluates to false, otherwise
660
- </span><span class="inferred1"><a name="line39" />39 # evaluate the block or return the default argument
661
- </span><span class="marked0"><a name="line40" />40 def then default=nil, &amp;block
662
- </span><span class="marked1"><a name="line41" />41 if self
663
- </span><span class="marked0"><a name="line42" />42 block_given? ? (yield_or_eval &amp;block) : (default || (fail \
664
- </span><span class="marked1"><a name="line43" />43 ArgumentError, &quot;#then must be called with an argument or a block&quot;))
665
- </span><span class="inferred0"><a name="line44" />44 else
666
- </span><span class="marked1"><a name="line45" />45 self
667
- </span><span class="inferred0"><a name="line46" />46 end
668
- </span><span class="inferred1"><a name="line47" />47 end
669
- </span><span class="inferred0"><a name="line48" />48
670
- </span><span class="inferred1"><a name="line49" />49 # the inverse of then
671
- </span><span class="marked0"><a name="line50" />50 def else arg=nil, &amp;block
672
- </span><span class="marked1"><a name="line51" />51 if self
673
- </span><span class="marked0"><a name="line52" />52 self
625
+ </span><span class="marked0"><a name="line4" /> 4 def tap meths=nil, &amp;block
626
+ </span><span class="marked1"><a name="line5" /> 5 send_arguments_as_functions *meths if meths
627
+ </span><span class="marked0"><a name="line6" /> 6 yield_or_eval(&amp;block) if block_given?
628
+ </span><span class="marked1"><a name="line7" /> 7 self
629
+ </span><span class="inferred0"><a name="line8" /> 8 end
630
+ </span><span class="inferred1"><a name="line9" /> 9
631
+ </span><span class="inferred0"><a name="line10" />10 # method chaining with a guard.
632
+ </span><span class="inferred1"><a name="line11" />11 # If no guard block is given then guard against nil and false
633
+ </span><span class="inferred0"><a name="line12" />12 # *methods = [method] where
634
+ </span><span class="inferred1"><a name="line13" />13 # method = Message | Code
635
+ </span><span class="inferred0"><a name="line14" />14 # Message = Symbol | [Symbol, *arguments]
636
+ </span><span class="inferred1"><a name="line15" />15 # Code.to_proc = Proc
637
+ </span><span class="marked0"><a name="line16" />16 def chain *meths, &amp;guard
638
+ </span><span class="inferred1"><a name="line17" />17 return self if meths.empty? or not(
639
+ </span><span class="marked0"><a name="line18" />18 (block_given? ? (yield_or_eval(&amp;guard)) : self))
640
+ </span><span class="inferred1"><a name="line19" />19
641
+ </span><span class="marked0"><a name="line20" />20 (send_as_function (meths.shift)).chain(*meths, &amp;guard)
642
+ </span><span class="inferred1"><a name="line21" />21 end
643
+ </span><span class="inferred0"><a name="line22" />22
644
+ </span><span class="marked1"><a name="line23" />23 def send_as_function meth
645
+ </span><span class="marked0"><a name="line24" />24 case meth
646
+ </span><span class="marked1"><a name="line25" />25 when Symbol then __send__ meth
647
+ </span><span class="marked0"><a name="line26" />26 when Array then __send__(*meth)
648
+ </span><span class="marked1"><a name="line27" />27 else yield_or_eval(&amp;meth)
649
+ </span><span class="inferred0"><a name="line28" />28 end
650
+ </span><span class="marked1"><a name="line29" />29 end
651
+ </span><span class="marked0"><a name="line30" />30 private :send_as_function
652
+ </span><span class="inferred1"><a name="line31" />31
653
+ </span><span class="marked0"><a name="line32" />32 def send_arguments_as_functions *methods
654
+ </span><span class="marked1"><a name="line33" />33 methods.each {|meth| send_as_function meth}
655
+ </span><span class="marked0"><a name="line34" />34 self
656
+ </span><span class="inferred1"><a name="line35" />35 end
657
+ </span><span class="inferred0"><a name="line36" />36
658
+ </span><span class="inferred1"><a name="line37" />37 # yield or eval based on the block arity
659
+ </span><span class="marked0"><a name="line38" />38 def yield_or_eval &amp;block
660
+ </span><span class="marked1"><a name="line39" />39 case block.arity
661
+ </span><span class="inferred0"><a name="line40" />40 # ruby bug for -1
662
+ </span><span class="marked1"><a name="line41" />41 when 0, -1 then instance_eval(&amp;block)
663
+ </span><span class="marked0"><a name="line42" />42 when 1 then yield(self)
664
+ </span><span class="marked1"><a name="line43" />43 else raise ArgumentError, &quot;too many arguments required by block&quot;
665
+ </span><span class="inferred0"><a name="line44" />44 end
666
+ </span><span class="inferred1"><a name="line45" />45 end
667
+ </span><span class="inferred0"><a name="line46" />46
668
+ </span><span class="inferred1"><a name="line47" />47 # return self if self evaluates to false, otherwise
669
+ </span><span class="inferred0"><a name="line48" />48 # evaluate the block or return the default argument
670
+ </span><span class="marked1"><a name="line49" />49 def then default=nil, &amp;block
671
+ </span><span class="marked0"><a name="line50" />50 if self
672
+ </span><span class="marked1"><a name="line51" />51 block_given? ? (yield_or_eval(&amp;block)) : (default || (fail \
673
+ </span><span class="marked0"><a name="line52" />52 ArgumentError, &quot;#then must be called with an argument or a block&quot;))
674
674
  </span><span class="inferred1"><a name="line53" />53 else
675
- </span><span class="marked0"><a name="line54" />54 block_given? ? (yield_or_eval &amp;block) : (arg || (fail \
676
- </span><span class="marked1"><a name="line55" />55 ArgumentError, &quot;#else must be called with an argument or a bloc&quot;))
677
- </span><span class="inferred0"><a name="line56" />56 end
678
- </span><span class="inferred1"><a name="line57" />57 end
679
- </span><span class="inferred0"><a name="line58" />58 end
675
+ </span><span class="marked0"><a name="line54" />54 self
676
+ </span><span class="inferred1"><a name="line55" />55 end
677
+ </span><span class="inferred0"><a name="line56" />56 end
678
+ </span><span class="inferred1"><a name="line57" />57
679
+ </span><span class="inferred0"><a name="line58" />58 # the inverse of then
680
+ </span><span class="marked1"><a name="line59" />59 def else arg=nil, &amp;block
681
+ </span><span class="marked0"><a name="line60" />60 if self
682
+ </span><span class="marked1"><a name="line61" />61 self
683
+ </span><span class="inferred0"><a name="line62" />62 else
684
+ </span><span class="marked1"><a name="line63" />63 block_given? ? (yield_or_eval(&amp;block)) : (arg || (fail \
685
+ </span><span class="marked0"><a name="line64" />64 ArgumentError, &quot;#else must be called with an argument or a bloc&quot;))
686
+ </span><span class="inferred1"><a name="line65" />65 end
687
+ </span><span class="inferred0"><a name="line66" />66 end
688
+ </span><span class="inferred1"><a name="line67" />67 end
680
689
  </span></pre><hr /> <p>Generated using the <a href='http://eigenclass.org/hiki.rb?rcov'>rcov code coverage analysis tool for Ruby</a> version 0.8.0.</p><p>
681
690
  <a href='http://validator.w3.org/check/referer'>
682
691
  <img src='http://www.w3.org/Icons/valid-xhtml10' height='31' alt='Valid XHTML 1.0!' width='88' />
@@ -556,7 +556,7 @@ span.run100 {
556
556
  </head>
557
557
  <body>
558
558
  <h3>C0 code coverage information</h3>
559
- <p>Generated on Mon Mar 10 10:31:09 -0500 2008 with <a href='http://eigenclass.org/hiki.rb?rcov'>rcov 0.8.0</a>
559
+ <p>Generated on Thu Mar 13 11:28:30 -0500 2008 with <a href='http://eigenclass.org/hiki.rb?rcov'>rcov 0.8.0</a>
560
560
  </p>
561
561
  <hr /><pre><span class='marked0'>Code reported as executed by Ruby looks like this...
562
562
  </span><span class='marked1'>and this: this line is also marked as covered.
data/doc/created.rid CHANGED
@@ -1 +1 @@
1
- Tue, 11 Mar 2008 13:49:16 -0500
1
+ Sun, 16 Mar 2008 10:24:28 -0500
@@ -20,7 +20,6 @@
20
20
  <div id="index">
21
21
  <h1 class="section-bar">Classes</h1>
22
22
  <div id="index-entries">
23
- <a href="classes/MethodChain.html">MethodChain</a><br />
24
23
  </div>
25
24
  </div>
26
25
  </body>
@@ -21,8 +21,6 @@
21
21
  <h1 class="section-bar">Files</h1>
22
22
  <div id="index-entries">
23
23
  <a href="files/README.html">README</a><br />
24
- <a href="files/lib/methodchain_rb.html">lib/methodchain.rb</a><br />
25
- <a href="files/lib/methodchain/not_included_rb.html">lib/methodchain/not_included.rb</a><br />
26
24
  </div>
27
25
  </div>
28
26
  </body>
@@ -20,11 +20,6 @@
20
20
  <div id="index">
21
21
  <h1 class="section-bar">Methods</h1>
22
22
  <div id="index-entries">
23
- <a href="classes/MethodChain.html#M000002">chain (MethodChain)</a><br />
24
- <a href="classes/MethodChain.html#M000005">else (MethodChain)</a><br />
25
- <a href="classes/MethodChain.html#M000001">tap (MethodChain)</a><br />
26
- <a href="classes/MethodChain.html#M000004">then (MethodChain)</a><br />
27
- <a href="classes/MethodChain.html#M000003">yield_or_eval (MethodChain)</a><br />
28
23
  </div>
29
24
  </div>
30
25
  </body>
data/lib/methodchain.rb CHANGED
@@ -1,4 +1,3 @@
1
- require File.dirname(__FILE__) + '/methodchain/not_included'
1
+ require File.dirname(__FILE__) + '/methodchain/not-included'
2
2
 
3
- class Object # :nodoc:
4
- include MethodChain end
3
+ class Object; include MethodChain end
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/../lib/methodchain'
2
2
 
3
3
  describe "#chain" do
4
- it "should return self when no arguments are given" do
4
+ it "should return self when no arguments or just a block are given" do
5
5
  [nil,'a'].each do |var|
6
6
  var.chain.should == var
7
7
  var.chain {fail}.should == var
@@ -17,6 +17,12 @@ describe "#chain" do
17
17
  it "should send an array as a message with arguments" do
18
18
  [['a']].chain(:flatten, lambda{|arr| arr.push('b')}, [:join, ' ']).should == 'a b'
19
19
  end
20
+ it "should yield self to a block and return self if block has one argument" do
21
+ [true,false,'a'].each do |o|
22
+ o.chain {|s| s.should == o }.should == o
23
+ o.chain {|s| 'foo' }.should == o
24
+ end
25
+ end
20
26
 
21
27
  it "should guard the chain against nil and false" do
22
28
  nil.chain(:foo,:bar,:baz).should == nil
@@ -39,13 +45,28 @@ describe "#chain" do
39
45
  end
40
46
 
41
47
  describe "#tap" do
42
- it "#tap should yield self to a block and return self if block has one argument" do
48
+ it "should return self when no arguments are given" do
49
+ [true,false,'a'].each do |o|
50
+ o.tap.should == o
51
+ end
52
+ end
53
+ it "should send symbols" do
54
+ [[]].tap(:flatten!).should == []
55
+ end
56
+ it "should send an array as a message with arguments" do
57
+ ['a','b'].tap( [:join, ' '] ).should == ['a','b']
58
+ end
59
+ it "should send procs" do
60
+ [].tap(lambda{|arr| arr.push('a'); 'blah'}).should == ['a']
61
+ [].tap(lambda{ push('a'); 'blah' }).should == ['a']
62
+ end
63
+ it "should yield self to a block and return self if block has one argument" do
43
64
  [true,false,'a'].each do |o|
44
65
  o.tap {|s| s.should == o }.should == o
45
66
  o.tap {|s| not s }.should == o
46
67
  end
47
68
  end
48
- it "#tap should raise an error if a block has more than one argument" do
69
+ it "should raise an error if a block has more than one argument" do
49
70
  [true,false,'a'].each do |o|
50
71
  lambda{ o.tap {|s,a|} }.should raise_error(ArgumentError)
51
72
  lambda{ o.tap {|s,*args|} }.should raise_error(ArgumentError)
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: methodchain
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.2.2
7
- date: 2008-03-11 00:00:00 -05:00
6
+ version: 0.3.0
7
+ date: 2008-03-16 00:00:00 -05:00
8
8
  summary: convenience methods for method chaining
9
9
  require_paths:
10
10
  - lib
@@ -31,11 +31,9 @@ authors:
31
31
  files:
32
32
  - ./doc
33
33
  - ./lib
34
- - ./pkg
35
34
  - ./spec
35
+ - ./Rakefile
36
36
  - ./README
37
- - ./rakefile
38
- - ./example.rb
39
37
  - ./coverage
40
38
  - doc/files
41
39
  - doc/index.html
@@ -47,12 +45,6 @@ files:
47
45
  - doc/classes
48
46
  - lib/methodchain
49
47
  - lib/methodchain.rb
50
- - pkg/methodchain-0.2.0.gem
51
- - pkg/methodchain-0.2.1.gem
52
- - pkg/methodchain-0.0.1.gem
53
- - pkg/methodchain-0.0.3.gem
54
- - pkg/methodchain-0.0.5.gem
55
- - pkg/methodchain-0.1.0.gem
56
48
  - spec/methodchain_spec.rb
57
49
  - coverage/lib-methodchain_rb.html
58
50
  - coverage/index.html
data/example.rb DELETED
@@ -1,90 +0,0 @@
1
- # :main: README
2
- module MethodChain
3
-
4
- # send a method, evaluate a block, but always return self
5
- def tap meth=nil, &block
6
- __send__ meth if meth
7
- yield_or_eval(&block) if block_given?
8
- self
9
- end
10
-
11
- # method chaining with a guard.
12
- # If no guard block is given then guard against nil and false
13
- # *methods = [method] where
14
- # method = Message | Code
15
- # Message = Symbol | [Symbol, *arguments]
16
- # Code.to_proc = Proc
17
- def chain *methods, &guard
18
- return self if methods.empty? or not(
19
- (block_given? ? (yield_or_eval(&guard)) : self))
20
-
21
- case(meth = methods.shift)
22
- when Symbol then __send__ meth
23
- when Array then __send__(*meth)
24
- else yield_or_eval(&meth)
25
- end.chain(*methods, &guard)
26
- end
27
-
28
- # yield or eval based on the block arity
29
- def yield_or_eval &block
30
- case block.arity
31
- # ruby bug for -1
32
- when 0, -1 then instance_eval(&block)
33
- when 1 then yield(self)
34
- else raise ArgumentError, "too many arguments required by block"
35
- end
36
- end
37
-
38
- # return self if self evaluates to false, otherwise
39
- # evaluate the block or return the default argument
40
- def then default=nil, &block
41
- if self
42
- block_given? ? (yield_or_eval(&block)) : (default || (fail \
43
- ArgumentError, "#then must be called with an argument or a block"))
44
- else
45
- self
46
- end
47
- end
48
-
49
- # the inverse of then
50
- def else arg=nil, &block
51
- if self
52
- self
53
- else
54
- block_given? ? (yield_or_eval(&block)) : (arg || (fail \
55
- ArgumentError, "#else must be called with an argument or a bloc"))
56
- end
57
- end
58
- end
59
- class Object; include MethodChain end
60
- arr = [1]
61
- arr.compact! # => nil
62
- arr.first # => 1
63
- [1].tap {|arr| arr.compact!}.first # => 1
64
- [1].tap(:compact!).first # => 1
65
- person = nil
66
- name = person ? person.name : nil
67
- name = person.then {|p| p.name}
68
- def find(*args)
69
- # do some expensive database queries
70
- end
71
- location = find(:first)
72
- @phone = location && location.phone # => nil
73
- @phone = find(:first).then {phone} # => nil
74
-
75
- 'a'.then('b') #=> 'b'
76
- nil.then('b').else('c') #=> 'c'
77
- customer = nil
78
- customer && customer.order && customer.order.id
79
- customer.chain(:order, :id)
80
- customer.then {order}.then {id}
81
- value = 0
82
- result = if value == 0 then value else
83
- tmp = value.abs
84
- if tmp == 0 then tmp else
85
- tmp * 20
86
- end
87
- end
88
- result # => 0
89
- value.chain(:abs, [:*, 20]) {|s| s == 0 } # => 0
90
- value.chain(:abs, lambda {|n| n * 20 }) {|s| s == 0 } # => 0
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file