methodchain 0.2.2 → 0.3.0

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 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