pattern-matching 0.4.0 → 0.4.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.
- checksums.yaml +4 -4
- data/README.md +54 -14
- data/lib/pattern_matching.rb +2 -8
- data/lib/pattern_matching/all.rb +4 -0
- data/lib/pattern_matching/functions.rb +62 -0
- data/lib/pattern_matching/version.rb +3 -0
- data/spec/spec_helper.rb +1 -2
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f2ca66eef8d4d13adbeb30543b7e94041cff2f3
|
4
|
+
data.tar.gz: f3bc1eb0cc656c4dc3c94fdd9acca81f37fc3bb8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70efb1797316f271897879dcb889b323c5471f4d9bf82dca6956b234b1e87a488ce106bfd99c11e6ce076921fab2472331efec3adfcf1e795471f9d6508ed408
|
7
|
+
data.tar.gz: 3a65bdb66509b7274a604415198009b9d01da4453ddfc63cdc49d7536a43c80721be76fa07cfc8e50e8c153b8e6279f06da76de8ccad136d824573d58997d4ff
|
data/README.md
CHANGED
@@ -2,8 +2,6 @@
|
|
2
2
|
|
3
3
|
A gem for adding Erlang-style function/method overloading through pattern matching to Ruby classes.
|
4
4
|
|
5
|
-
*NOTE: This is a work in progress. Expect changes.*
|
6
|
-
|
7
5
|
The project is hosted on the following sites:
|
8
6
|
|
9
7
|
* [RubyGems project page](https://rubygems.org/gems/pattern-matching)
|
@@ -26,7 +24,8 @@ Pattern matching is like function overloading cranked to 11. So one day I was mu
|
|
26
24
|
that I'd like to see Erlang-stype pattern matching in Ruby and one of my friends responded "Build it!"
|
27
25
|
So I did. And here it is.
|
28
26
|
|
29
|
-
For fun I've also thrown in Erlang's sparsely documented [-behaviour](http://www.erlang.org/doc/design_principles/gen_server_concepts.html)
|
27
|
+
For fun I've also thrown in Erlang's sparsely documented [-behaviour](http://www.erlang.org/doc/design_principles/gen_server_concepts.html)
|
28
|
+
functionality plus a few other functions and constants I find useful.
|
30
29
|
|
31
30
|
### Goals
|
32
31
|
|
@@ -85,7 +84,23 @@ gem 'pattern-matching'
|
|
85
84
|
|
86
85
|
and run `bundle install` from your shell.
|
87
86
|
|
88
|
-
|
87
|
+
Once you've installed the gem you must `require` it in your project. Becuase this gem includes multiple features
|
88
|
+
that not all users may want, several `require` options are available:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
require 'behavior'
|
92
|
+
require 'behaviour' # alternate spelling
|
93
|
+
require 'pattern_matching'
|
94
|
+
require 'pattern_matching/functions'
|
95
|
+
```
|
96
|
+
|
97
|
+
If you want everything you can do that, too:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
require 'pattern_matching/all'
|
101
|
+
```
|
102
|
+
|
103
|
+
## PatternMatching
|
89
104
|
|
90
105
|
First, familiarize yourself with Erlang [pattern matching](http://learnyousomeerlang.com/syntax-in-functions#pattern-matching).
|
91
106
|
This gem may not make much sense if you don't understand how Erlang dispatches
|
@@ -306,11 +321,11 @@ in Ruby. Please read them. Please don't submit a bug report if you use a
|
|
306
321
|
`return` statement within your `defn` and your code blows up with a
|
307
322
|
[LocalJumpError](http://ruby-doc.org/core-2.0/LocalJumpError.html).
|
308
323
|
|
309
|
-
|
324
|
+
### Examples
|
310
325
|
|
311
326
|
For more examples see the integration tests in *spec/integration_spec.rb*.
|
312
327
|
|
313
|
-
|
328
|
+
#### Simple Functions
|
314
329
|
|
315
330
|
This example is based on [Syntax in defnctions: Pattern Matching](http://learnyousomeerlang.com/syntax-in-defnctions) in [Learn You Some Erlang for Great Good!](http://learnyousomeerlang.com/).
|
316
331
|
|
@@ -349,7 +364,7 @@ class Foo
|
|
349
364
|
end
|
350
365
|
```
|
351
366
|
|
352
|
-
|
367
|
+
#### Simple Functions with Overloading
|
353
368
|
|
354
369
|
This example is based on [Syntax in defnctions: Pattern Matching](http://learnyousomeerlang.com/syntax-in-defnctions) in [Learn You Some Erlang for Great Good!](http://learnyousomeerlang.com/).
|
355
370
|
|
@@ -394,7 +409,7 @@ class Foo
|
|
394
409
|
end
|
395
410
|
```
|
396
411
|
|
397
|
-
|
412
|
+
#### Constructor Overloading
|
398
413
|
|
399
414
|
```ruby
|
400
415
|
require 'pattern_matching'
|
@@ -407,7 +422,7 @@ class Foo
|
|
407
422
|
end
|
408
423
|
```
|
409
424
|
|
410
|
-
|
425
|
+
#### Matching by Class/Datatype
|
411
426
|
|
412
427
|
```ruby
|
413
428
|
require 'pattern_matching'
|
@@ -430,7 +445,7 @@ class Foo
|
|
430
445
|
end
|
431
446
|
```
|
432
447
|
|
433
|
-
|
448
|
+
#### Matching a Hash Parameter
|
434
449
|
|
435
450
|
```ruby
|
436
451
|
require 'pattern_matching'
|
@@ -473,7 +488,7 @@ foo.hashable({bar: :baz}) #=> {bar: :baz}
|
|
473
488
|
foo.hashable({}) #=> :empty
|
474
489
|
```
|
475
490
|
|
476
|
-
|
491
|
+
#### Variable Length Argument Lists with ALL
|
477
492
|
|
478
493
|
```ruby
|
479
494
|
defn(:all, :one, ALL) { |args|
|
@@ -498,7 +513,7 @@ foo.all('a', 'bee', :see) #=> ['a', 'bee', :see]
|
|
498
513
|
foo.all() #=> NoMethodError: no method `all` matching [] found for class Foo
|
499
514
|
```
|
500
515
|
|
501
|
-
|
516
|
+
#### Guard Clauses
|
502
517
|
|
503
518
|
These examples are based on [Syntax in defnctions: Pattern Matching](http://learnyousomeerlang.com/syntax-in-defnctions)
|
504
519
|
in [Learn You Some Erlang for Great Good!](http://learnyousomeerlang.com/).
|
@@ -541,9 +556,9 @@ defn(:wrong_age, _) {
|
|
541
556
|
}
|
542
557
|
```
|
543
558
|
|
544
|
-
|
559
|
+
## Behavior
|
545
560
|
|
546
|
-
The `behavior` functionality is not
|
561
|
+
The `behavior` functionality is not imported by default. It requires a separate `require` statement:
|
547
562
|
|
548
563
|
```ruby
|
549
564
|
require 'behavior'
|
@@ -641,6 +656,31 @@ foo.behaves_as?(:bogus) #=> false
|
|
641
656
|
'foo'.behaves_as? :gen_foo #=> false
|
642
657
|
```
|
643
658
|
|
659
|
+
## Functions
|
660
|
+
|
661
|
+
Convenience functions are not imported by default. It require a separate `require` statement:
|
662
|
+
|
663
|
+
```ruby
|
664
|
+
require 'pattern_matching/functions'
|
665
|
+
```
|
666
|
+
|
667
|
+
```ruby
|
668
|
+
Infinity #=> Infinity
|
669
|
+
NaN #=> NaN
|
670
|
+
|
671
|
+
repl? #=> true when called under irb, pry, bundle console, or rails console
|
672
|
+
|
673
|
+
safe(1, 2){|a, b| a + b} #=> 3
|
674
|
+
safe{ eval 'puts "Hello World!"' } #=> SecurityError: Insecure operation
|
675
|
+
|
676
|
+
pp_s [1,2,3,4] #=> "[1, 2, 3, 4]\n" props to Rha7
|
677
|
+
|
678
|
+
delta(-1, 1) #=> 2
|
679
|
+
delta({count: -1}, {count: 1}){|item| item[:count]} #=> 2
|
680
|
+
```
|
681
|
+
|
682
|
+
This gives you access to a few constants and functions:
|
683
|
+
|
644
684
|
## Copyright
|
645
685
|
|
646
686
|
*PatternMatching* is Copyright © 2013 [Jerry D'Antonio](https://twitter.com/jerrydantonio).
|
data/lib/pattern_matching.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
module PatternMatching
|
2
2
|
|
3
|
-
VERSION = '0.4.0'
|
4
|
-
|
5
3
|
UNBOUND = Class.new
|
6
4
|
ALL = Class.new
|
7
5
|
|
@@ -64,7 +62,7 @@ module PatternMatching
|
|
64
62
|
matchers = clazz.__function_pattern_matches__[func]
|
65
63
|
return [:nodef, nil] if matchers.nil?
|
66
64
|
|
67
|
-
|
65
|
+
match = matchers.detect do |matcher|
|
68
66
|
if PatternMatching.__match_pattern__(args, matcher.first)
|
69
67
|
if matcher.last.nil?
|
70
68
|
true # no guard clause
|
@@ -74,11 +72,7 @@ module PatternMatching
|
|
74
72
|
end
|
75
73
|
end
|
76
74
|
|
77
|
-
|
78
|
-
return [:nomatch, nil]
|
79
|
-
else
|
80
|
-
return [:ok, matchers[index]]
|
81
|
-
end
|
75
|
+
return (match ? [:ok, match] : [:nomatch, nil])
|
82
76
|
end
|
83
77
|
|
84
78
|
protected
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'pp'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
Infinity = 1/0.0 unless defined?(Infinity)
|
5
|
+
NaN = 0/0.0 unless defined?(NaN)
|
6
|
+
|
7
|
+
module Kernel
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def repl?
|
12
|
+
return ($0 == 'irb' || $0 == 'pry' || $0 == 'script/rails' || !!($0 =~ /bin\/bundle$/))
|
13
|
+
end
|
14
|
+
module_function :repl?
|
15
|
+
|
16
|
+
def safe(*args, &block)
|
17
|
+
raise ArgumentError.new('no block given') unless block_given?
|
18
|
+
result = nil
|
19
|
+
t = Thread.new do
|
20
|
+
$SAFE = 3
|
21
|
+
result = self.instance_exec(*args, &block)
|
22
|
+
end
|
23
|
+
t.join
|
24
|
+
return result
|
25
|
+
end
|
26
|
+
module_function :safe
|
27
|
+
|
28
|
+
# http://rhaseventh.blogspot.com/2008/07/ruby-and-rails-how-to-get-pp-pretty.html
|
29
|
+
def pp_s(*objs)
|
30
|
+
s = StringIO.new
|
31
|
+
objs.each {|obj|
|
32
|
+
PP.pp(obj, s)
|
33
|
+
}
|
34
|
+
s.rewind
|
35
|
+
s.read
|
36
|
+
end
|
37
|
+
module_function :pp_s
|
38
|
+
|
39
|
+
# Compute the difference (delta) between two values.
|
40
|
+
#
|
41
|
+
# When a block is given the block will be applied to both arguments.
|
42
|
+
# Using a block in this way allows computation against a specific field
|
43
|
+
# in a data set of hashes or objects.
|
44
|
+
#
|
45
|
+
# @yield iterates over each element in the data set
|
46
|
+
# @yieldparam item each element in the data set
|
47
|
+
#
|
48
|
+
# @param [Object] v1 the first value
|
49
|
+
# @param [Object] v2 the second value
|
50
|
+
#
|
51
|
+
# @return [Float] positive value representing the difference
|
52
|
+
# between the two parameters
|
53
|
+
def delta(v1, v2)
|
54
|
+
if block_given?
|
55
|
+
v1 = yield(v1)
|
56
|
+
v2 = yield(v2)
|
57
|
+
end
|
58
|
+
return (v1 - v2).abs
|
59
|
+
end
|
60
|
+
module_function :delta
|
61
|
+
|
62
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pattern-matching
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jerry D'Antonio
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-06-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -26,6 +26,9 @@ dependencies:
|
|
26
26
|
version: '0'
|
27
27
|
description: |2
|
28
28
|
A gem for adding Erlang-style function/method overloading through pattern matching to Ruby classes.
|
29
|
+
|
30
|
+
For fun I've also thrown in Erlang's sparsely documented -behaviour
|
31
|
+
functionality plus a few other functions and constants I find useful.
|
29
32
|
email: jerry.dantonio@gmail.com
|
30
33
|
executables: []
|
31
34
|
extensions: []
|
@@ -37,6 +40,9 @@ files:
|
|
37
40
|
- LICENSE
|
38
41
|
- lib/behavior.rb
|
39
42
|
- lib/behaviour.rb
|
43
|
+
- lib/pattern_matching/all.rb
|
44
|
+
- lib/pattern_matching/functions.rb
|
45
|
+
- lib/pattern_matching/version.rb
|
40
46
|
- lib/pattern_matching.rb
|
41
47
|
- spec/behavior_spec.rb
|
42
48
|
- spec/integration_spec.rb
|