patme 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.travis.yml +8 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +229 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/patme/arguments/arbitrary.rb +20 -0
- data/lib/patme/arguments/optional.rb +22 -0
- data/lib/patme/arguments/specific.rb +21 -0
- data/lib/patme/implementation.rb +21 -0
- data/lib/patme/implementation_builder.rb +61 -0
- data/lib/patme/method.rb +22 -0
- data/lib/patme/pattern_matching.rb +38 -0
- data/lib/patme/version.rb +3 -0
- data/lib/patme.rb +6 -0
- data/patme.gemspec +28 -0
- metadata +119 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f270e55081adb2c27a467a59a88dcce06996a14f
|
4
|
+
data.tar.gz: 5fb92273c02545651cb7b0b2033c61c5f87c7f6a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 60c5a51bb417bf20fe806040ab9f1e14428e4aa57021f134ddc007154fc69b955856aa97942abdf18fb6619fff21def8161f91fbaaf62e310ffe4ca846bcf184
|
7
|
+
data.tar.gz: 8d5b443bab40c29f57b1982931f0827d1a53227e9824b9fbcbf3b2606f3883480d9b48390691312d61f729abb162d65f488dbc895406a13c7b6827aada0c52ef
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 vizvamitra
|
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
|
13
|
+
all 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
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,229 @@
|
|
1
|
+
# Patme
|
2
|
+
|
3
|
+
[](https://travis-ci.org/vizvamitra/patme)
|
4
|
+
|
5
|
+
This gem is my experiment on elixir-style pattern matching in ruby.
|
6
|
+
|
7
|
+
The implementation is neither production-ready, nor complete. It is just a proof of concept.
|
8
|
+
|
9
|
+
## Info
|
10
|
+
|
11
|
+
Patme module stores your instance methods internally and removes them from your class. Then, when method is called, it tries to pattern-match given arguments with existing method implementations. If implementation was found, it executes it, othervise you'll get a NoMethodError.
|
12
|
+
|
13
|
+
Currently this gem supports 3 types of arguments: specific, arbitrary and optional. In method definition `def foo(agr1, arg2=1, _arg3=false)` arg1 is an arbitrary argument, arg2 is specific and arg3 is optional.
|
14
|
+
|
15
|
+
Patme supports class-based pattern matching. If method's specific argument is a `Class`, then it will be matched based on given argument's class using `is_a?`
|
16
|
+
|
17
|
+
|
18
|
+
## Limitations
|
19
|
+
|
20
|
+
Only pattern matching on instance methods is supported. Also you must use parentheses around method arguments.
|
21
|
+
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
#### Recursion example
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require 'patme'
|
29
|
+
|
30
|
+
class Factorial
|
31
|
+
include Patme::PatternMatching
|
32
|
+
|
33
|
+
def calculate(n=0)
|
34
|
+
1
|
35
|
+
end
|
36
|
+
|
37
|
+
def calculate(n)
|
38
|
+
n * self.of(n-1)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
factorial_calculator = Factorial.new
|
43
|
+
|
44
|
+
factorial_calculator.calculate(0) # => 1
|
45
|
+
factorial_calculator.calculate(5) # => 120
|
46
|
+
factorial_calculator.calculate(-1) # => endless recursion, don't do so ^_^
|
47
|
+
```
|
48
|
+
|
49
|
+
|
50
|
+
#### Class-based pattern matching
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
require 'parme'
|
54
|
+
|
55
|
+
SeriousError = Class.new(StandardError)
|
56
|
+
RegularError = Class.new(StandardError)
|
57
|
+
UnexpectedError = Class.new(StandardError)
|
58
|
+
|
59
|
+
class ErrorHandler
|
60
|
+
include Patme::PatternMatching
|
61
|
+
|
62
|
+
def initialize(error)
|
63
|
+
@error = error
|
64
|
+
end
|
65
|
+
|
66
|
+
def handle
|
67
|
+
do_handle(@error)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Will match if error.is_a?(SeriousError)
|
71
|
+
def do_handle(error=SeriousError)
|
72
|
+
puts "Alarm! SeriousError! Details: #{error.message}"
|
73
|
+
end
|
74
|
+
|
75
|
+
# Will match if error.is_a?(RegularError)
|
76
|
+
def do_handle(error=RegularError)
|
77
|
+
puts "Don't worry, just a RegularError: #{error.message}"
|
78
|
+
end
|
79
|
+
|
80
|
+
# Will match for all other StandardErrors
|
81
|
+
def do_handle(error=StandardError)
|
82
|
+
puts "Unexpected error: #{error.class}. Details: #{error.message}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
begin
|
87
|
+
raise SeriousError, 'boom!'
|
88
|
+
rescue => error
|
89
|
+
ErrorHandler.new(error).handle
|
90
|
+
end
|
91
|
+
# => Alarm! SeriousError! Details: boom!
|
92
|
+
|
93
|
+
begin
|
94
|
+
raise RegularError, 'we need to fix this'
|
95
|
+
rescue => error
|
96
|
+
ErrorHandler.new(error).handle
|
97
|
+
end
|
98
|
+
# => Don't worry, just a RegularError: we need to fix this
|
99
|
+
|
100
|
+
begin
|
101
|
+
raise UnexpectedError, 'something went completely wrong'
|
102
|
+
rescue => error
|
103
|
+
ErrorHandler.new(error).handle
|
104
|
+
end
|
105
|
+
# => Unexpected error: UnexpectedError. Details: something went completely wrong
|
106
|
+
```
|
107
|
+
|
108
|
+
|
109
|
+
#### Full-featured example
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
require 'patme'
|
113
|
+
|
114
|
+
class MyClass
|
115
|
+
include Patme::PatternMatching
|
116
|
+
|
117
|
+
# This method will match only when arg1 ='test'
|
118
|
+
def foo(arg1='test')
|
119
|
+
"runned foo('test') with #{arg1}"
|
120
|
+
end
|
121
|
+
|
122
|
+
# Will match only when arg1 ='other'
|
123
|
+
def foo(arg1='other')
|
124
|
+
"runned foo('other') with #{arg1}"
|
125
|
+
end
|
126
|
+
|
127
|
+
# You can also use other basic types
|
128
|
+
def foo(arg1={a: 1, b: 2})
|
129
|
+
"runned foo({a: 1, b: 2}) with #{arg1}"
|
130
|
+
end
|
131
|
+
|
132
|
+
# Will match when arg2 = 'test' no matter what arg1 is
|
133
|
+
def foo(arg1, arg2='test')
|
134
|
+
"runned foo(any, 'test') with [#{arg1}, #{arg2}]"
|
135
|
+
end
|
136
|
+
|
137
|
+
# Will match with any arg1 and both with and without arg2
|
138
|
+
# if arg2 is not supplied, method will receive arg2 = 'default'
|
139
|
+
def foo(arg1, _arg2="default")
|
140
|
+
"runned foo(any, optional) with [#{arg1}, #{_arg2}]"
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
# Will match with any one argument.
|
145
|
+
def bar(arg1)
|
146
|
+
"runned bar(any) with #{arg1}"
|
147
|
+
end
|
148
|
+
|
149
|
+
# Won't ever match because previous definition of bar will be pattern-matched
|
150
|
+
# before this one
|
151
|
+
def bar(arg1='never')
|
152
|
+
"runned bar('never') with #{arg1}"
|
153
|
+
end
|
154
|
+
|
155
|
+
|
156
|
+
def baz(arg1='test')
|
157
|
+
"runned baz('test') with #{arg1}"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
my_obj = MyClass.new
|
162
|
+
|
163
|
+
my_obj.foo('test') # => "runned foo('test') with test"
|
164
|
+
my_obj.foo('other') # => "runned foo('other') with other"
|
165
|
+
my_obj.foo({a: 1, b: 2}) # => "runned foo({a: 1, b: 2}) with {:a => 1, :b => 2}"
|
166
|
+
my_obj.foo(1, 'test') # => "runned foo(any, 'test') with [1, test]"
|
167
|
+
my_obj.foo(1) # => "runned foo(any, optional) with [1, default]"
|
168
|
+
my_obj.foo(1, 'some') # => "runned foo(any, optional) with [1, some]"
|
169
|
+
|
170
|
+
my_obj.bar(1) # => "runned bar(any) with 1"
|
171
|
+
my_obj.bar('never') # => "runned bar(any) with never"
|
172
|
+
|
173
|
+
my_obj.baz('test') # => "runned baz('test') with test"
|
174
|
+
my_obj.baz(1) # => NoMethodError
|
175
|
+
```
|
176
|
+
|
177
|
+
|
178
|
+
## Todos
|
179
|
+
|
180
|
+
1. Add support for keyword arguments (`key:` - arbitrary, `key: value` - specific, `_key: value` - optional)
|
181
|
+
2. Add support for class methods
|
182
|
+
3. Add something to tell Parme not to pattern-match on given methods
|
183
|
+
|
184
|
+
```ruby
|
185
|
+
# Possible example
|
186
|
+
class Hello
|
187
|
+
include Parme::PatternMatching
|
188
|
+
|
189
|
+
# Comment after method header will tell Parme not to touch this method
|
190
|
+
def tell(name) # ::pm_off
|
191
|
+
puts "Hello, #{name}"
|
192
|
+
end
|
193
|
+
end
|
194
|
+
```
|
195
|
+
|
196
|
+
4. Add support for method headers without parentheses
|
197
|
+
5. Add watchers
|
198
|
+
|
199
|
+
```ruby
|
200
|
+
# Possible example
|
201
|
+
class Factorial
|
202
|
+
include Patme::PatternMatch
|
203
|
+
|
204
|
+
def calculate(n=0)
|
205
|
+
1
|
206
|
+
end
|
207
|
+
|
208
|
+
def calculate(n) # ::when( n < 0 )
|
209
|
+
raise ArgumentError, "Can't calculate factorial of a negative number: #{n}"
|
210
|
+
end
|
211
|
+
|
212
|
+
def calculate(n) # ::when( n > 0 )
|
213
|
+
n * self.of(n-1)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
```
|
217
|
+
|
218
|
+
6. Your suggestions?
|
219
|
+
|
220
|
+
|
221
|
+
## Contributing
|
222
|
+
|
223
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/vizvamitra/patme.
|
224
|
+
|
225
|
+
|
226
|
+
## License
|
227
|
+
|
228
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
229
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "patme"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "pry"
|
14
|
+
Pry.start
|
data/bin/setup
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Patme
|
2
|
+
module Arguments
|
3
|
+
class Arbitrary
|
4
|
+
def initialize(_value=nil)
|
5
|
+
end
|
6
|
+
|
7
|
+
def get_value(given=nil)
|
8
|
+
given
|
9
|
+
end
|
10
|
+
|
11
|
+
def ==(other)
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
15
|
+
def any?; true; end
|
16
|
+
def optional?; false; end
|
17
|
+
def specific?; false; end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Patme
|
2
|
+
module Arguments
|
3
|
+
class Optional
|
4
|
+
def initialize(default_value)
|
5
|
+
@default_value = default_value
|
6
|
+
end
|
7
|
+
|
8
|
+
# *given is an array to distinguish cases with no value or nil
|
9
|
+
def get_value(*given)
|
10
|
+
given.size == 1 ? given[0] : @default_value
|
11
|
+
end
|
12
|
+
|
13
|
+
def ==(other)
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
def any?; false; end
|
18
|
+
def optional?; true; end
|
19
|
+
def specific?; false; end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Patme
|
2
|
+
module Arguments
|
3
|
+
class Specific
|
4
|
+
def initialize(value)
|
5
|
+
@value = value
|
6
|
+
end
|
7
|
+
|
8
|
+
def get_value(given)
|
9
|
+
given
|
10
|
+
end
|
11
|
+
|
12
|
+
def ==(other)
|
13
|
+
@value.is_a?(Class) ? other.is_a?(@value) : @value == other
|
14
|
+
end
|
15
|
+
|
16
|
+
def any?; false; end
|
17
|
+
def optional?; false; end
|
18
|
+
def specific?; true; end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Patme
|
2
|
+
class Implementation
|
3
|
+
|
4
|
+
def initialize(method_obj, args)
|
5
|
+
@method_proc = method_obj
|
6
|
+
@args = args
|
7
|
+
end
|
8
|
+
|
9
|
+
def match?(given_args)
|
10
|
+
required_args = @args.reject(&:optional?)
|
11
|
+
|
12
|
+
(required_args.size..@args.size).cover?(given_args.size)\
|
13
|
+
&& required_args == given_args.first(required_args.size)
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(object, args)
|
17
|
+
@method_proc.bind(object).call(*args)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Patme
|
2
|
+
|
3
|
+
# Gets method's header (for example, def foo(arg1, arg2='spec', _arg3='opt') )
|
4
|
+
# parses it and creates method implementation with the following arguments:
|
5
|
+
# arg1 - any argument
|
6
|
+
# arg2 - specific argument, 'spec'
|
7
|
+
# _arg3 - optional argument which defaults to 'opt'
|
8
|
+
class ImplementationBuilder
|
9
|
+
def initialize(method_obj)
|
10
|
+
@method_obj = method_obj
|
11
|
+
end
|
12
|
+
|
13
|
+
def build
|
14
|
+
values = get_values(method_header, method_params)
|
15
|
+
args = build_args(method_params, values)
|
16
|
+
|
17
|
+
Patme::Implementation.new(@method_obj, args)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def get_values(header, params)
|
23
|
+
return {} if params.size == 0
|
24
|
+
|
25
|
+
regex_str = params.map do |type, name|
|
26
|
+
case type
|
27
|
+
when :opt then "#{name}=(?<#{name}>.+)"
|
28
|
+
when :req
|
29
|
+
name =~ /^_/ ? "#{name}=(?<#{name}>.+)" : "#{name}"
|
30
|
+
end
|
31
|
+
end.join(', ') + '\s*\)\s*$'
|
32
|
+
|
33
|
+
match_data = header.match( Regexp.new(regex_str) )
|
34
|
+
match_data.names.map do |name|
|
35
|
+
[name.to_sym, eval(match_data[name.to_s])]
|
36
|
+
end.to_h
|
37
|
+
end
|
38
|
+
|
39
|
+
def method_header
|
40
|
+
path, line = @method_obj.source_location
|
41
|
+
File.read(path).split("\n")[line - 1]
|
42
|
+
end
|
43
|
+
|
44
|
+
def method_params
|
45
|
+
@method_obj.parameters
|
46
|
+
end
|
47
|
+
|
48
|
+
def build_args(params, values)
|
49
|
+
return [] if params.size == 0
|
50
|
+
|
51
|
+
params.map do |type, name|
|
52
|
+
case type
|
53
|
+
when :opt
|
54
|
+
(name =~ /^_/ ? Arguments::Optional : Arguments::Specific).new(values[name])
|
55
|
+
when :req then Arguments::Arbitrary.new
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
data/lib/patme/method.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
module Patme
|
2
|
+
class Method
|
3
|
+
|
4
|
+
def initialize(name)
|
5
|
+
@name = name
|
6
|
+
@implementations = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def add_implementation(implementation)
|
10
|
+
@implementations << implementation
|
11
|
+
end
|
12
|
+
|
13
|
+
def implemented_for?(args)
|
14
|
+
@implementations.any?{|i| i.match?(args)}
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(object, args)
|
18
|
+
@implementations.find{|i| i.match?(args)}.call(object, args)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Patme
|
2
|
+
|
3
|
+
module PatternMatching
|
4
|
+
def self.included(klass)
|
5
|
+
klass.include(InstanceMethods)
|
6
|
+
klass.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def method_added(name)
|
11
|
+
@patme_methods ||= {}
|
12
|
+
@patme_methods[name] ||= Patme::Method.new(name)
|
13
|
+
|
14
|
+
method_obj = self.instance_method(name)
|
15
|
+
impl = Patme::ImplementationBuilder.new(method_obj).build
|
16
|
+
@patme_methods[name].add_implementation(impl)
|
17
|
+
|
18
|
+
undef_method(name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def patme_method(name)
|
22
|
+
@patme_methods[name]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module InstanceMethods
|
27
|
+
def method_missing name, *args, &block
|
28
|
+
method = self.class.patme_method(name)
|
29
|
+
if method && method.implemented_for?(args)
|
30
|
+
method.call(self, args)
|
31
|
+
else
|
32
|
+
super
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
data/lib/patme.rb
ADDED
data/patme.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'patme/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "patme"
|
8
|
+
spec.version = Patme::VERSION
|
9
|
+
spec.authors = ["Dmitrii Krasnov"]
|
10
|
+
spec.email = ["vizvamitra@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = "Pattern matching for ruby methods"
|
13
|
+
spec.description = "Elixir-style pattern matching for ruby methods"
|
14
|
+
spec.homepage = "http://github.com/vizvamitra/patme"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
27
|
+
spec.add_development_dependency "pry"
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: patme
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dmitrii Krasnov
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-03-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.14'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.14'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Elixir-style pattern matching for ruby methods
|
70
|
+
email:
|
71
|
+
- vizvamitra@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rspec"
|
78
|
+
- ".travis.yml"
|
79
|
+
- Gemfile
|
80
|
+
- LICENSE.txt
|
81
|
+
- README.md
|
82
|
+
- Rakefile
|
83
|
+
- bin/console
|
84
|
+
- bin/setup
|
85
|
+
- lib/patme.rb
|
86
|
+
- lib/patme/arguments/arbitrary.rb
|
87
|
+
- lib/patme/arguments/optional.rb
|
88
|
+
- lib/patme/arguments/specific.rb
|
89
|
+
- lib/patme/implementation.rb
|
90
|
+
- lib/patme/implementation_builder.rb
|
91
|
+
- lib/patme/method.rb
|
92
|
+
- lib/patme/pattern_matching.rb
|
93
|
+
- lib/patme/version.rb
|
94
|
+
- patme.gemspec
|
95
|
+
homepage: http://github.com/vizvamitra/patme
|
96
|
+
licenses:
|
97
|
+
- MIT
|
98
|
+
metadata: {}
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
requirements: []
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 2.6.10
|
116
|
+
signing_key:
|
117
|
+
specification_version: 4
|
118
|
+
summary: Pattern matching for ruby methods
|
119
|
+
test_files: []
|