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