mallow 0.0.2 → 0.0.4
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.md +8 -8
- data/lib/mallow/basic_dsl.rb +50 -0
- data/lib/mallow/dsl.rb +30 -92
- data/lib/mallow/monads.rb +2 -6
- data/lib/mallow/version.rb +1 -2
- data/lib/mallow.rb +7 -31
- data/mallow.gemspec +2 -2
- data/test/case/control.rb +44 -0
- data/test/unit/meta.rb +11 -0
- data/test/unit/{monad.rb → monad_laws.rb} +2 -2
- data/test/unit/rule.rb +52 -0
- metadata +13 -8
- data/test/case/mallow.rb +0 -38
data/README.md
CHANGED
@@ -6,10 +6,10 @@ An example of Mallow's versatility is Graham, a tiny testing library powered by
|
|
6
6
|
|
7
7
|
## Papa teach me to mallow ##
|
8
8
|
|
9
|
-
To mallow is very
|
9
|
+
To mallow it is very easy little boy. First marshal, then mallow:
|
10
10
|
|
11
11
|
```ruby
|
12
|
-
mallow = Mallow
|
12
|
+
mallow = Mallow.build do |match|
|
13
13
|
match.a_hash.to {"#{keys.first} #{values.first}"}
|
14
14
|
end
|
15
15
|
```
|
@@ -20,7 +20,7 @@ Now feed your mallow some iterable data:
|
|
20
20
|
```
|
21
21
|
Mallow's DSL has a moderately rich vocabulary of built-in helpers (with complementary method_missing magic if that's yr thing):
|
22
22
|
```ruby
|
23
|
-
Mallow.
|
23
|
+
Mallow.build { |match|
|
24
24
|
match.a(Float).to &:to_i
|
25
25
|
match.tuple(3).where{last != 0}.to {|a,b,c| (a + b) / c}
|
26
26
|
match.an(Array).and_hashify_with( :name, :age ).and_make_a( Person ).and &:save!
|
@@ -34,7 +34,7 @@ Mallow's DSL has a moderately rich vocabulary of built-in helpers (with compleme
|
|
34
34
|
|
35
35
|
A mallow is stateless, so it can't supply internal metadata (like index or match statistics) to rules. But that is not necessary for two reasons. First:
|
36
36
|
```ruby
|
37
|
-
Mallow.
|
37
|
+
Mallow.build do |match|
|
38
38
|
line = 0
|
39
39
|
match.a(Fixnum).to {"Found a fixnum on line #{line+=1}"}
|
40
40
|
match.*.to {|e| line+=1;e}
|
@@ -44,9 +44,9 @@ But that is just awful, and will betray you if you forget to increment the line
|
|
44
44
|
|
45
45
|
Luckily the second reason is that this should be done as part of some kind of post-processing anyway. To aid in such an undertaking, Mallow wraps a matched element in its _own_ metadata, which can be accessed transparently at any point in the transformer chain once a match has succeeded:
|
46
46
|
```ruby
|
47
|
-
doubler = Mallow.
|
48
|
-
m.a(Fixnum)
|
49
|
-
m.anything.to {nil}.^(matched: false)
|
47
|
+
doubler = Mallow.build do |m|
|
48
|
+
m.a(Fixnum).^(type: Fixnum).to {|n| n*2}
|
49
|
+
m.anything.to {nil}.^(matched: false)
|
50
50
|
end
|
51
51
|
|
52
52
|
data = doubler.fluff [1,2,:moo] #=> [2, 4, nil]
|
@@ -58,7 +58,7 @@ Luckily the second reason is that this should be done as part of some kind of po
|
|
58
58
|
|
59
59
|
When a matcher is passed a parameter-less block, Mallow evaluates that block in the context of the element running against the matcher:
|
60
60
|
```ruby
|
61
|
-
Mallow.
|
61
|
+
Mallow.build {|m| m.*.to {self} }.fluff1(1) #=> 1
|
62
62
|
```
|
63
63
|
In most cases this helps to make code less verbose and more semantic without having to rely on dispatch-via-method_missing (hooray!). If you're sticking side-effecting code in these blocks, though, weird things could potentially happen unless you're careful. If you want to avoid this behaviour, just be sure to give parameters to your blocks.
|
64
64
|
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Mallow
|
2
|
+
class BasicDSL
|
3
|
+
attr_reader :core, :actions, :conditions
|
4
|
+
|
5
|
+
def self.build_core
|
6
|
+
yield (dsl = new)
|
7
|
+
dsl.finish!
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@core = Core.new
|
12
|
+
reset!
|
13
|
+
end
|
14
|
+
|
15
|
+
def where(&b); push b, :conditions end
|
16
|
+
def to(&b); push b, :actions end
|
17
|
+
def and(&b); push b end
|
18
|
+
|
19
|
+
def finish!
|
20
|
+
in_conds? ? to{self}.finish! : rule!.core
|
21
|
+
end
|
22
|
+
|
23
|
+
alias such_that where
|
24
|
+
|
25
|
+
private
|
26
|
+
def in_conds?
|
27
|
+
actions.empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
def rule!
|
31
|
+
core << Rule::Builder[conditions, actions]
|
32
|
+
reset!
|
33
|
+
end
|
34
|
+
|
35
|
+
def push(p, loc = in_conds? ? :conditions : :actions)
|
36
|
+
rule! if loc == :conditions and not in_conds?
|
37
|
+
send(loc) << preproc(p)
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def preproc(p)
|
42
|
+
p.parameters.empty? ? proc {|e| e.instance_eval &p} : p
|
43
|
+
end
|
44
|
+
|
45
|
+
def reset!
|
46
|
+
@conditions, @actions = Matcher.new, Transformer.new
|
47
|
+
self
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/mallow/dsl.rb
CHANGED
@@ -1,104 +1,42 @@
|
|
1
|
+
require 'mallow/basic_dsl'
|
1
2
|
module Mallow
|
2
|
-
class DSL
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
reset!
|
13
|
-
end
|
14
|
-
|
15
|
-
def where(&b); push b, :conditions end
|
16
|
-
def to(&b); push b, :actions end
|
17
|
-
def and(&b); push b end
|
18
|
-
|
19
|
-
def *; where {true} end
|
20
|
-
def a(c); where {|e| e.is_a? c} end
|
21
|
-
def this(o); where {|e| e == o} end
|
22
|
-
def size(n); where {|e| e.size==n rescue false} end
|
23
|
-
def with_key(k); where {|e| e.has_key?(k) rescue false} end
|
24
|
-
|
25
|
-
def and_hashify_with_keys(*ks); to {|e| Hash[ks.zip e]} end
|
26
|
-
def and_hashify_with_values(*vs); to {|e| Hash[e.zip vs]} end
|
27
|
-
def with_metadata(d={}); to {|e| Meta.new e, d} end
|
28
|
-
|
29
|
-
def to_nil; to{nil} end
|
30
|
-
def to_true; to{true} end
|
31
|
-
def to_false; to{false} end
|
32
|
-
def to_self; to{self} end
|
33
|
-
|
34
|
-
def tuple(n); a(Array).size(n) end
|
35
|
-
def and_make(o,s=false); and_send(:new,o,s) end
|
36
|
-
|
37
|
-
def and_send(msg, obj, splat = false)
|
38
|
-
to {|e| splat ? obj.send(msg, *e) : obj.send(msg, e)}
|
39
|
-
end
|
40
|
-
|
41
|
-
alias an a
|
42
|
-
alias ^ with_metadata
|
43
|
-
alias anything *
|
44
|
-
alias and_hashify_with and_hashify_with_keys
|
45
|
-
alias and_make_a and_make
|
46
|
-
alias and_make_an and_make
|
47
|
-
alias a_tuple tuple
|
48
|
-
alias such_that where
|
49
|
-
alias of_size size
|
50
|
-
alias to_itself to_self
|
51
|
-
|
52
|
-
def finish!
|
53
|
-
in_conds? ? to_self.finish! : rule!.core
|
54
|
-
end
|
55
|
-
|
56
|
-
# Checks for three forms:
|
57
|
-
# * (a|an)_(<thing>) with no args
|
58
|
-
# * (with|of)_(<msg>) with one arg, which tests <match>.send(<msg>) == arg
|
59
|
-
# * to_(<msg>) with any args, which resolves to <match>.send(<msg>) *args
|
60
|
-
def method_missing(msg, *args)
|
61
|
-
case msg.to_s
|
62
|
-
when /^(a|an)_(.+)$/
|
63
|
-
args.empty??
|
64
|
-
(a(Object.const_get $2.split(?_).map(&:capitalize).join) rescue super) :
|
65
|
-
super
|
66
|
-
when /^(with|of)_(.+)$/
|
67
|
-
args.size == 1 ?
|
68
|
-
where {|e| e.send($2) == args.first rescue false} :
|
69
|
-
super
|
70
|
-
when /^to_(.+)$/
|
71
|
-
to {|e| e.send $1, *args}
|
72
|
-
else
|
73
|
-
super
|
3
|
+
class DSL < BasicDSL
|
4
|
+
module Matchers
|
5
|
+
def *; where {true} end
|
6
|
+
def a(c); where {|e| c===e} end
|
7
|
+
def this(o); where {|e| o== e} end
|
8
|
+
def size(n); where {|e| e.size==n rescue false} end
|
9
|
+
def with_key(k); where {|e| e.has_key?(k) rescue false} end
|
10
|
+
|
11
|
+
def tuple(n)
|
12
|
+
a(Array).size(n)
|
74
13
|
end
|
14
|
+
alias an a
|
15
|
+
alias anything *
|
16
|
+
alias of_size size
|
17
|
+
alias a_tuple tuple
|
75
18
|
end
|
76
19
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
20
|
+
module Transformers
|
21
|
+
def and_hashify_with_keys(*ks); to {|e| Hash[ks.zip e]} end
|
22
|
+
def and_hashify_with_values(*vs); to {|e| Hash[e.zip vs]} end
|
23
|
+
def ^(d={}); to {|e| Meta.new e, d } end
|
82
24
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
end
|
25
|
+
def and_make(o,s=false)
|
26
|
+
and_send(o,:new,s)
|
27
|
+
end
|
87
28
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
29
|
+
def and_send(obj, mgs, splat = false)
|
30
|
+
to {|e| splat ? obj.send(msg, *e) : obj.send(msg, e)}
|
31
|
+
end
|
32
|
+
alias and_hashify_with and_hashify_with_keys
|
33
|
+
alias and_make_a and_make
|
34
|
+
alias and_make_an and_make
|
92
35
|
end
|
93
36
|
|
94
|
-
|
95
|
-
|
96
|
-
end
|
37
|
+
include Matchers
|
38
|
+
include Transformers
|
97
39
|
|
98
|
-
def reset!
|
99
|
-
@conditions, @actions = Matcher.new, Transformer.new
|
100
|
-
self
|
101
|
-
end
|
102
40
|
end
|
103
41
|
end
|
104
42
|
|
data/lib/mallow/monads.rb
CHANGED
@@ -2,9 +2,7 @@ module Mallow
|
|
2
2
|
# Rule monad(ish) encapsulating "execute the first rule whose conditions
|
3
3
|
# pass" logic.
|
4
4
|
class Rule < Struct.new :matcher, :transformer, :val
|
5
|
-
|
6
|
-
def return(v); new Matcher.new, Transformer.new, v end
|
7
|
-
end
|
5
|
+
def self.return(v); new Matcher.new, Transformer.new, v end
|
8
6
|
# Curried proc for building procs for binding rules. If this were Haskell
|
9
7
|
# its type signature might vaguely resemble:
|
10
8
|
# Elt e => [e -> Bool] -> [e -> e] -> e -> Maybe (Meta e)
|
@@ -16,7 +14,7 @@ module Mallow
|
|
16
14
|
def unwrap!; matcher === val ? transformer >> val : dx end
|
17
15
|
private
|
18
16
|
def dx
|
19
|
-
raise
|
17
|
+
raise MatchException, "No rule matches #{val}:#{val.class}"
|
20
18
|
end
|
21
19
|
end
|
22
20
|
# Wrapper monad(ish) for successful matches that allows the user to
|
@@ -48,8 +46,6 @@ module Mallow
|
|
48
46
|
def >>(e); reduce(Meta.return(e),:bind) end
|
49
47
|
# Wraps argument using Meta::proc
|
50
48
|
def <<(p); super Meta::Builder[p] end
|
51
|
-
alias push <<
|
52
49
|
end
|
53
|
-
|
54
50
|
end
|
55
51
|
|
data/lib/mallow/version.rb
CHANGED
data/lib/mallow.rb
CHANGED
@@ -3,38 +3,14 @@ require 'mallow/version'
|
|
3
3
|
require 'mallow/monads'
|
4
4
|
require 'mallow/dsl'
|
5
5
|
module Mallow
|
6
|
-
class
|
7
|
-
|
6
|
+
class MatchException < StandardError; end
|
8
7
|
class Core < Array
|
9
|
-
def fluff(es)
|
10
|
-
|
11
|
-
end
|
12
|
-
def
|
13
|
-
_fluff1(e).val
|
14
|
-
end
|
15
|
-
def _fluff(es)
|
16
|
-
es.map {|e| _fluff1 e}
|
17
|
-
end
|
18
|
-
def _fluff1(e)
|
19
|
-
reduce(Rule.return(e),:bind).unwrap!
|
20
|
-
end
|
21
|
-
class << self
|
22
|
-
# aka Mallow::DSL::build
|
23
|
-
def build(&b); DSL.build &b end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
class << self
|
28
|
-
# aka Mallow::Core::build
|
29
|
-
def fluff(&b); Core.build(&b) end
|
30
|
-
# Defines a class method <sym> on <klass> to deserialize its argument (as
|
31
|
-
# with Core#fluff) using the Core generated by passing the supplied block
|
32
|
-
# to Mallow.fluff
|
33
|
-
def engulf(klass, sym=:fluff, &b)
|
34
|
-
mtd, mod = Mallow.fluff(&b), Module.new
|
35
|
-
mod.send(:define_method, sym) {|d| mtd.fluff d}
|
36
|
-
klass.extend mod
|
37
|
-
end
|
8
|
+
def fluff(es); _fluff(es).map &:val end
|
9
|
+
def fluff1(e); _fluff1(e).val end
|
10
|
+
def _fluff(es); es.map {|e| _fluff1 e} end
|
11
|
+
def _fluff1(e); reduce(Rule.return(e),:bind).unwrap! end
|
38
12
|
end
|
13
|
+
# see DSL#build_core
|
14
|
+
def self.build(&b); DSL.build_core &b end
|
39
15
|
end
|
40
16
|
|
data/mallow.gemspec
CHANGED
@@ -2,7 +2,7 @@ $LOAD_PATH << File.expand_path("../lib", __FILE__)
|
|
2
2
|
require 'rake'
|
3
3
|
require 'mallow/version'
|
4
4
|
|
5
|
-
|
5
|
+
Gem::Specification.new do |spec|
|
6
6
|
spec.name = 'mallow'
|
7
7
|
spec.version = Mallow::VERSION
|
8
8
|
spec.author = 'feivel jellyfish'
|
@@ -12,6 +12,6 @@ mallow = Gem::Specification.new do |spec|
|
|
12
12
|
spec.homepage = 'http://github.com/gwentacle/mallow'
|
13
13
|
spec.summary = 'Tiny universal data pattern matcher / dispatcher'
|
14
14
|
spec.description = 'Tiny universal data pattern matcher / dispatcher'
|
15
|
-
spec.add_development_dependency 'graham'
|
15
|
+
spec.add_development_dependency 'graham', '>=0.0.2'
|
16
16
|
end
|
17
17
|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class Cases
|
2
|
+
def initialize
|
3
|
+
@mallow = Mallow.build do |match|
|
4
|
+
match.a(String).to{upcase}
|
5
|
+
match.a_tuple(3).to {|a,b,c| a+b+c}
|
6
|
+
match.a(Fixnum).to {self*2}
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_case_1
|
11
|
+
@mallow.fluff [ 99, 'asdf', 'qwer', [5,5,5], 47, %w{cool story bro} ]
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
class Exceptions
|
17
|
+
def initialize
|
18
|
+
@mallow = Mallow.build do |match|
|
19
|
+
match.a(Fixnum).to {self/0}
|
20
|
+
match.a(String).to {self/0}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
def division_by_zero
|
24
|
+
@mallow.fluff1 1
|
25
|
+
end
|
26
|
+
def calling_a_nonexistent_method
|
27
|
+
@mallow.fluff1 ?1
|
28
|
+
end
|
29
|
+
def an_unmatched_element
|
30
|
+
@mallow.fluff1 :ok
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
Graham.pp(Cases) {|that|
|
36
|
+
that.test_case_1.returns_an_array.that_is [ 198, 'ASDF', 'QWER', 15, 94, 'coolstorybro' ]
|
37
|
+
}
|
38
|
+
|
39
|
+
Graham.pp(Exceptions) {|that|
|
40
|
+
that.division_by_zero.raises_a ZeroDivisionError
|
41
|
+
that.calling_a_nonexistent_method.raises_a NoMethodError
|
42
|
+
that.an_unmatched_element.raises_a Mallow::MatchException
|
43
|
+
}
|
44
|
+
|
data/test/unit/meta.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
class MetaTests
|
2
|
+
def binding_behaviour_with_common_keys
|
3
|
+
meta = Mallow::Meta.return 1, meta: :data, any: :body?
|
4
|
+
meta.bind ->(v){Mallow::Meta.return v, meta: :data!}
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
Graham.pp(MetaTests) do |that|
|
9
|
+
that.binding_behaviour_with_common_keys.returns meta: :data!, any: :body?
|
10
|
+
end
|
11
|
+
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class
|
1
|
+
class MonadLaws
|
2
2
|
def RuleLeftIdentity
|
3
3
|
rule = Mallow::Rule.return 350_000_000
|
4
4
|
f = Mallow::Rule::Builder[Mallow::Matcher.new][Mallow::Transformer.new]
|
@@ -36,7 +36,7 @@ class Graham::MonadLaws
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
Graham.pp(
|
39
|
+
Graham.pp(MonadLaws) {|that|
|
40
40
|
that.RuleLeftIdentity.is true
|
41
41
|
that.RuleRightIdentity.is true
|
42
42
|
that.RuleAssociativity.is true
|
data/test/unit/rule.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
class RuleTests
|
2
|
+
def initialize
|
3
|
+
(@fmatcher = Mallow::Matcher.new)[0] = ->(e){false}
|
4
|
+
(@pmatcher = Mallow::Matcher.new)[0] = ->(e){true}
|
5
|
+
@fbuilder = Mallow::Rule::Builder[@fmatcher, Mallow::Transformer.new]
|
6
|
+
@pbuilder = Mallow::Rule::Builder[@pmatcher, Mallow::Transformer.new]
|
7
|
+
end
|
8
|
+
|
9
|
+
def unwrapping_an_empty_rule
|
10
|
+
Mallow::Rule.return(nil).unwrap!
|
11
|
+
end
|
12
|
+
|
13
|
+
def unwrapping_a_passing_rule
|
14
|
+
@pbuilder[:value].unwrap!
|
15
|
+
end
|
16
|
+
|
17
|
+
def unwrapping_a_failing_rule
|
18
|
+
@fbuilder[:value].unwrap!
|
19
|
+
end
|
20
|
+
|
21
|
+
def binding_a_failing_rule_in_a_passing_rule
|
22
|
+
@fbuilder[1].bind(@pbuilder)
|
23
|
+
end
|
24
|
+
|
25
|
+
def binding_a_passing_rule_in_a_failing_rule
|
26
|
+
@pbuilder[//].bind(@fbuilder)
|
27
|
+
end
|
28
|
+
|
29
|
+
def binding_a_passing_rule_in_a_passing_rule
|
30
|
+
(passing_matcher = Mallow::Matcher.new)[0] = ->(e){1}
|
31
|
+
passing_builder = Mallow::Rule::Builder[passing_matcher, Mallow::Transformer.new]
|
32
|
+
@pbuilder[1].bind passing_builder
|
33
|
+
end
|
34
|
+
|
35
|
+
def binding_a_failing_rule_in_a_failing_rule
|
36
|
+
(failing_matcher = Mallow::Matcher.new)[0] = ->(e){nil}
|
37
|
+
failing_builder = Mallow::Rule::Builder[failing_matcher, Mallow::Transformer.new]
|
38
|
+
@fbuilder[1].bind failing_builder
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
Graham.pp(RuleTests) do |that|
|
43
|
+
that.unwrapping_an_empty_rule.raises_a Mallow::MatchException
|
44
|
+
that.unwrapping_a_failing_rule.raises_a Mallow::MatchException
|
45
|
+
that.unwrapping_a_passing_rule.returns_a(Mallow::Meta).such_that { val == :value }
|
46
|
+
|
47
|
+
that.binding_a_failing_rule_in_a_passing_rule.returns_a(Mallow::Rule).such_that { matcher === val }
|
48
|
+
that.binding_a_passing_rule_in_a_passing_rule.returns_a(Mallow::Rule).such_that { matcher === val }
|
49
|
+
that.binding_a_passing_rule_in_a_failing_rule.returns_a(Mallow::Rule).such_that { matcher === val }
|
50
|
+
that.binding_a_failing_rule_in_a_failing_rule.returns_a(Mallow::Rule).such_that { not matcher === val }
|
51
|
+
end
|
52
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mallow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: graham
|
@@ -18,7 +18,7 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 0.0.2
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 0.0.2
|
30
30
|
description: Tiny universal data pattern matcher / dispatcher
|
31
31
|
email: feivel@sdf.org
|
32
32
|
executables: []
|
@@ -36,12 +36,15 @@ files:
|
|
36
36
|
- mallow.gemspec
|
37
37
|
- README.md
|
38
38
|
- lib/mallow.rb
|
39
|
+
- lib/mallow/basic_dsl.rb
|
39
40
|
- lib/mallow/version.rb
|
40
41
|
- lib/mallow/dsl.rb
|
41
42
|
- lib/mallow/monads.rb
|
42
43
|
- Rakefile
|
43
|
-
- test/case/
|
44
|
-
- test/unit/
|
44
|
+
- test/case/control.rb
|
45
|
+
- test/unit/monad_laws.rb
|
46
|
+
- test/unit/meta.rb
|
47
|
+
- test/unit/rule.rb
|
45
48
|
homepage: http://github.com/gwentacle/mallow
|
46
49
|
licenses: []
|
47
50
|
post_install_message:
|
@@ -68,5 +71,7 @@ specification_version: 3
|
|
68
71
|
summary: Tiny universal data pattern matcher / dispatcher
|
69
72
|
test_files:
|
70
73
|
- Rakefile
|
71
|
-
- test/case/
|
72
|
-
- test/unit/
|
74
|
+
- test/case/control.rb
|
75
|
+
- test/unit/monad_laws.rb
|
76
|
+
- test/unit/meta.rb
|
77
|
+
- test/unit/rule.rb
|
data/test/case/mallow.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
class Graham::Cases
|
2
|
-
def initialize
|
3
|
-
@mallow1 = Mallow.fluff do |match|
|
4
|
-
match.a_string.to_upcase
|
5
|
-
match.a_tuple(3).to {|a,b,c| a+b+c}
|
6
|
-
match.a_fixnum.to {self*2}
|
7
|
-
end
|
8
|
-
|
9
|
-
@xmallow = Mallow.fluff do |match|
|
10
|
-
match.a(Fixnum).to {self/0}
|
11
|
-
match.a(String).to {self/self}
|
12
|
-
match.*.to {}
|
13
|
-
match.a_symbol.to {UNDEFINED}
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def Case1
|
18
|
-
@mallow1.fluff [ 99, 'asdf', 'qwer', [5,5,5], 47, %w{cool story bro} ]
|
19
|
-
end
|
20
|
-
|
21
|
-
def XCase1
|
22
|
-
@xmallow.fluff1 1
|
23
|
-
end
|
24
|
-
def XCase2
|
25
|
-
@xmallow.fluff1 ?1
|
26
|
-
end
|
27
|
-
def XCase3
|
28
|
-
@xmallow.fluff1 :ok
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
Graham.pp {|that|
|
33
|
-
that.Case1.returns_an(Array).that_is [ 198, 'ASDF', 'QWER', 15, 94, 'coolstorybro' ]
|
34
|
-
that.XCase1.raises_a ZeroDivisionError
|
35
|
-
that.XCase2.raises_a NoMethodError
|
36
|
-
that.XCase3.does_not_raise_an_exception
|
37
|
-
}
|
38
|
-
|