multi_case 0.0.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.
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +2 -0
- data/LICENSE +20 -0
- data/README.md +131 -0
- data/Rakefile +30 -0
- data/lib/multi_case.rb +10 -0
- data/lib/multi_case/api.rb +20 -0
- data/lib/multi_case/core_ext.rb +15 -0
- data/lib/multi_case/dsl.rb +45 -0
- data/multi_case.gemspec +25 -0
- data/spec/multi_case/api_spec.rb +104 -0
- data/spec/multi_case/core_ext_spec.rb +32 -0
- data/spec/spec_helper.rb +2 -0
- data/travis.yml +4 -0
- metadata +113 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2013 Andrey Korzhuev <andrew@korzhuev.com>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included
|
12
|
+
in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
17
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
18
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
19
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
20
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
multi_case [](https://travis-ci.org/andrusha/multi_case) [](https://gemnasium.com/andrusha/multi_case) [](https://codeclimate.com/github/andrusha/multi_case)
|
2
|
+
==========
|
3
|
+
|
4
|
+
An improved `case` operator for ruby which allows you to make a choice based on how variable changes (a state machine of ifs).
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------
|
8
|
+
|
9
|
+
`gem install multi_case`
|
10
|
+
|
11
|
+
Usage
|
12
|
+
-----
|
13
|
+
|
14
|
+
### Interfaces
|
15
|
+
|
16
|
+
There are two interfaces available, one is an unobtrusive module, which can be
|
17
|
+
included into your class like so:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
require 'multi_case'
|
21
|
+
|
22
|
+
class Cookie
|
23
|
+
include MultiCase::API
|
24
|
+
|
25
|
+
def eat_it!
|
26
|
+
mutli_case weight_was, weight do
|
27
|
+
multi(150 => 0..50) { puts "That was a good bite!" }
|
28
|
+
multi(150 => 150..(+1.0/0.0)) { puts "Are you puked?!" }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
```
|
33
|
+
|
34
|
+
Another one is to extend your `Kernel` making `multi_case` function global:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
require 'multi_case/core_ext'
|
38
|
+
|
39
|
+
mutli_case ENV['petals_was'], ENV['petal'] do
|
40
|
+
multi([] => (0..100).step(2)) { puts "Любит" }
|
41
|
+
multi([] => (1..100).step(2)) { puts "Не любит" }
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
### Features
|
46
|
+
|
47
|
+
Most common use-case is to make a decision based on how your variable changes,
|
48
|
+
it also might be used as an unbotrusive state-machine implementation. For
|
49
|
+
example, if you have a post and its state went from `:draft` to `:published`
|
50
|
+
you might want to notify all your subscribed users about that, which can be
|
51
|
+
implemented like so:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
class Post
|
55
|
+
def notify
|
56
|
+
multi_case status_was, status do
|
57
|
+
multi([] => :draft) { Notification.needs_input(post).to_editors }
|
58
|
+
multi(:draft => :published) { Notification.new_post(post).to_subscribers }
|
59
|
+
multi([] => :destroyed) { Notification.destoyed_post(post).to_admins }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
It also returns values so it can be used to replace nested `case` statements:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
beer_status = multi_case bottles_was, bottles do
|
69
|
+
multi(0 => 1..10) { :party_time }
|
70
|
+
multi(1..10 => 0) { :needs_refil }
|
71
|
+
end
|
72
|
+
```
|
73
|
+
|
74
|
+
Since it uses case-matching (`===`) internally you can use all its goodiness:
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
multi_case x, y do
|
78
|
+
multi(String => /a+/i) { 0 }
|
79
|
+
multi(1..100 => [:x, :y, :z]) { 0 }
|
80
|
+
end
|
81
|
+
```
|
82
|
+
|
83
|
+
### Syntax
|
84
|
+
|
85
|
+
`multi_case` expect two values and block which contains matchers, first value
|
86
|
+
is matched against key of one-elemnt hash which is provided to `multi`,
|
87
|
+
second value is matched against value of said hash.
|
88
|
+
|
89
|
+
`multi` expect you to provide one-elemnt hash and block, if hash has array in it
|
90
|
+
then all array elements are matched against value sequentially and empty array
|
91
|
+
means "match-all". The block provided to multi is executed in case of correct
|
92
|
+
match and its result is what is returned by `multi_case`.
|
93
|
+
|
94
|
+
### Implementation
|
95
|
+
|
96
|
+
The `mutli_case` statement is complete equivalent of nested `case` statements,
|
97
|
+
so these two snippets are intedent to work exactly the same:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
result = multi_case old_value, new_value do
|
101
|
+
multi [:a, :b] => [:c, :d] { :e }
|
102
|
+
multi [:f, :g] => [:h, :i] { :j }
|
103
|
+
multi [] => [:k, :l] { :m }
|
104
|
+
multi [:n, :o] => [] { :p }
|
105
|
+
multi [:f, :g] => [:q, :r] { :s }
|
106
|
+
end
|
107
|
+
```
|
108
|
+
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
result = case old_value
|
112
|
+
when :a, :b
|
113
|
+
case new_value
|
114
|
+
when :c, :d then :e
|
115
|
+
end
|
116
|
+
when :f, :g
|
117
|
+
case new_value
|
118
|
+
when :h, :i then :j
|
119
|
+
when :q, :r then :s
|
120
|
+
end
|
121
|
+
when :n, :o then :p
|
122
|
+
else
|
123
|
+
case new_value
|
124
|
+
when :k, :l then :m
|
125
|
+
end
|
126
|
+
end
|
127
|
+
```
|
128
|
+
|
129
|
+
Copyright
|
130
|
+
=========
|
131
|
+
Copytright © 2013 Andrey Korzhuev. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
|
+
|
7
|
+
task :test => ["rspec"]
|
8
|
+
|
9
|
+
require "multi_case"
|
10
|
+
|
11
|
+
PACKAGE = "#{MultiCase::PACKAGE}"
|
12
|
+
VERSION = "#{MultiCase::VERSION}"
|
13
|
+
|
14
|
+
task :package do
|
15
|
+
system "gem build #{PACKAGE}.gemspec"
|
16
|
+
end
|
17
|
+
|
18
|
+
task :install => :package do
|
19
|
+
Dir.chdir("pkg") do
|
20
|
+
system "gem install #{PACKAGE}-#{VERSION}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
task :release => :package do
|
25
|
+
Dir.chdir("pkg") do
|
26
|
+
system "gem push #{PACKAGE}-#{VERSION}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
task :default => :test
|
data/lib/multi_case.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'multi_case/dsl'
|
2
|
+
|
3
|
+
module MultiCase::API
|
4
|
+
protected
|
5
|
+
|
6
|
+
#
|
7
|
+
# Matches two parameters agains specified causes returning the result
|
8
|
+
# of user specified functions
|
9
|
+
# @param lhs [#===] Matched against left-hand side
|
10
|
+
# @param rhs [#===] Matches against right-hand side
|
11
|
+
# @param &block [Object] A function which contains number of `multi` clauses
|
12
|
+
#
|
13
|
+
# @return [Object] Value returned by first matching matching specified by user
|
14
|
+
def multi_case(lhs, rhs, &block)
|
15
|
+
dsl = MultiCase::DSL.new(lhs, rhs)
|
16
|
+
dsl.instance_eval(&block)
|
17
|
+
|
18
|
+
dsl.result
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'multi_case'
|
2
|
+
|
3
|
+
#
|
4
|
+
# Makes multi_case a global method available at main:Object
|
5
|
+
# as well as inside any other class. BEWARE, this might make
|
6
|
+
# some modules behave unexpectedly because of name collision.
|
7
|
+
#
|
8
|
+
module Kernel
|
9
|
+
include MultiCase::API
|
10
|
+
alias_method :_multi_case, :multi_case
|
11
|
+
|
12
|
+
def multi_case(x, y, &block)
|
13
|
+
_multi_case(x, y, &block)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class MultiCase::DSL
|
2
|
+
#
|
3
|
+
# @param lhs [#===]
|
4
|
+
# @param rhs [#===]
|
5
|
+
#
|
6
|
+
def initialize(lhs, rhs)
|
7
|
+
@lhs = lhs
|
8
|
+
@rhs = rhs
|
9
|
+
|
10
|
+
@result = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :result
|
14
|
+
|
15
|
+
#
|
16
|
+
# A single case to which @lhs & @rhs are matched against
|
17
|
+
# @param from_to [Hash] @lhs is matched against keys, @rhs against values,
|
18
|
+
# they both can be arrays
|
19
|
+
# @param &block [Object] User-specified result if both of parameters match
|
20
|
+
#
|
21
|
+
# @return [Object] Return-value of user-specified function
|
22
|
+
def multi(from_to, &block)
|
23
|
+
from = from_to.keys.flatten(1)
|
24
|
+
from = [@lhs] if from.empty? # catch-all on empty array
|
25
|
+
|
26
|
+
to = from_to.values.flatten(1)
|
27
|
+
to = [@rhs] if to.empty?
|
28
|
+
|
29
|
+
if from.product(to).map(&method(:param_equal)).any?
|
30
|
+
@result ||= block.call
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
#
|
37
|
+
# Case-compares tuple against @lhs and @rhs
|
38
|
+
# @param arr [Array] Tuple to match against
|
39
|
+
#
|
40
|
+
# @return [Boolean]
|
41
|
+
def param_equal(arr)
|
42
|
+
f, t = arr
|
43
|
+
(f === @lhs) && (t === @rhs)
|
44
|
+
end
|
45
|
+
end
|
data/multi_case.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "multi_case"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = MultiCase::PACKAGE
|
7
|
+
s.version = MultiCase::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Andrey Korzhuev"]
|
10
|
+
s.email = ["andrew@korzhuev.com"]
|
11
|
+
s.homepage = "https://github.com/andrusha/multi_case"
|
12
|
+
s.summary = %q{Multi-parameter case statement}
|
13
|
+
s.description = %q{A state-machine inspired case/if statement}
|
14
|
+
|
15
|
+
s.rubyforge_project = "multi_case"
|
16
|
+
|
17
|
+
s.files = `git ls-files -z`.split("\0")
|
18
|
+
s.test_files = `git ls-files -z -- {fixtures,features,spec}/*`.split("\0")
|
19
|
+
s.extra_rdoc_files = ["LICENSE", "README.md"]
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_development_dependency "rake"
|
23
|
+
s.add_development_dependency "rspec"
|
24
|
+
s.add_development_dependency "simplecov"
|
25
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MultiCase::API do
|
4
|
+
include MultiCase::API
|
5
|
+
|
6
|
+
describe "simple matching" do
|
7
|
+
it "matches two argument against pre-defined cases returning specified value" do
|
8
|
+
result = multi_case :a, :c do
|
9
|
+
multi(:a => :b) { 1 }
|
10
|
+
multi(:a => :c) { 2 }
|
11
|
+
end
|
12
|
+
|
13
|
+
result.should == 2
|
14
|
+
end
|
15
|
+
|
16
|
+
it "return nil if no matches found" do
|
17
|
+
result = multi_case :x, :y do
|
18
|
+
multi(:a => :b) { 1 }
|
19
|
+
multi(:a => :c) { 2 }
|
20
|
+
end
|
21
|
+
|
22
|
+
result.should be_nil
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns first match if we have multiple matches" do
|
26
|
+
result = multi_case :x, :y do
|
27
|
+
multi(:a => :b) { 1 }
|
28
|
+
multi(:x => :y) { 2 }
|
29
|
+
multi(:x => [:y, :z]) { 3 }
|
30
|
+
end
|
31
|
+
|
32
|
+
result.should == 2
|
33
|
+
end
|
34
|
+
|
35
|
+
it "doesn't execute unmatched functions" do
|
36
|
+
expect do
|
37
|
+
result = multi_case :a, :c do
|
38
|
+
multi(:a => :b) { raise "oh shit" }
|
39
|
+
multi(:a => :c) { 2 }
|
40
|
+
multi(:a => :c) { raise "oh shittiest" }
|
41
|
+
end
|
42
|
+
end.not_to raise_error
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "case matching" do
|
47
|
+
it "classes" do
|
48
|
+
result = multi_case 'aaa', :y do
|
49
|
+
multi(:a => :b) { 1 }
|
50
|
+
multi(String => :y) { 2 }
|
51
|
+
end
|
52
|
+
|
53
|
+
result.should == 2
|
54
|
+
end
|
55
|
+
|
56
|
+
it "regexps" do
|
57
|
+
result = multi_case 'aaa', :y do
|
58
|
+
multi(:a => :b) { 1 }
|
59
|
+
multi(/A+/i => :y) { 2 }
|
60
|
+
end
|
61
|
+
|
62
|
+
result.should == 2
|
63
|
+
end
|
64
|
+
|
65
|
+
it "ranges" do
|
66
|
+
result = multi_case 'aaa', 100 do
|
67
|
+
multi(:a => :b) { 1 }
|
68
|
+
multi('aaa' => :c) { 2 }
|
69
|
+
multi('aaa' => [:c, 99..120]) { 3 }
|
70
|
+
end
|
71
|
+
|
72
|
+
result.should == 3
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "array matching" do
|
77
|
+
it "allow arbitrary input" do
|
78
|
+
result = multi_case :a, :c do
|
79
|
+
multi([:c, :a] => [:b, :d]) { 1 }
|
80
|
+
multi([:c, :d] => [:c, :e]) { 2 }
|
81
|
+
multi([:c, :a] => [:c, :e]) { 3 }
|
82
|
+
end
|
83
|
+
|
84
|
+
result.should == 3
|
85
|
+
end
|
86
|
+
|
87
|
+
it "treat empty arrays as catch-all" do
|
88
|
+
result = multi_case :a, :c do
|
89
|
+
multi([] => [:c]) { 1 }
|
90
|
+
end
|
91
|
+
|
92
|
+
result.should == 1
|
93
|
+
end
|
94
|
+
|
95
|
+
it "can match nested arrays" do
|
96
|
+
result = multi_case [:a, :b], :c do
|
97
|
+
multi([[:a, :b]] => [:c]) { 1 }
|
98
|
+
end
|
99
|
+
|
100
|
+
result.should == 1
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'multi_case/core_ext'
|
3
|
+
|
4
|
+
def f
|
5
|
+
multi_case :a, :b do
|
6
|
+
multi(:a => :b) { 1 }
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "core extensions" do
|
11
|
+
it "makes multi_case global function" do
|
12
|
+
value = multi_case :a, :b do
|
13
|
+
multi(:a => :b) { 1 }
|
14
|
+
end
|
15
|
+
|
16
|
+
value.should == 1
|
17
|
+
end
|
18
|
+
|
19
|
+
it "allow you to call it from inside arbitrary function" do
|
20
|
+
f.should == 1
|
21
|
+
end
|
22
|
+
|
23
|
+
it "is accessible from inside another class" do
|
24
|
+
Class.new do
|
25
|
+
def f
|
26
|
+
multi_case :a, :b do
|
27
|
+
multi(:a => :b) { 1 }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end.new.f.should == 1
|
31
|
+
end
|
32
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/travis.yml
ADDED
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: multi_case
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Andrey Korzhuev
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-12 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: simplecov
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: A state-machine inspired case/if statement
|
63
|
+
email:
|
64
|
+
- andrew@korzhuev.com
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files:
|
68
|
+
- LICENSE
|
69
|
+
- README.md
|
70
|
+
files:
|
71
|
+
- .gitignore
|
72
|
+
- .rspec
|
73
|
+
- Gemfile
|
74
|
+
- LICENSE
|
75
|
+
- README.md
|
76
|
+
- Rakefile
|
77
|
+
- lib/multi_case.rb
|
78
|
+
- lib/multi_case/api.rb
|
79
|
+
- lib/multi_case/core_ext.rb
|
80
|
+
- lib/multi_case/dsl.rb
|
81
|
+
- multi_case.gemspec
|
82
|
+
- spec/multi_case/api_spec.rb
|
83
|
+
- spec/multi_case/core_ext_spec.rb
|
84
|
+
- spec/spec_helper.rb
|
85
|
+
- travis.yml
|
86
|
+
homepage: https://github.com/andrusha/multi_case
|
87
|
+
licenses: []
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
requirements: []
|
105
|
+
rubyforge_project: multi_case
|
106
|
+
rubygems_version: 1.8.23
|
107
|
+
signing_key:
|
108
|
+
specification_version: 3
|
109
|
+
summary: Multi-parameter case statement
|
110
|
+
test_files:
|
111
|
+
- spec/multi_case/api_spec.rb
|
112
|
+
- spec/multi_case/core_ext_spec.rb
|
113
|
+
- spec/spec_helper.rb
|