pattern-proc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 570c658ac139da0ade4f67576ec391963253c432
4
+ data.tar.gz: c59c291c8cc567c685fe42c907c79eecee31f985
5
+ SHA512:
6
+ metadata.gz: f767b258e7adb44cc7c114dcc5f139dc560ea1554fc60cdc2d3eb1f9bc8dba25e1069b0601071df0ce7b0c7b3e21ebb4a809728a03f8106058e61066062f0369
7
+ data.tar.gz: fab0de65a0e2215f50119a4bae8883b8c4ff14f97392a8af839066314c18e3a1eb5a492aa68b1880fe5ab01ce44e3ec6d2bbd667bb6b391fe71bbec279003225
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 William Pleasant-Ryan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ pattern-proc
2
+ ============
3
+
4
+ pattern matching Proc definitions
@@ -0,0 +1,146 @@
1
+ class PatternProc
2
+
3
+ def initialize(cases = [])
4
+ @arity = -1
5
+ @cases = []
6
+ cases.each do |c| add_case c end
7
+ end
8
+
9
+ def with(*args, &block)
10
+ case_obj = PatternProcCase.new(args, &block)
11
+ add_case case_obj
12
+ case_obj
13
+ end
14
+
15
+ def to_proc
16
+ ->(*args) { call(args) }
17
+ end
18
+
19
+ private
20
+ def add_case(case_obj)
21
+ if @arity == -1
22
+ @arity = case_obj.arity
23
+ elsif @arity != case_obj.arity
24
+ raise "mismatched arity"
25
+ end
26
+ @cases << case_obj
27
+ end
28
+
29
+
30
+ def call(args)
31
+ if args.size == @arity
32
+ best_match = find_matches(args, true).first
33
+ if best_match
34
+ best_match.to_proc.call(args)
35
+ else
36
+ raise "no match"
37
+ end
38
+ elsif args.size < @arity
39
+ sliced_cases = find_matches(args, false)
40
+ if sliced_cases.size > 0
41
+ PatternProc.new(sliced_cases).to_proc
42
+ else
43
+ raise "no match"
44
+ end
45
+ else
46
+ raise "too many args"
47
+ end
48
+ end
49
+
50
+ def find_matches(args, stop_at_first_match)
51
+ results = []
52
+ sorted_cases = @cases.sort do |case_obj_1, case_obj_2|
53
+ case_obj_1.specificity <=> case_obj_2.specificity
54
+ end.reverse
55
+ sorted_cases.each do |case_obj|
56
+ result = case_obj.make_subcase(args)
57
+ if result
58
+ results << result
59
+ if stop_at_first_match
60
+ break
61
+ end
62
+ end
63
+ end
64
+ results
65
+ end
66
+ end
67
+
68
+ class PatternProcCase
69
+
70
+ attr_reader :proc_applied_level
71
+ attr_reader :proc_arity
72
+
73
+ def initialize(args, previous_specificity = 0, proc_arity = 0, &block)
74
+ @expected_args = args
75
+ @proc = block
76
+ @proc_arity = proc_arity
77
+ @previous_specificity = previous_specificity || 0
78
+ if block.present? && block.arity > 0
79
+ @proc_arity = block.arity
80
+ end
81
+ end
82
+
83
+ def returns(value)
84
+ @return_value = value
85
+ self
86
+ end
87
+
88
+ # private ish
89
+ def expected_arity
90
+ @expected_args.size || 0
91
+ end
92
+
93
+ def arity
94
+ expected_arity + proc_arity
95
+ end
96
+
97
+ def specificity
98
+ expected_arity + @previous_specificity
99
+ end
100
+
101
+ def make_subcase(args)
102
+ match_len = [args.size, @expected_args.size].min
103
+ expected = @expected_args.take(match_len)
104
+ actual = args.take(match_len)
105
+ if expected == actual
106
+ new_proc = to_proc.curry
107
+ curry_count = args.size - @expected_args.size
108
+ new_arity = proc_arity
109
+ if curry_count > 0
110
+ send_args = args.drop(match_len).take(curry_count)
111
+ new_proc = new_proc.call(*send_args)
112
+ new_arity -= curry_count
113
+ if new_arity == 0
114
+ return PatternProcCase.new([], specificity).returns(new_proc)
115
+ elsif !(new_proc.is_a?(Proc))
116
+ raise "uh oh"
117
+ end
118
+ end
119
+ PatternProcCase.new(@expected_args.drop(match_len), specificity, new_arity, &new_proc).returns(@return_value)
120
+ else
121
+ nil
122
+ end
123
+ end
124
+
125
+ def to_proc
126
+ @proc || ->(*args) { @return_value }
127
+ end
128
+ end
129
+
130
+ class Object
131
+ def partials(method)
132
+ @__partials ||= {}
133
+ unless @__partials[method]
134
+ proc_obj = ComposableProc.new
135
+ metaclass = class << self; self; end
136
+ metaclass.class_eval do
137
+ define_method(method) do |*args|
138
+ curried_method = proc_obj.to_proc.curry
139
+ curried_method[*args]
140
+ end
141
+ end
142
+ @__partials[method] = proc_obj
143
+ end
144
+ @__partials[method]
145
+ end
146
+ end
@@ -0,0 +1,14 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'pattern-proc'
3
+ s.version = '0.0.1'
4
+ s.date = '2014-07-01'
5
+ s.summary = 'Pattern Proc'
6
+ s.description = 'define a Proc with pattern matching "re-declaration" ala Haskell'
7
+ s.authors = ['William Pleasant-Ryan']
8
+ s.email = ['krelian18@gmail.com']
9
+ s.files = `git ls-files`.split("\n")
10
+ s.files.delete(".gitignore")
11
+ s.homepage = "http://rubygems.org/gems/pattern-proc"
12
+ s.license = "MIT"
13
+ end
14
+
@@ -0,0 +1,54 @@
1
+ describe PatternProc do
2
+ subject { described_class.new }
3
+
4
+ it "simple" do
5
+ subject.with(3,4).returns(12)
6
+
7
+ prc = subject.to_proc
8
+ prc.(3,4).should == 12
9
+ prc.(3).(4).should == 12
10
+ end
11
+
12
+ it "works" do
13
+ subject.with(3,1,2).returns(12)
14
+ subject.with(4,4,1).returns(10)
15
+ subject.with(7,7,7).returns(777)
16
+ subject.with(7,7) do |l_arg|
17
+ 140 + l_arg
18
+ end
19
+ subject.with(7,3,4).returns(11)
20
+ subject.with(2) do |x, y| 2 * x * y end
21
+ subject.with do |x, y, z|
22
+ x * (y + z)
23
+ end
24
+
25
+ prc = subject.to_proc
26
+
27
+ prc.(3,1,2).should == 12
28
+ prc.(3).(1,2).should == 12
29
+ prc.(3).(1).(2).should == 12
30
+ prc.(3,1).(2).should == 12
31
+
32
+ prc.(4,4,1).should == 10
33
+ prc.(4,4,2).should == 24
34
+ prc.(4,4).(2).should == 24
35
+ prc.(4).(4,2).should == 24
36
+
37
+ prc.(7,7,7).should == 777
38
+ prc.(7).(7).(7).should == 777
39
+ prc.(7).(7,7).should == 777
40
+
41
+ prc.(7,7,3).should == 143
42
+ prc.(7).(7,3).should == 143
43
+ prc.(7,7).(3).should == 143
44
+ prc.(7).(7).(3).should == 143
45
+
46
+ prc.(2,1,1).should == 2
47
+ prc.(2,3).(8).should == 48
48
+
49
+ prc.(5,6,7).should == 65
50
+ prc.(5).(6,7).should == 65
51
+ prc.(5).(6).(7).should == 65
52
+ prc.(5,6).(7).should == 65
53
+ end
54
+ end
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pattern-proc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - William Pleasant-Ryan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-01 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: define a Proc with pattern matching "re-declaration" ala Haskell
14
+ email:
15
+ - krelian18@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - LICENSE
21
+ - README.md
22
+ - lib/pattern_proc.rb
23
+ - pattern-proc.gemspec
24
+ - spec/pattern_proc_spec.rb
25
+ homepage: http://rubygems.org/gems/pattern-proc
26
+ licenses:
27
+ - MIT
28
+ metadata: {}
29
+ post_install_message:
30
+ rdoc_options: []
31
+ require_paths:
32
+ - lib
33
+ required_ruby_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ required_rubygems_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ requirements: []
44
+ rubyforge_project:
45
+ rubygems_version: 2.2.2
46
+ signing_key:
47
+ specification_version: 4
48
+ summary: Pattern Proc
49
+ test_files: []