pattern-match 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 7472cd3f781f3de13a150b3f7451f1b6c7acbebc
4
- data.tar.gz: a400bedeed0e8e87ec9a0c56e283184083f34988
2
+ SHA256:
3
+ metadata.gz: 2cd3ccf69d626d2302494e2393796dfb571b06aace34f29def21dde39021e852
4
+ data.tar.gz: 8cfb00569ac023f7e76d1ae165a4f0ca2c43fa3afb82eb1e17dce30012d8ca4a
5
5
  SHA512:
6
- metadata.gz: c94fa67c645a45c2e67d3c02a2e86e0612a61749ccbc9098469d784e5afa65891d9dc88311f3ae4b73a27c1fa252d0db31789ad4739f96840100a3633a95f98d
7
- data.tar.gz: 3822c0b6c0d94237c589e1f15aa93818c399ffb677bdfce95c6e8ae5082ddd4fb51e5d00b35222e044b2bd9b3041319bbae5ad10f085d36bcf61e09e553932e9
6
+ metadata.gz: 575702a7996ba07a2a0b8bf3cbc5fd83035298f9ecec13fffb51652b8b6f92742df823d59bcfdd53cba8ebcb8e7861876215ea413573416c2aa167987b4257f2
7
+ data.tar.gz: 40218d0fbd2c075b6b2a0660febd458d04d5e379b0fdc06ca6c7588207091297fb2952eb7a2683ba686e154777a9fd6baf005feda34b8d2e303544764699f92f
@@ -0,0 +1,35 @@
1
+ on: [ push, pull_request ]
2
+
3
+ jobs:
4
+ ruby-versions:
5
+ uses: ruby/actions/.github/workflows/ruby_versions.yml@master
6
+ with:
7
+ engine: cruby
8
+ min_version: 2.4
9
+ test:
10
+ needs: ruby-versions
11
+ name: >-
12
+ Test (${{ matrix.ruby-version }} / ${{ matrix.os }} / DISABLE_REFINEMENTS: ${{ matrix.DISABLE_REFINEMENTS }})
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ ruby-version: ${{ fromJson(needs.ruby-versions.outputs.versions) }}
17
+ os: [ ubuntu-latest, macos-latest ]
18
+ exclude:
19
+ - { os: macos-latest, ruby-version: 2.4 }
20
+ - { os: macos-latest, ruby-version: 2.5 }
21
+ DISABLE_REFINEMENTS: [ 1, 0 ]
22
+ runs-on: ${{ matrix.os }}
23
+ env:
24
+ DISABLE_REFINEMENTS: ${{ matrix.DISABLE_REFINEMENTS }}
25
+ continue-on-error: ${{ matrix.ruby-version == 'head' }}
26
+ steps:
27
+ - uses: actions/checkout@v2
28
+ - name: Set up Ruby
29
+ uses: ruby/setup-ruby@v1
30
+ with:
31
+ ruby-version: ${{ matrix.ruby-version }}
32
+ bundler-cache: true
33
+ - name: Run the test suite
34
+ run: |
35
+ bundle exec rake
data/BSDL CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (C) 2012-2015 Kazuki Tsujimoto, All rights reserved.
1
+ Copyright (C) 2012 Kazuki Tsujimoto
2
2
 
3
3
  Redistribution and use in source and binary forms, with or without
4
4
  modification, are permitted provided that the following conditions
data/COPYING CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (C) 2012-2015 Kazuki Tsujimoto, All rights reserved.
1
+ Copyright (C) 2012 Kazuki Tsujimoto
2
2
 
3
3
  You can redistribute it and/or modify it under either the terms of the
4
4
  2-clause BSDL (see the file BSDL), or the conditions below:
data/README.rdoc CHANGED
@@ -48,14 +48,14 @@ An ordinary object is a value pattern.
48
48
  The pattern matches an object such that <code>pattern === object</code>.
49
49
 
50
50
  match(0) do
51
- with(Fixnum) { :match } #=> :match
51
+ with(Integer) { :match } #=> :match
52
52
  end
53
53
 
54
54
  If you want to use an another method of matching,
55
55
  you have to use <code>_</code> as follows.
56
56
 
57
57
  match(0) do
58
- with(_(Fixnum, :==)) { :match }
58
+ with(_(Integer, :==)) { :match }
59
59
  end #=> NoMatchingPatternError
60
60
 
61
61
  === Deconstructor
@@ -112,7 +112,7 @@ all objects bound to variable must be equal.
112
112
  <code>And</code>, <code>Or</code>, <code>Not</code> return and/or/not pattern.
113
113
 
114
114
  match([0, [1]]) do
115
- with(_[a & Fixnum, ! (_[2] | _[3])]) { a } #=> 0
115
+ with(_[a & Integer, ! (_[2] | _[3])]) { a } #=> 0
116
116
  end
117
117
 
118
118
  match(0) do
@@ -129,7 +129,7 @@ They are equivalent to <code>*</code>, <code>*?</code>,
129
129
  You can write as <code>*pattern</code> instead of <code>pattern, \___</code>.
130
130
 
131
131
  match([:a, 0, :b, :c]) do
132
- with(_[a & Symbol, ___, b & Fixnum, c & Symbol, ___]) do
132
+ with(_[a & Symbol, ___, b & Integer, c & Symbol, ___]) do
133
133
  a #=> [:a]
134
134
  b #=> 0
135
135
  c #=> [:b, :c]
@@ -142,7 +142,7 @@ You can write as <code>*pattern</code> instead of <code>pattern, \___</code>.
142
142
  It is equivalent to <code>()</code> in regular expression.
143
143
 
144
144
  match([:a, 0, :b, 1]) do
145
- with(_[Seq(a & Symbol, b & Fixnum), ___]) do
145
+ with(_[Seq(a & Symbol, b & Integer), ___]) do
146
146
  a #=> [:a, :b]
147
147
  b #=> [0, 1]
148
148
  end
@@ -154,6 +154,7 @@ It is equivalent to <code>()</code> in regular expression.
154
154
  * KeyMatcher
155
155
  * Hash.()
156
156
  * AttributeMatcher
157
+ * fallthrough (requires binding_of_caller gem)
157
158
 
158
159
  To use experimental features, you must also require 'pattern-match/experimental'.
159
160
  See source code for more details.
@@ -251,8 +252,19 @@ Pattern guard can be specified as a second argument to <code>with</code>.
251
252
  end
252
253
  end
253
254
 
254
- * {RubyTextProcessing}[https://code.google.com/p/tokland/wiki/RubyTextProcessing]
255
+ match([]) do
256
+ with(_[]) do
257
+ opts = {}
258
+ fallthrough
259
+ end
260
+ with(_[opts & Hash]) do
261
+ opts #=> {}
262
+ end
263
+ end
264
+
265
+ * {tokland/RubyTextProcessing}[https://github.com/tokland/tokland/wiki/RubyTextProcessing]
255
266
  * {yhara/tapl-ruby}[https://github.com/yhara/tapl-ruby]
267
+ * {k-tsj/power_assert}[https://github.com/k-tsj/power_assert/blob/8e9e0399a032936e3e3f3c1f06e0d038565f8044/lib/power_assert.rb]
256
268
 
257
269
  == Reference
258
270
  * {Pattern Matching in Ruby (at Sapporo RubyKaigi 2012) // Speaker Deck}[https://speakerdeck.com/k_tsj/patternmatchinginruby]
@@ -264,5 +276,3 @@ Pattern guard can be specified as a second argument to <code>with</code>.
264
276
  $ bundle install --path vendor/bundle
265
277
  $ bundle exec rake test (or "bundle exec rake")
266
278
  $ bundle exec rake build
267
-
268
- == Travis Build Status {<img src="https://secure.travis-ci.org/k-tsj/pattern-match.png"/>}[http://travis-ci.org/k-tsj/pattern-match]
@@ -473,10 +473,17 @@ module PatternMatch
473
473
  end
474
474
  end
475
475
 
476
+ FALLTHROUGH_TAG = Object.new
477
+
476
478
  class Env < BasicObject
477
479
  def initialize(ctx, val)
478
480
  @ctx = ctx
479
481
  @val = val
482
+ @fallthrough_quasibinding = nil
483
+ end
484
+
485
+ def fallthrough_called?
486
+ !! @fallthrough_quasibinding
480
487
  end
481
488
 
482
489
  private
@@ -489,9 +496,22 @@ module PatternMatch
489
496
  pat.append(PatternCondition.new { with_quasibinding(ctx, pat.quasibinding, &guard_proc) })
490
497
  end
491
498
  pat.validate
492
- if pat.match([@val])
493
- ret = with_quasibinding(ctx, pat.quasibinding, &block)
499
+ if fallthrough_called?
500
+ ret = with_quasibinding(ctx, pat.quasibinding.merge(@fallthrough_quasibinding), &block)
494
501
  ::Kernel.throw(self, ret)
502
+ end
503
+ if pat.match([@val])
504
+ ret = nil
505
+ fallthrough_called = true
506
+ block_quasibinding = ::Kernel.catch(::PatternMatch::FALLTHROUGH_TAG) do
507
+ ret = with_quasibinding(ctx, pat.quasibinding, &block)
508
+ fallthrough_called = false
509
+ end
510
+ if fallthrough_called
511
+ @fallthrough_quasibinding = pat.quasibinding.merge(block_quasibinding)
512
+ else
513
+ ::Kernel.throw(self, ret)
514
+ end
495
515
  else
496
516
  nil
497
517
  end
@@ -638,6 +658,9 @@ module PatternMatch
638
658
  env = Env.new(self, val)
639
659
  catch(env) do
640
660
  env.instance_eval(&block)
661
+ if env.fallthrough_called?
662
+ raise PatternMatchError, 'cannot fallthrough final case in match'
663
+ end
641
664
  raise NoMatchingPatternError
642
665
  end
643
666
  end
@@ -20,7 +20,11 @@ module PatternMatch
20
20
  end
21
21
 
22
22
  refine Class do
23
- include PatternMatch::Deconstructable
23
+ if respond_to?(:import_methods, true)
24
+ import_methods PatternMatch::Deconstructable
25
+ else
26
+ include PatternMatch::Deconstructable
27
+ end
24
28
 
25
29
  def deconstruct(val)
26
30
  raise NotImplementedError, "need to define `#{__method__}'"
@@ -69,7 +73,11 @@ module PatternMatch
69
73
  end
70
74
 
71
75
  refine Regexp do
72
- include PatternMatch::Deconstructable
76
+ if respond_to?(:import_methods, true)
77
+ import_methods PatternMatch::Deconstructable
78
+ else
79
+ include PatternMatch::Deconstructable
80
+ end
73
81
 
74
82
  def deconstruct(val)
75
83
  m = Regexp.new("\\A#{source}\\z", options).match(val.to_s)
@@ -62,6 +62,12 @@ module PatternMatch
62
62
  end
63
63
  end
64
64
 
65
+ refine Class do
66
+ if respond_to?(:import_methods, true)
67
+ import_methods PatternMatch::Deconstructable
68
+ end
69
+ end
70
+
65
71
  module AttributeMatcher
66
72
  def self.included(klass)
67
73
  class << klass
@@ -185,4 +191,18 @@ class Object
185
191
  Kernel.eval("with(#{pattern}) { self }", Kernel.binding)
186
192
  end
187
193
  end
194
+
195
+ begin
196
+ require 'binding_of_caller'
197
+
198
+ private
199
+
200
+ def fallthrough
201
+ b = binding.of_caller(1)
202
+ vars = b.eval('local_variables')
203
+ quasibinding = Hash[*vars.map {|i| [i, b.local_variable_get(i)] }.flatten(1)]
204
+ throw PatternMatch::FALLTHROUGH_TAG, quasibinding
205
+ end
206
+ rescue LoadError
207
+ end
188
208
  end
@@ -1,3 +1,3 @@
1
1
  module PatternMatch
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
data/lib/pattern-match.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # pattern-match.rb
2
2
  #
3
- # Copyright (C) 2012-2015 Kazuki Tsujimoto, All rights reserved.
3
+ # Copyright (C) 2012 Kazuki Tsujimoto
4
4
 
5
5
  require 'pattern-match/version'
6
6
  require 'pattern-match/deconstructor'
@@ -22,5 +22,4 @@ Gem::Specification.new do |s|
22
22
 
23
23
  s.add_development_dependency 'test-unit'
24
24
  s.add_development_dependency 'rake'
25
- s.add_development_dependency 'simplecov'
26
25
  end
@@ -1,11 +1,11 @@
1
1
  require_relative 'helper'
2
2
  require 'test-unit'
3
- if ENV['DISABLE_REFINEMENTS']
4
- require 'pattern-match/disable_refinements'
3
+ if ENV['DISABLE_REFINEMENTS'].to_i.zero?
5
4
  require 'pattern-match'
5
+ using PatternMatch
6
6
  else
7
+ require 'pattern-match/disable_refinements'
7
8
  require 'pattern-match'
8
- using PatternMatch
9
9
  end
10
10
  begin
11
11
  require 'pattern-match/experimental'
@@ -102,10 +102,10 @@ class TestExperimental < Test::Unit::TestCase
102
102
  end
103
103
 
104
104
  def test_object_assert_pattern
105
- assert_equal([0], [0].assert_pattern('_[Fixnum]'))
106
- assert_equal([0], [0].assert_pattern('_[a & Fixnum], guard { a.even? }'))
105
+ assert_equal([0], [0].assert_pattern('_[Integer]'))
106
+ assert_equal([0], [0].assert_pattern('_[a & Integer], guard { a.even? }'))
107
107
  assert_raises(PatternMatch::NoMatchingPatternError) do
108
- [0, 1].assert_pattern('_[Fixnum]')
108
+ [0, 1].assert_pattern('_[Integer]')
109
109
  end
110
110
  end
111
111
 
@@ -145,4 +145,28 @@ class TestExperimental < Test::Unit::TestCase
145
145
  with(_) { flunk }
146
146
  end
147
147
  end
148
+
149
+ def test_fallthrough
150
+ omit unless respond_to?(:fallthrough, true)
151
+
152
+ match(0) do
153
+ with(a) do
154
+ b = 1
155
+ assert_equal 0, a
156
+ assert_equal 1, b
157
+ fallthrough
158
+ end
159
+ with(_[a, c]) do
160
+ assert_equal 0, a
161
+ assert_equal 1, b
162
+ assert_nil c
163
+ end
164
+ end
165
+
166
+ assert_raises(PatternMatch::PatternMatchError) do
167
+ match(0) do
168
+ with(_) { fallthrough }
169
+ end
170
+ end
171
+ end
148
172
  end if defined? PatternMatch::AttributeMatcher
@@ -1,11 +1,11 @@
1
1
  require_relative 'helper'
2
2
  require 'test-unit'
3
- if ENV['DISABLE_REFINEMENTS']
4
- require 'pattern-match/disable_refinements'
3
+ if ENV['DISABLE_REFINEMENTS'].to_i.zero?
5
4
  require 'pattern-match'
5
+ using PatternMatch
6
6
  else
7
+ require 'pattern-match/disable_refinements'
7
8
  require 'pattern-match'
8
- using PatternMatch
9
9
  end
10
10
 
11
11
  class TestStandard < Test::Unit::TestCase
@@ -17,7 +17,7 @@ class TestStandard < Test::Unit::TestCase
17
17
  with(nil) { flunk }
18
18
  with(_[]) { flunk }
19
19
  with(_[a, 0, 0, b]) { flunk }
20
- with(_[a, Fixnum , 2, b]) do
20
+ with(_[a, Integer , 2, b]) do
21
21
  assert_equal(this, self)
22
22
  assert_equal(0, a)
23
23
  assert_equal(3, b)
@@ -125,8 +125,8 @@ class TestStandard < Test::Unit::TestCase
125
125
  end
126
126
 
127
127
  def test_uscore
128
- match([0, 1, Fixnum]) do
129
- with(_[_, ! _(Float), _(Fixnum, :==)]) do
128
+ match([0, 1, Integer]) do
129
+ with(_[_, ! _(Float), _(Integer, :==)]) do
130
130
  assert_raises(NameError) { _ }
131
131
  end
132
132
  with(_) { flunk }
@@ -277,7 +277,7 @@ class TestStandard < Test::Unit::TestCase
277
277
  end
278
278
 
279
279
  match([[0, 1, :a, 'A'], [2, :b, :c, 'B'], ['C'], 3]) do
280
- with(_[_[a & Fixnum, ___, b & Symbol, ___, c], ___, d]) do
280
+ with(_[_[a & Integer, ___, b & Symbol, ___, c], ___, d]) do
281
281
  assert_equal([[0, 1], [2], []], a)
282
282
  assert_equal([[:a], [:b, :c], []], b)
283
283
  assert_equal(['A', 'B', 'C'], c)
@@ -287,7 +287,7 @@ class TestStandard < Test::Unit::TestCase
287
287
  end
288
288
 
289
289
  match([0, 1, 2, 4, 5]) do
290
- with(_[*a, b & Fixnum, __2, *c], guard { b.all?(&:even?) }) do
290
+ with(_[*a, b & Integer, __2, *c], guard { b.all?(&:even?) }) do
291
291
  assert_equal([0, 1], a)
292
292
  assert_equal([2, 4], b)
293
293
  assert_equal([5], c)
@@ -345,7 +345,7 @@ class TestStandard < Test::Unit::TestCase
345
345
  end
346
346
 
347
347
  match([0, :a, 1, 2, :b, 3]) do
348
- with(_[Seq(a & Fixnum, b & Symbol, c & Fixnum), ___]) do
348
+ with(_[Seq(a & Integer, b & Symbol, c & Integer), ___]) do
349
349
  assert_equal([0, 2], a)
350
350
  assert_equal([:a, :b], b)
351
351
  assert_equal([1, 3], c)
@@ -354,12 +354,12 @@ class TestStandard < Test::Unit::TestCase
354
354
  end
355
355
 
356
356
  match([0, :a, 1, 2, :b, :c]) do
357
- with(_[Seq(a & Fixnum, b & Symbol, c & Fixnum), ___]) { flunk }
357
+ with(_[Seq(a & Integer, b & Symbol, c & Integer), ___]) { flunk }
358
358
  with(_) { pass }
359
359
  end
360
360
 
361
361
  match([0, 1, :a, 2, 3, :b, 4, 5]) do
362
- with(_[a, Seq(b & Fixnum, c & Symbol, d & Fixnum), ___, e]) do
362
+ with(_[a, Seq(b & Integer, c & Symbol, d & Integer), ___, e]) do
363
363
  assert_equal(0, a)
364
364
  assert_equal([1, 3], b)
365
365
  assert_equal([:a, :b], c)
@@ -422,7 +422,7 @@ class TestStandard < Test::Unit::TestCase
422
422
 
423
423
  assert_raises(NotImplementedError) do
424
424
  match([0]) do
425
- with(_[Seq(a & Fixnum, ___), ___]) {}
425
+ with(_[Seq(a & Integer, ___), ___]) {}
426
426
  end
427
427
  end
428
428
  end
@@ -632,16 +632,16 @@ class TestStandard < Test::Unit::TestCase
632
632
  end
633
633
 
634
634
  def test_refinements
635
- if ENV['DISABLE_REFINEMENTS']
636
- assert_kind_of(PatternMatch.const_get(:Pattern), eval_in_unrefined_scope('Class.()'))
637
- assert_equal(0, eval_in_unrefined_scope('match(0) { with(_) { 0 } }'))
638
- else
635
+ if ENV['DISABLE_REFINEMENTS'].to_i.zero?
639
636
  assert_raises(NoMethodError) do
640
637
  eval_in_unrefined_scope('Class.()')
641
638
  end
642
639
  assert_raises(NoMethodError) do
643
640
  eval_in_unrefined_scope('match(0) { with(_) { 0 } }')
644
641
  end
642
+ else
643
+ assert_kind_of(PatternMatch.const_get(:Pattern), eval_in_unrefined_scope('Class.()'))
644
+ assert_equal(0, eval_in_unrefined_scope('match(0) { with(_) { 0 } }'))
645
645
  end
646
646
  end
647
647
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pattern-match
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kazuki Tsujimoto
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-27 00:00:00.000000000 Z
11
+ date: 2024-05-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: test-unit
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: simplecov
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
41
  description: A pattern matching library.
56
42
  email:
57
43
  - kazuki@callcc.net
@@ -60,8 +46,8 @@ extensions: []
60
46
  extra_rdoc_files:
61
47
  - README.rdoc
62
48
  files:
49
+ - ".github/workflows/ci.yml"
63
50
  - ".gitignore"
64
- - ".travis.yml"
65
51
  - BSDL
66
52
  - COPYING
67
53
  - Gemfile
@@ -83,7 +69,7 @@ licenses:
83
69
  - 2-clause BSDL
84
70
  - Ruby's
85
71
  metadata: {}
86
- post_install_message:
72
+ post_install_message:
87
73
  rdoc_options:
88
74
  - "--main"
89
75
  - README.rdoc
@@ -100,9 +86,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
100
86
  - !ruby/object:Gem::Version
101
87
  version: '0'
102
88
  requirements: []
103
- rubyforge_project:
104
- rubygems_version: 2.4.6
105
- signing_key:
89
+ rubygems_version: 3.4.19
90
+ signing_key:
106
91
  specification_version: 4
107
92
  summary: A pattern matching library
108
- test_files: []
93
+ test_files:
94
+ - test/helper.rb
95
+ - test/test_experimental.rb
96
+ - test/test_standard.rb
data/.travis.yml DELETED
@@ -1,26 +0,0 @@
1
- rvm:
2
- - 1.9.3
3
- - 2.0.0
4
- - 2.1
5
- - 2.2
6
- - ruby-head
7
- - jruby-19mode
8
- env:
9
- - TEST="test/test_*"
10
- - TEST="test/test_standard.rb"
11
- - DISABLE_REFINEMENTS=1 TEST="test/test_*"
12
- - DISABLE_REFINEMENTS=1 TEST="test/test_standard.rb"
13
- matrix:
14
- exclude:
15
- - rvm: 1.9.3
16
- env: TEST="test/test_*"
17
- - rvm: 1.9.3
18
- env: TEST="test/test_standard.rb"
19
- - rvm: jruby-19mode
20
- env: TEST="test/test_*"
21
- - rvm: jruby-19mode
22
- env: TEST="test/test_standard.rb"
23
- - rvm: jruby-19mode
24
- env: DISABLE_REFINEMENTS=1 TEST="test/test_*"
25
- allow_failures:
26
- - rvm: ruby-head