case 0.5 → 0.5.1

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.
Files changed (3) hide show
  1. data/README.rdoc +241 -0
  2. data/Rakefile +4 -3
  3. metadata +7 -4
@@ -0,0 +1,241 @@
1
+ = case
2
+
3
+ The case gem is a power-up for Ruby's case-matching.
4
+
5
+ == Structs
6
+
7
+ <code>Case::Struct</code> is a subclass of Ruby's standard <code>Struct</code>
8
+ class that supports structural matching. When two instances of a normal Ruby
9
+ <code>Struct</code> are matched, their fields are compared using the normal
10
+ equality test. <code>Case::Struct</code> uses the case-matching
11
+ <code>===</code> operator instead.
12
+
13
+ Here's an example of some of the things which are possible:
14
+
15
+ require 'case'
16
+
17
+ Foo = Case::Struct.new :foo
18
+
19
+ [Foo["blah"], Foo["hoge"], Foo[3], Foo["testing"]].each do |value|
20
+ case value
21
+ when Foo["testing"]
22
+ puts "matched testing"
23
+ when Foo["blah"]
24
+ puts "matched blah"
25
+ when Foo[String]
26
+ puts "matched string #{value.foo}"
27
+ else
28
+ puts "fell through"
29
+ end
30
+ end
31
+
32
+ This will print:
33
+
34
+ matched blah
35
+ matched string hoge
36
+ fell through
37
+ matched testing
38
+
39
+ == Wildcards
40
+
41
+ The case gem also supports wildcards. For example:
42
+
43
+ require 'case'
44
+
45
+ Foo = Case::Struct :name, :arg
46
+
47
+ [Foo["blah", 9], Foo["meat", 5], Foo["blah", 23]].each do |value|
48
+ case value
49
+ when Foo["blah", Case::Any]
50
+ puts "blah: #{value.arg}"
51
+ end
52
+ end
53
+
54
+ This will print:
55
+
56
+ blah: 9
57
+ blah: 23
58
+
59
+ <code>Case::Any</code> can also be used directly, though there's seldom
60
+ reason to do so instead of using an <code>else</code> clause.
61
+
62
+ case thing
63
+ when "foo"
64
+ # specific case
65
+ when Case::Any
66
+ # fall-through
67
+ end
68
+
69
+ case thing
70
+ when "foo"
71
+ # specific case
72
+ else
73
+ # fall-through
74
+ end
75
+
76
+ == Conjunction
77
+
78
+ Case also supports simultaneously testing several cases in a single when:
79
+
80
+ [4.5, 3, 3.0].each do |value|
81
+ case value
82
+ when Case::All[Float, 3]
83
+ puts "float 3"
84
+ when 3
85
+ puts "generic 3"
86
+ when Float
87
+ puts "generic float"
88
+ end
89
+ end
90
+
91
+ This prints:
92
+
93
+ generic float
94
+ generic 3
95
+ float 3
96
+
97
+ == Disjunction
98
+
99
+ It's also possible to match one of several alternatives, if you pass
100
+ arguments to <code>Case::Any</code>:
101
+
102
+ require 'rational'
103
+ require 'case'
104
+
105
+ [3, Rational(3, 1), 6.0, 3.0].each do |value|
106
+ case value
107
+ when Case::All[Case::Any[Float, Rational], 3]
108
+ puts "matched #{value.inspect}"
109
+ end
110
+ end
111
+
112
+ Which prints:
113
+
114
+ matched Rational(3, 1)
115
+ matched 3.0
116
+
117
+ Once again, <code>Case::Any</code> can be used on its own, though usually
118
+ there's not much point.
119
+
120
+ case thing
121
+ when Case::Any["foo", "bar"]
122
+ # either of these
123
+ end
124
+
125
+ case thing
126
+ when "foo", "bar"
127
+ # either of these
128
+ end
129
+
130
+ (Note that <code>Case::Any[]</code> with no arguments matches nothing; it
131
+ is different from <code>Case::Any</code> without braces.)
132
+
133
+ == Comparisons
134
+
135
+ <code>Case::Cmp</code> can be used to perform comparisons as part of
136
+ case-matching:
137
+
138
+ require 'case'
139
+
140
+ [0..5].each do |value|
141
+ case value
142
+ when 0, 1
143
+ puts "0 or 1"
144
+ when Case::Cmp < 4
145
+ puts "less than 4"
146
+ else
147
+ puts "fell through"
148
+ end
149
+ end
150
+
151
+ This prints:
152
+
153
+ 0 or 1
154
+ 0 or 1
155
+ less than 4
156
+ less than 4
157
+ fell through
158
+ fell through
159
+
160
+ The <, >, >= and <= operators are all supported.
161
+
162
+ == Guards
163
+
164
+ More general tests can be put in when statements using <code>Case::Guard</code>.
165
+
166
+ require 'case'
167
+
168
+ ["foobar", "beef", "lorem"].each do |value|
169
+ case value
170
+ when Case::Guard.new { |v| v[1, 1] == "o" }
171
+ puts "second letter in #{value} is o"
172
+ else
173
+ puts "just got #{value}"
174
+ end
175
+ end
176
+
177
+ This will print:
178
+
179
+ second letter in foobar is o
180
+ just got beef
181
+ second letter in lorem is o
182
+
183
+ (Yes, I realize a regular expression could be used for this purpose.)
184
+
185
+ In simple cases, when <code>Case::Guard</code> is being used directly, you
186
+ don't even need to bother with the block parameter:
187
+
188
+ ["foobar", "beef", "lorem"].each do |value|
189
+ case value
190
+ when Case::Guard.new { value[1, 1] == "o" }
191
+ puts "second letter in #{value} is o"
192
+ else
193
+ puts "just got #{value}"
194
+ end
195
+ end
196
+
197
+ (The parameter is really only there for when <code>Case::Guard</code> is
198
+ being used as part of a larger expression.)
199
+
200
+ == Negation
201
+
202
+ <code>Case::Not</code> inverts the normal matching. For example:
203
+
204
+ [1, "foobar", :blah].each do |value|
205
+ case value
206
+ when Case::Not[String]
207
+ puts value.inspect
208
+ end
209
+ end
210
+
211
+ This will print:
212
+
213
+ 1
214
+ :blah
215
+
216
+ == Arrays
217
+
218
+ <code>Case::Array</code> is a subclass of <code>Array</code> which can
219
+ be used as a pattern to do positional matching in arrays:
220
+
221
+ require 'case'
222
+
223
+ [["foo", 2], ["bar", 3, 4], ["bar", 9]].each do |value|
224
+ case value
225
+ when Case::Array["foo", Case::Any]
226
+ puts "Foo #{value[1]}"
227
+ when Case::Array["bar", Case::Any]
228
+ puts "Bar #{value[1]}"
229
+ end
230
+ end
231
+
232
+ This will print:
233
+
234
+ Foo 2
235
+ Bar 9
236
+
237
+ Note that <code>Case::Array</code> only matches arrays of the same
238
+ length.
239
+
240
+ <code>Case::Array</code> should only be used as a pattern; there's no
241
+ need to use it in lieu of <code>Array</code> for your actual data.
data/Rakefile CHANGED
@@ -4,10 +4,11 @@ require 'rake/rdoctask'
4
4
  require 'rake/gempackagetask'
5
5
  require 'rake/clean'
6
6
 
7
- GEM_VERSION = "0.5"
7
+ GEM_VERSION = "0.5.1"
8
8
 
9
9
  Rake::RDocTask.new do |task|
10
- task.rdoc_files.add [ 'lib/**/*.rb' ]
10
+ task.rdoc_files.add [ 'lib/**/*.rb', 'README.rdoc' ]
11
+ task.main = 'README.rdoc'
11
12
  end
12
13
 
13
14
  task :clobber => [ :clean ]
@@ -27,7 +28,7 @@ gemspec = Gem::Specification.new do |gemspec|
27
28
  gemspec.author = "MenTaLguY <mental@rydia.net>"
28
29
  gemspec.summary = "Pattern matching for Ruby"
29
30
  gemspec.test_file = 'test/test_all.rb'
30
- gemspec.files = FileList[ 'Rakefile', 'test/*.rb', 'lib/**/*.rb' ]
31
+ gemspec.files = FileList[ 'Rakefile', 'README.rdoc', 'test/*.rb', 'lib/**/*.rb' ]
31
32
  gemspec.require_paths = [ 'lib' ]
32
33
  gemspec.has_rdoc = true
33
34
  gemspec.platform = Gem::Platform::RUBY
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: case
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.5"
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - MenTaLguY <mental@rydia.net>
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-08-13 00:00:00 -04:00
12
+ date: 2010-12-09 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -23,12 +23,15 @@ extra_rdoc_files: []
23
23
 
24
24
  files:
25
25
  - Rakefile
26
+ - README.rdoc
26
27
  - test/test_case.rb
27
28
  - test/test_all.rb
28
29
  - lib/case.rb
29
30
  - lib/case/core.rb
30
31
  has_rdoc: true
31
32
  homepage:
33
+ licenses: []
34
+
32
35
  post_install_message:
33
36
  rdoc_options: []
34
37
 
@@ -49,9 +52,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
49
52
  requirements: []
50
53
 
51
54
  rubyforge_project: concurrent
52
- rubygems_version: 1.1.1
55
+ rubygems_version: 1.3.5
53
56
  signing_key:
54
- specification_version: 2
57
+ specification_version: 3
55
58
  summary: Pattern matching for Ruby
56
59
  test_files:
57
60
  - test/test_all.rb