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 +69 -23
- data/{rakefile → Rakefile} +9 -7
- data/coverage/-var-lib-gems-1_8-gems-rcov-0_8_0_2-lib-rcov_rb.html +1 -1
- data/coverage/index.html +11 -11
- data/coverage/lib-methodchain-not_included_rb.html +66 -57
- data/coverage/lib-methodchain_rb.html +1 -1
- data/doc/created.rid +1 -1
- data/doc/fr_class_index.html +0 -1
- data/doc/fr_file_index.html +0 -2
- data/doc/fr_method_index.html +0 -5
- data/lib/methodchain.rb +2 -3
- data/spec/methodchain_spec.rb +24 -3
- metadata +3 -11
- data/example.rb +0 -90
- data/pkg/methodchain-0.0.1.gem +0 -0
- data/pkg/methodchain-0.0.3.gem +0 -0
- data/pkg/methodchain-0.0.5.gem +0 -0
- data/pkg/methodchain-0.1.0.gem +0 -0
- data/pkg/methodchain-0.2.0.gem +0 -0
- data/pkg/methodchain-0.2.1.gem +0 -0
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
|
-
|
40
|
-
@phone =
|
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
|
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
|
-
|
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/
|
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
|
-
|
98
|
-
|
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
|
data/{rakefile → Rakefile}
RENAMED
@@ -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','
|
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 = "#{
|
102
|
+
example_file = "#{Dir.pwd}/example.rb"
|
103
103
|
|
104
104
|
File.write(example_file, (
|
105
|
-
File.read("#{__DIR__}/lib/methodchain/
|
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.
|
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 =
|
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
|
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
|
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>
|
170
|
+
<tt>1047</tt>
|
171
171
|
</td>
|
172
172
|
<td class='lines_code'>
|
173
|
-
<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.
|
179
|
+
<tt class='coverage_total'>9.9%</tt> </td>
|
180
180
|
<td>
|
181
181
|
<table cellspacing='0' class='percent_graph' cellpadding='0' width='100'>
|
182
182
|
<tr>
|
183
|
-
<td class='covered' width='
|
184
|
-
<td class='uncovered' width='
|
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'>
|
195
|
+
<tt class='coverage_code'>10.4%</tt> </td>
|
196
196
|
<td>
|
197
197
|
<table cellspacing='0' class='percent_graph' cellpadding='0' width='100'>
|
198
198
|
<tr>
|
199
|
-
<td class='covered' width='
|
200
|
-
<td class='uncovered' width='
|
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>
|
299
|
+
<tt>67</tt>
|
300
300
|
</td>
|
301
301
|
<td class='lines_code'>
|
302
|
-
<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
|
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>
|
583
|
+
<tt>67</tt>
|
584
584
|
</td>
|
585
585
|
<td class='lines_code'>
|
586
|
-
<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="
|
626
|
-
</span><span class="marked1"><a name="line5" /> 5
|
627
|
-
</span><span class="marked0"><a name="line6" /> 6
|
628
|
-
</span><span class="marked1"><a name="line7" /> 7
|
629
|
-
</span><span class="
|
630
|
-
</span><span class="inferred1"><a name="line9" /> 9
|
631
|
-
</span><span class="inferred0"><a name="line10" />10
|
632
|
-
</span><span class="inferred1"><a name="line11" />11 #
|
633
|
-
</span><span class="inferred0"><a name="line12" />12 #
|
634
|
-
</span><span class="inferred1"><a name="line13" />13 #
|
635
|
-
</span><span class="inferred0"><a name="line14" />14 #
|
636
|
-
</span><span class="inferred1"><a name="line15" />15 #
|
637
|
-
</span><span class="
|
638
|
-
</span><span class="
|
639
|
-
</span><span class="
|
640
|
-
</span><span class="
|
641
|
-
</span><span class="
|
642
|
-
</span><span class="
|
643
|
-
</span><span class="
|
644
|
-
</span><span class="marked1"><a name="line23" />23
|
645
|
-
</span><span class="marked0"><a name="line24" />24
|
646
|
-
</span><span class="marked1"><a name="line25" />25
|
647
|
-
</span><span class="
|
648
|
-
</span><span class="
|
649
|
-
</span><span class="inferred0"><a name="line28" />28
|
650
|
-
</span><span class="marked1"><a name="line29" />29
|
651
|
-
</span><span class="marked0"><a name="line30" />30
|
652
|
-
</span><span class="inferred1"><a name="line31" />31
|
653
|
-
</span><span class="marked0"><a name="line32" />32
|
654
|
-
</span><span class="marked1"><a name="line33" />33
|
655
|
-
</span><span class="marked0"><a name="line34" />34
|
656
|
-
</span><span class="inferred1"><a name="line35" />35
|
657
|
-
</span><span class="inferred0"><a name="line36" />36
|
658
|
-
</span><span class="inferred1"><a name="line37" />37
|
659
|
-
</span><span class="
|
660
|
-
</span><span class="
|
661
|
-
</span><span class="
|
662
|
-
</span><span class="marked1"><a name="line41" />41
|
663
|
-
</span><span class="marked0"><a name="line42" />42
|
664
|
-
</span><span class="marked1"><a name="line43" />43
|
665
|
-
</span><span class="inferred0"><a name="line44" />44
|
666
|
-
</span><span class="
|
667
|
-
</span><span class="inferred0"><a name="line46" />46
|
668
|
-
</span><span class="inferred1"><a name="line47" />47
|
669
|
-
</span><span class="inferred0"><a name="line48" />48
|
670
|
-
</span><span class="
|
671
|
-
</span><span class="marked0"><a name="line50" />50
|
672
|
-
</span><span class="marked1"><a name="line51" />51
|
673
|
-
</span><span class="marked0"><a name="line52" />52
|
625
|
+
</span><span class="marked0"><a name="line4" /> 4 def tap meths=nil, &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(&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, &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(&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, &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(&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 &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(&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, "too many arguments required by block"
|
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, &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(&block)) : (default || (fail \
|
673
|
+
</span><span class="marked0"><a name="line52" />52 ArgumentError, "#then must be called with an argument or a block"))
|
674
674
|
</span><span class="inferred1"><a name="line53" />53 else
|
675
|
-
</span><span class="marked0"><a name="line54" />54
|
676
|
-
</span><span class="
|
677
|
-
</span><span class="inferred0"><a name="line56" />56
|
678
|
-
</span><span class="inferred1"><a name="line57" />57
|
679
|
-
</span><span class="inferred0"><a name="line58" />58
|
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, &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(&block)) : (arg || (fail \
|
685
|
+
</span><span class="marked0"><a name="line64" />64 ArgumentError, "#else must be called with an argument or a bloc"))
|
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
|
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
|
-
|
1
|
+
Sun, 16 Mar 2008 10:24:28 -0500
|
data/doc/fr_class_index.html
CHANGED
data/doc/fr_file_index.html
CHANGED
@@ -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>
|
data/doc/fr_method_index.html
CHANGED
@@ -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
data/spec/methodchain_spec.rb
CHANGED
@@ -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 "
|
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 "
|
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.
|
7
|
-
date: 2008-03-
|
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
|
data/pkg/methodchain-0.0.1.gem
DELETED
Binary file
|
data/pkg/methodchain-0.0.3.gem
DELETED
Binary file
|
data/pkg/methodchain-0.0.5.gem
DELETED
Binary file
|
data/pkg/methodchain-0.1.0.gem
DELETED
Binary file
|
data/pkg/methodchain-0.2.0.gem
DELETED
Binary file
|
data/pkg/methodchain-0.2.1.gem
DELETED
Binary file
|