facets 3.2.0 → 3.2.2
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/HISTORY.md +65 -2
- data/README.md +17 -31
- data/lib/core/facets/array.rb +1 -1
- data/lib/core/facets/binding/caller.rb +8 -4
- data/lib/core/facets/dir.rb +1 -1
- data/lib/core/facets/enumerable.rb +2 -2
- data/lib/core/facets/essentials.rb +3 -3
- data/lib/core/facets/file.rb +1 -1
- data/lib/core/facets/hash.rb +1 -1
- data/lib/core/facets/kernel/as.rb +2 -2
- data/lib/core/facets/matchdata.rb +1 -1
- data/lib/core/facets/numeric.rb +2 -2
- data/lib/core/facets/object.rb +2 -2
- data/lib/core/facets/process.rb +1 -1
- data/lib/core/facets/range/intersection.rb +2 -1
- data/lib/core/facets/range/overlap.rb +19 -0
- data/lib/core/facets/range.rb +1 -0
- data/lib/core/facets/symbol.rb +1 -1
- data/lib/core/facets/version.rb +1 -1
- data/lib/standard/facets/opendsl.rb +33 -0
- data/lib/standard/facets/ostruct.rb +10 -0
- data/lib/standard/facets/pic.rb +173 -0
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: da62aa5e36dc4d4fbe19984071e7f4bf38acc53a7812c285a50a36b714115f23
|
|
4
|
+
data.tar.gz: 7244c28aff76e1073f723148e6a9e3006246a26cd59c047dab8a2d8f765a3e3d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: acc7199da1618757142fede6aece2bdbc324a7d8d95525f4ff40a0ef1085484ec42d3727eb3adcd65be3eccfa210e599d1488dafde8640b04375947b6df96c7b
|
|
7
|
+
data.tar.gz: 0e561c34ccac85af4fa6b1ce7c28a2396d4326ff75917b6fde31c6618be7cdb46c959fec59454b1a6b4df5a2c3a6812cae72c68ce5bd0a96714afa1dc43bd344
|
data/HISTORY.md
CHANGED
|
@@ -1,5 +1,64 @@
|
|
|
1
1
|
# Facets Release History
|
|
2
2
|
|
|
3
|
+
## 3.2.2 / 2026-06-15
|
|
4
|
+
|
|
5
|
+
Patch release with cross-version fixes surfaced by CI on Ruby 3.1–3.4.
|
|
6
|
+
|
|
7
|
+
Changes:
|
|
8
|
+
|
|
9
|
+
* Bug Fixes
|
|
10
|
+
|
|
11
|
+
* Fix `Range.intersection` on Ruby 3.1 and 3.2. It relied on `Range#overlap?`,
|
|
12
|
+
which only exists in Ruby 3.3+; replaced with an explicit overlap test that
|
|
13
|
+
works on any Ruby and any comparable element type.
|
|
14
|
+
* Restore `Range#overlap?` for Ruby < 3.3. It was dropped in 3.2.0 (since Ruby
|
|
15
|
+
3.3 added a native one), which left 3.1/3.2 users without it. It is now
|
|
16
|
+
defined only when missing, so it never replaces the built-in on 3.3+.
|
|
17
|
+
* Widen `Binding#caller` and `Binding#caller_locations` to accept the optional
|
|
18
|
+
`length` argument (matching `Kernel#caller`/`#caller_locations`). The
|
|
19
|
+
too-narrow arity raised `ArgumentError` when `warn(uplevel:)` dispatched to
|
|
20
|
+
them under JRuby's pure-Ruby `warn`.
|
|
21
|
+
|
|
22
|
+
* Internal
|
|
23
|
+
|
|
24
|
+
* Add `ostruct` to the test dependencies. `ostruct` is deprecated in Ruby 3.4
|
|
25
|
+
and removed from the default gems in Ruby 3.5, so it must be declared
|
|
26
|
+
explicitly. Facets' OpenStruct extensions (`require 'facets/ostruct'`) still
|
|
27
|
+
work, but now require the `ostruct` gem to be installed on Ruby 3.5+. These
|
|
28
|
+
extensions may be divested from Facets in a future release.
|
|
29
|
+
|
|
30
|
+
## 3.2.1 / 2026-06-14
|
|
31
|
+
|
|
32
|
+
Patch release that fixes the broken 3.2.0 release. 3.2.0 shipped with stale
|
|
33
|
+
`require_relative` lines pointing at method files that had been removed or
|
|
34
|
+
renamed, so `require 'facets'` raised `LoadError`. This restores loadability
|
|
35
|
+
and adds a regression guard so it cannot recur. (The breaking-change and
|
|
36
|
+
versioning concern raised in issue #314 is left for a future major release.)
|
|
37
|
+
|
|
38
|
+
Changes:
|
|
39
|
+
|
|
40
|
+
* New Features
|
|
41
|
+
|
|
42
|
+
* Add `OpenDSL` — build free-form, pluggable DSL modules from a block.
|
|
43
|
+
* Add `PIC` — COBOL-style edited-picture pattern matching as a simple
|
|
44
|
+
alternative to regular expressions.
|
|
45
|
+
|
|
46
|
+
* Bug Fixes
|
|
47
|
+
|
|
48
|
+
* Fix `LoadError` on `require 'facets'`: remove stale `require_relative`
|
|
49
|
+
lines left pointing at removed method files, and correct the
|
|
50
|
+
`hash/to_proc` -> `hash/setter` require after the rename.
|
|
51
|
+
(issues #312, #315; PR#313)
|
|
52
|
+
* Fix `range.rb` requiring the removed `range/overlap`. (PR#318)
|
|
53
|
+
* Stop `Kernel::As` from redefining `object_id`, which emitted a
|
|
54
|
+
"redefining 'object_id' may cause serious problems" warning on load.
|
|
55
|
+
(issue #310)
|
|
56
|
+
|
|
57
|
+
* Internal
|
|
58
|
+
|
|
59
|
+
* Add a load-path regression test that verifies every `require_relative`
|
|
60
|
+
target across the library resolves to an existing file.
|
|
61
|
+
|
|
3
62
|
## 3.2.0 / 2026-04-01
|
|
4
63
|
|
|
5
64
|
Modernization release targeting Ruby 3.1+. Cleans up long-standing
|
|
@@ -19,8 +78,12 @@ Changes:
|
|
|
19
78
|
* Add `Range.intersection` and `Range#intersection` for finding the shared
|
|
20
79
|
region of multiple ranges. Works with any comparable type.
|
|
21
80
|
* Add `Kernel#functor` — block-less method chaining via Functor, replaces `tap` override.
|
|
22
|
-
*
|
|
23
|
-
|
|
81
|
+
* Stop overriding `Hash#to_proc` and provide its behavior as `Hash#setter`
|
|
82
|
+
instead. Facets' version built a Proc that assigns the hash's key/value
|
|
83
|
+
pairs as attributes on a target object, which conflicted with Ruby's own
|
|
84
|
+
`Hash#to_proc` (added in 2.3, does key lookup). Facets now cedes `to_proc`
|
|
85
|
+
to Ruby; use `Hash#setter` for the attribute-assignment behavior. Also
|
|
86
|
+
renamed the option `response:` to `safe:` and fixed a receiver check.
|
|
24
87
|
* Consolidate `Array#arrange` and `Array#to_ranges`; `to_ranges` is now primary,
|
|
25
88
|
`arrange` and `rangify` are aliases. Now handles mixed ranges and values.
|
|
26
89
|
* Fix `Array#step` to start at index 0 (was n-1); add optional offset parameter.
|
data/README.md
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# Ruby Facets
|
|
2
2
|
|
|
3
|
-
[](
|
|
4
|
-
[](http://flattr.com/thing/324911/Rubyworks-Ruby-Development-Fund)
|
|
3
|
+
[](https://rubygems.org/gems/facets)
|
|
4
|
+
[](https://github.com/rubyworks/facets/actions/workflows/ci.yml)
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
*"ALL YOUR BASE ARE BELONG TO RUBY"*
|
|
@@ -10,7 +9,7 @@
|
|
|
10
9
|
|
|
11
10
|
## Introduction
|
|
12
11
|
|
|
13
|
-
Ruby Facets is the
|
|
12
|
+
Ruby Facets is the premier collection of general purpose method
|
|
14
13
|
extensions and standard additions for the Ruby programming language.
|
|
15
14
|
|
|
16
15
|
Facets houses the largest single collection of methods available for
|
|
@@ -28,11 +27,10 @@ to a wide variety of usecases.
|
|
|
28
27
|
|
|
29
28
|
## Resources
|
|
30
29
|
|
|
31
|
-
* Homepage:
|
|
32
|
-
* Report Bugs:
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* Source Code: http://github.com/rubyworks/facets
|
|
30
|
+
* Homepage: https://rubyworks.github.io/facets
|
|
31
|
+
* Report Bugs: https://github.com/rubyworks/facets/issues
|
|
32
|
+
* Wiki Pages: https://github.com/rubyworks/facets/wiki
|
|
33
|
+
* Source Code: https://github.com/rubyworks/facets
|
|
36
34
|
|
|
37
35
|
|
|
38
36
|
## Documentation
|
|
@@ -45,7 +43,7 @@ it is important to remain aware of the source location of particular
|
|
|
45
43
|
methods.
|
|
46
44
|
|
|
47
45
|
For better organized online documentation, generated to separate core
|
|
48
|
-
extensions from standard libraries, see the [Learn Facets](
|
|
46
|
+
extensions from standard libraries, see the [Learn Facets](https://rubyworks.github.io/facets/learn.html) page on the website for links to available documentation.
|
|
49
47
|
|
|
50
48
|
|
|
51
49
|
## Installation
|
|
@@ -64,16 +62,9 @@ The easiest way to install is via RubyGems.
|
|
|
64
62
|
|
|
65
63
|
$ gem install facets
|
|
66
64
|
|
|
67
|
-
###
|
|
65
|
+
### Requirements
|
|
68
66
|
|
|
69
|
-
Facets
|
|
70
|
-
Download and unpack the .tar.gz package and run setup.rb, like so:
|
|
71
|
-
|
|
72
|
-
$ tar -xvzf facets-2.x.x.tar.gz
|
|
73
|
-
$ cd facets-2.x.x
|
|
74
|
-
$ sudo setup.rb
|
|
75
|
-
|
|
76
|
-
Facets 2.8+ requires Ruby 1.8.7 or higher. Facets 3.0+ requires Ruby 2.0.0 or higher.
|
|
67
|
+
Facets 3.2+ requires Ruby 3.1 or higher.
|
|
77
68
|
|
|
78
69
|
|
|
79
70
|
## Mission
|
|
@@ -204,18 +195,13 @@ welcome. We want Ruby Facets to be of the highest quality.
|
|
|
204
195
|
|
|
205
196
|
## Development
|
|
206
197
|
|
|
207
|
-
Facets uses the [Lemon](
|
|
208
|
-
to handle unit testing, while [QED](
|
|
209
|
-
provide tested documentation.
|
|
198
|
+
Facets uses the [Lemon](https://rubyworks.github.io/lemon) testing framework
|
|
199
|
+
to handle unit testing, while [QED](https://rubyworks.github.io/qed) specifications
|
|
200
|
+
provide tested documentation. Run the test suite with [Rake](https://ruby.github.io/rake/):
|
|
201
|
+
|
|
202
|
+
$ rake test
|
|
210
203
|
|
|
211
|
-
|
|
212
|
-
build tools. Detroit is a life-cycle tool and Rulebow is a continuous integration tool. These
|
|
213
|
-
tools, via the `Assembly` and `Rulebook` scripts respectively, sometimes use other tools such
|
|
214
|
-
as [Mast](http://rubyworks.github.com/mast) and [Indexer](http://rubyworks.github.com/indexer).
|
|
215
|
-
In addition we support [Rake](https://ruby.github.io/rake/) and [Guard](http://guardgem.org/)
|
|
216
|
-
build tools, which most developers are familiar with.
|
|
217
|
-
Note, that while these build tools can be easy circumvented, the Mast and Indexer tools are
|
|
218
|
-
necessary to prepare Facets for release.
|
|
204
|
+
Continuous integration runs on GitHub Actions (see `.github/workflows/ci.yml`).
|
|
219
205
|
|
|
220
206
|
|
|
221
207
|
## Authors
|
|
@@ -263,5 +249,5 @@ code under such license, with appropriate credit citations.
|
|
|
263
249
|
|
|
264
250
|
Ruby Facets, Copyright (c) 2005 Rubyworks
|
|
265
251
|
|
|
266
|
-
Do you Ruby? (
|
|
252
|
+
Do you Ruby? (https://ruby-lang.org)
|
|
267
253
|
|
data/lib/core/facets/array.rb
CHANGED
|
@@ -43,7 +43,7 @@ require_relative 'array/split.rb'
|
|
|
43
43
|
require_relative 'array/squeeze.rb'
|
|
44
44
|
require_relative 'array/store.rb'
|
|
45
45
|
require_relative 'array/thru.rb'
|
|
46
|
-
require_relative 'array/to_h.rb'
|
|
46
|
+
#require_relative 'array/to_h.rb' # removed: now provided by Ruby
|
|
47
47
|
require_relative 'array/traverse.rb'
|
|
48
48
|
require_relative 'array/uniq_by.rb'
|
|
49
49
|
|
|
@@ -4,14 +4,18 @@ class Binding
|
|
|
4
4
|
|
|
5
5
|
# Returns the call stack, same format as Kernel#caller()
|
|
6
6
|
#
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
# Accepts the same `(start, length)` arguments as Kernel#caller.
|
|
8
|
+
#
|
|
9
|
+
def caller( start=0, length=nil )
|
|
10
|
+
length ? eval("caller(#{start}, #{length})") : eval("caller(#{start})")
|
|
9
11
|
end
|
|
10
12
|
|
|
11
13
|
# Returns the call stack, same format as Kernel#caller_locations()
|
|
12
14
|
#
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
# Accepts the same `(start, length)` arguments as Kernel#caller_locations.
|
|
16
|
+
#
|
|
17
|
+
def caller_locations( start=0, length=nil )
|
|
18
|
+
length ? eval("caller_locations(#{start}, #{length})") : eval("caller_locations(#{start})")
|
|
15
19
|
end
|
|
16
20
|
|
|
17
21
|
# Return the line number on which the binding was created.
|
data/lib/core/facets/dir.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require_relative 'dir/ascend.rb'
|
|
2
2
|
require_relative 'dir/descend.rb'
|
|
3
|
-
require_relative 'dir/each_child.rb'
|
|
3
|
+
#require_relative 'dir/each_child.rb' # removed: now provided by Ruby
|
|
4
4
|
require_relative 'dir/multiglob.rb'
|
|
5
5
|
require_relative 'dir/parent.rb'
|
|
6
6
|
require_relative 'dir/recurse.rb'
|
|
@@ -9,7 +9,7 @@ require_relative 'enumerable/every.rb'
|
|
|
9
9
|
require_relative 'enumerable/ewise.rb'
|
|
10
10
|
require_relative 'enumerable/exclude.rb'
|
|
11
11
|
require_relative 'enumerable/expand.rb'
|
|
12
|
-
require_relative 'enumerable/filter.rb'
|
|
12
|
+
#require_relative 'enumerable/filter.rb' # removed: now provided by Ruby
|
|
13
13
|
require_relative 'enumerable/find_yield.rb'
|
|
14
14
|
require_relative 'enumerable/frequency.rb'
|
|
15
15
|
require_relative 'enumerable/graph.rb'
|
|
@@ -31,7 +31,7 @@ require_relative 'enumerable/per.rb'
|
|
|
31
31
|
require_relative 'enumerable/purge.rb'
|
|
32
32
|
require_relative 'enumerable/recursively.rb'
|
|
33
33
|
require_relative 'enumerable/squeeze.rb'
|
|
34
|
-
require_relative 'enumerable/sum.rb'
|
|
34
|
+
#require_relative 'enumerable/sum.rb' # removed: now provided by Ruby
|
|
35
35
|
require_relative 'enumerable/value_by'
|
|
36
36
|
#require_relative 'enumerable/unassociate.rb'
|
|
37
37
|
require_relative 'enumerable/uniq_by.rb'
|
|
@@ -16,7 +16,7 @@ require_relative 'kernel/false'
|
|
|
16
16
|
require_relative 'kernel/true'
|
|
17
17
|
|
|
18
18
|
### Object
|
|
19
|
-
require_relative 'object/itself'
|
|
19
|
+
#require_relative 'object/itself' # removed: now provided by Ruby
|
|
20
20
|
|
|
21
21
|
### Array
|
|
22
22
|
require_relative 'array/delete_values'
|
|
@@ -37,11 +37,11 @@ require_relative 'enumerable/graph'
|
|
|
37
37
|
require_relative 'enumerable/value_by'
|
|
38
38
|
|
|
39
39
|
### File
|
|
40
|
-
require_relative 'file/write'
|
|
40
|
+
#require_relative 'file/write' # removed: now provided by Ruby
|
|
41
41
|
|
|
42
42
|
### Hash
|
|
43
43
|
require_relative 'hash/autonew'
|
|
44
|
-
require_relative 'hash/compact'
|
|
44
|
+
#require_relative 'hash/compact' # removed: now provided by Ruby
|
|
45
45
|
#require_relative 'hash/data'
|
|
46
46
|
require_relative 'hash/delete_values'
|
|
47
47
|
require_relative 'hash/except'
|
data/lib/core/facets/file.rb
CHANGED
|
@@ -11,6 +11,6 @@ require_relative 'file/rootname.rb'
|
|
|
11
11
|
require_relative 'file/sanitize.rb'
|
|
12
12
|
require_relative 'file/split_all.rb'
|
|
13
13
|
require_relative 'file/split_root.rb'
|
|
14
|
-
require_relative 'file/write.rb'
|
|
14
|
+
#require_relative 'file/write.rb' # removed: now provided by Ruby
|
|
15
15
|
require_relative 'file/writelines.rb'
|
|
16
16
|
|
data/lib/core/facets/hash.rb
CHANGED
|
@@ -40,7 +40,7 @@ require_relative 'hash/swap.rb'
|
|
|
40
40
|
require_relative 'hash/symbolize_keys.rb'
|
|
41
41
|
require_relative 'hash/to_mod.rb'
|
|
42
42
|
require_relative 'hash/to_options.rb'
|
|
43
|
-
require_relative 'hash/
|
|
43
|
+
require_relative 'hash/setter.rb'
|
|
44
44
|
require_relative 'hash/to_struct.rb'
|
|
45
45
|
require_relative 'hash/traverse.rb'
|
|
46
46
|
require_relative 'hash/update.rb'
|
|
@@ -99,8 +99,8 @@ class As #:nodoc:
|
|
|
99
99
|
private :cache
|
|
100
100
|
end
|
|
101
101
|
|
|
102
|
-
# Privatize all methods except #binding
|
|
103
|
-
private(*instance_methods.select { |m| m !~ /(^__|^\W|^binding$)/ })
|
|
102
|
+
# Privatize all methods except #binding, #object_id and operators.
|
|
103
|
+
private(*instance_methods.select { |m| m !~ /(^__|^\W|^binding$|^object_id$)/ })
|
|
104
104
|
|
|
105
105
|
def initialize(subject, ancestor)
|
|
106
106
|
@subject = subject
|
data/lib/core/facets/numeric.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
require_relative 'numeric/approx.rb'
|
|
2
2
|
require_relative 'numeric/distance.rb'
|
|
3
3
|
require_relative 'numeric/length.rb'
|
|
4
|
-
require_relative 'numeric/negative.rb'
|
|
5
|
-
require_relative 'numeric/positive.rb'
|
|
4
|
+
#require_relative 'numeric/negative.rb' # removed: now provided by Ruby
|
|
5
|
+
#require_relative 'numeric/positive.rb' # removed: now provided by Ruby
|
|
6
6
|
require_relative 'numeric/round_to.rb'
|
|
7
7
|
require_relative 'numeric/spacing.rb'
|
|
8
8
|
|
data/lib/core/facets/object.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# TODO: Is there a good reason for these to be here instead of in Kernel module?
|
|
2
2
|
require_relative 'object/clone.rb'
|
|
3
3
|
require_relative 'object/dup.rb'
|
|
4
|
-
require_relative 'object/itself.rb'
|
|
4
|
+
#require_relative 'object/itself.rb' # removed: now provided by Ruby
|
|
5
5
|
require_relative 'object/object_state.rb'
|
|
6
|
-
require_relative 'object/try_dup.rb'
|
|
6
|
+
#require_relative 'object/try_dup.rb' # removed
|
|
7
7
|
|
data/lib/core/facets/process.rb
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require_relative 'process/daemon.rb'
|
|
1
|
+
#require_relative 'process/daemon.rb' # removed: now provided by Ruby
|
|
2
2
|
|
|
@@ -21,7 +21,8 @@ class Range
|
|
|
21
21
|
def self.intersection(*ranges)
|
|
22
22
|
return nil if ranges.empty?
|
|
23
23
|
ranges.reduce do |result, r|
|
|
24
|
-
|
|
24
|
+
# Manual overlap test (Range#overlap? is Ruby 3.3+; Facets targets 3.1+).
|
|
25
|
+
return nil unless result.first <= r.last && r.first <= result.last
|
|
25
26
|
new_first = result.first > r.first ? result.first : r.first
|
|
26
27
|
new_last = result.last < r.last ? result.last : r.last
|
|
27
28
|
new_first..new_last
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class Range
|
|
2
|
+
|
|
3
|
+
# Do two ranges overlap?
|
|
4
|
+
#
|
|
5
|
+
# (1..5).overlap?(3..8) #=> true
|
|
6
|
+
# (1..5).overlap?(6..8) #=> false
|
|
7
|
+
#
|
|
8
|
+
# Ruby 3.3 added a native Range#overlap?, so only define Facets' version
|
|
9
|
+
# on older Rubies that lack it -- this avoids replacing the built-in.
|
|
10
|
+
#
|
|
11
|
+
# CREDIT: Daniel Schierbeck, Brandon Keepers
|
|
12
|
+
|
|
13
|
+
unless method_defined?(:overlap?)
|
|
14
|
+
def overlap?(other)
|
|
15
|
+
include?(other.first) or other.include?(first)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
data/lib/core/facets/range.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require_relative 'range/combine.rb'
|
|
2
2
|
require_relative 'range/overlap.rb'
|
|
3
|
+
#require_relative 'range/intersection.rb' # too new
|
|
3
4
|
#require_relative 'range/quantile.rb' # uncommon
|
|
4
5
|
#require_relative 'range/op_add.rb' # too new
|
|
5
6
|
#require_relative 'range/op_sub.rb' # too new
|
data/lib/core/facets/symbol.rb
CHANGED
|
@@ -8,7 +8,7 @@ require_relative 'symbol/op_div.rb'
|
|
|
8
8
|
require_relative 'symbol/plain.rb'
|
|
9
9
|
require_relative 'symbol/query.rb'
|
|
10
10
|
require_relative 'symbol/setter.rb'
|
|
11
|
-
require_relative 'symbol/succ.rb'
|
|
11
|
+
#require_relative 'symbol/succ.rb' # removed: now provided by Ruby
|
|
12
12
|
require_relative 'symbol/thrown.rb'
|
|
13
13
|
require_relative 'symbol/variablize.rb'
|
|
14
14
|
|
data/lib/core/facets/version.rb
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# OpenDSL is a clever way to create a plugable
|
|
2
|
+
# free-form domain specific language.
|
|
3
|
+
#
|
|
4
|
+
# Example = OpenDSL.new do
|
|
5
|
+
# size do
|
|
6
|
+
# 100
|
|
7
|
+
# end
|
|
8
|
+
# end
|
|
9
|
+
#
|
|
10
|
+
# class Foo
|
|
11
|
+
# include Example
|
|
12
|
+
# end
|
|
13
|
+
#
|
|
14
|
+
# Foo.new.size #=> 100
|
|
15
|
+
#
|
|
16
|
+
class OpenDSL < Module
|
|
17
|
+
|
|
18
|
+
#
|
|
19
|
+
def initialize(&block)
|
|
20
|
+
instance_eval(&block) if block_given?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
#
|
|
24
|
+
def method_missing(s, *a, &b)
|
|
25
|
+
if block_given?
|
|
26
|
+
define_method(s, &b)
|
|
27
|
+
else
|
|
28
|
+
super(s, *a, &b)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
# Facets' extensions to Ruby's OpenStruct.
|
|
2
|
+
#
|
|
3
|
+
# NOTE: `ostruct` is deprecated as of Ruby 3.4 and is no longer a default gem
|
|
4
|
+
# as of Ruby 3.5 — it must be installed/declared explicitly to be available
|
|
5
|
+
# (`gem install ostruct`, or add `ostruct` to your Gemfile/gemspec). The gem
|
|
6
|
+
# itself still exists, so these extensions continue to work on top of it.
|
|
7
|
+
#
|
|
8
|
+
# Given OpenStruct's deprecation, Facets may divest these extensions in a
|
|
9
|
+
# future release.
|
|
10
|
+
|
|
1
11
|
require 'ostruct'
|
|
2
12
|
require 'facets/ostruct/initialize'
|
|
3
13
|
require 'facets/ostruct/to_ostruct'
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# PIC - Pattern matching based on COBOL-style Edited Pictures.
|
|
2
|
+
#
|
|
3
|
+
# PIC provides a simple alternative to regular expressions for common
|
|
4
|
+
# data format matching. It uses single-character codes to describe the
|
|
5
|
+
# expected format of a string, inspired by COBOL's PICTURE clause.
|
|
6
|
+
#
|
|
7
|
+
# == Picture Characters
|
|
8
|
+
#
|
|
9
|
+
# The following picture characters are supported:
|
|
10
|
+
#
|
|
11
|
+
# X - Any character (equivalent to regex `.`)
|
|
12
|
+
# 9 - Any digit (equivalent to regex `\d`)
|
|
13
|
+
# Z - Zero or more digits (equivalent to regex `\d*`)
|
|
14
|
+
# 0 - Any digit (equivalent to regex `\d`)
|
|
15
|
+
# A - Any letter, upper or lower case (equivalent to regex `[A-Za-z]`)
|
|
16
|
+
# W - Any word character (equivalent to regex `\w`)
|
|
17
|
+
# . - Literal period
|
|
18
|
+
# , - Literal comma
|
|
19
|
+
# - - Literal hyphen
|
|
20
|
+
# / - Literal forward slash
|
|
21
|
+
#
|
|
22
|
+
# == Repetition
|
|
23
|
+
#
|
|
24
|
+
# Any picture character can be followed by a count in brackets:
|
|
25
|
+
#
|
|
26
|
+
# 9[3] - Exactly 3 digits (e.g. `\d{3}`)
|
|
27
|
+
# 9[2,4] - Between 2 and 4 digits (e.g. `\d{2,4}`)
|
|
28
|
+
# 9[2..4] - Same as above, alternate syntax
|
|
29
|
+
#
|
|
30
|
+
# == Usage
|
|
31
|
+
#
|
|
32
|
+
# require 'pic'
|
|
33
|
+
#
|
|
34
|
+
# # Simple currency pattern
|
|
35
|
+
# PIC['Z.99'].to_re #=> /\d*\.\d\d/
|
|
36
|
+
#
|
|
37
|
+
# # US phone number
|
|
38
|
+
# PIC['9[3]-9[3]-9[4]'].to_re #=> /\d{3}\-\d{3}\-\d{4}/
|
|
39
|
+
#
|
|
40
|
+
# # Match against a string
|
|
41
|
+
# PIC['99/99/9999'] =~ '12/25/2025' #=> 0 (match)
|
|
42
|
+
#
|
|
43
|
+
# == Reference
|
|
44
|
+
#
|
|
45
|
+
# Based on the concept of Edited Pictures from COBOL.
|
|
46
|
+
# See: http://www.csis.ul.ie/cobol/course/EditedPics.htm
|
|
47
|
+
#
|
|
48
|
+
# Copyright (c) 2011 Rubyworks (BSD-2-Clause)
|
|
49
|
+
#
|
|
50
|
+
module PIC
|
|
51
|
+
|
|
52
|
+
# Shortcut to `PIC::Template.new(pic)`.
|
|
53
|
+
#
|
|
54
|
+
# @param [String] pic
|
|
55
|
+
# A picture string describing the expected format.
|
|
56
|
+
#
|
|
57
|
+
# @return [PIC::Template]
|
|
58
|
+
#
|
|
59
|
+
# @example
|
|
60
|
+
# PIC['Z.99'].to_re #=> /\d*\.\d\d/
|
|
61
|
+
#
|
|
62
|
+
def self.[](pic)
|
|
63
|
+
Template.new(pic)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Template class encapsulates a picture string, converts it to a
|
|
67
|
+
# regular expression, and delegates to it for matching.
|
|
68
|
+
#
|
|
69
|
+
# @example
|
|
70
|
+
# t = PIC::Template.new('9[3]-9[3]-9[4]')
|
|
71
|
+
# t.to_re #=> /\d{3}\-\d{3}\-\d{4}/
|
|
72
|
+
# t =~ '555-123-4567' #=> 0
|
|
73
|
+
#
|
|
74
|
+
class Template
|
|
75
|
+
|
|
76
|
+
# New pic template.
|
|
77
|
+
#
|
|
78
|
+
# @param [String] pic
|
|
79
|
+
# Picture string to use for matching.
|
|
80
|
+
#
|
|
81
|
+
def initialize(pic)
|
|
82
|
+
@pic = pic
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# The picture string.
|
|
86
|
+
#
|
|
87
|
+
# @return [String]
|
|
88
|
+
#
|
|
89
|
+
attr :pic
|
|
90
|
+
|
|
91
|
+
# Convert picture to a regular expression.
|
|
92
|
+
#
|
|
93
|
+
# @return [Regexp]
|
|
94
|
+
#
|
|
95
|
+
# @example
|
|
96
|
+
# PIC::Template.new('99/99/9999').to_re #=> /\d\d\/\d\d\/\d\d\d\d/
|
|
97
|
+
#
|
|
98
|
+
def to_re
|
|
99
|
+
re = ''
|
|
100
|
+
pic.scan(SCAN) do |s,c|
|
|
101
|
+
re << remap(s) + recnt(c)
|
|
102
|
+
end
|
|
103
|
+
Regexp.new(re)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Alias for `#to_re`.
|
|
107
|
+
alias_method :to_regexp, :to_re
|
|
108
|
+
|
|
109
|
+
# Match picture against a given string.
|
|
110
|
+
#
|
|
111
|
+
# @param [String] string
|
|
112
|
+
# String to match picture against.
|
|
113
|
+
#
|
|
114
|
+
# @return [Integer, nil] index position of match, or nil.
|
|
115
|
+
#
|
|
116
|
+
def =~(string)
|
|
117
|
+
to_re =~ string.to_str
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
alias === =~
|
|
121
|
+
|
|
122
|
+
# Check for non-match of the picture against a given string.
|
|
123
|
+
#
|
|
124
|
+
# @param [String] string
|
|
125
|
+
# String to match picture against.
|
|
126
|
+
#
|
|
127
|
+
# @return [Boolean]
|
|
128
|
+
#
|
|
129
|
+
def !~(string)
|
|
130
|
+
to_re !~ string.to_str
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
private
|
|
134
|
+
|
|
135
|
+
# Map a picture character to its regex equivalent.
|
|
136
|
+
def remap(s)
|
|
137
|
+
REMAP[s] || raise(ArgumentError, "unknown picture character: #{s}")
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Convert a bracket count to a regex quantifier.
|
|
141
|
+
def recnt(c)
|
|
142
|
+
return '' unless c
|
|
143
|
+
|
|
144
|
+
case c
|
|
145
|
+
when /\[(\d+)\.\.(\d+)\]/
|
|
146
|
+
'{'+$1+','+$2+'}'
|
|
147
|
+
when /\[(\d+)\,(\d+)\]/
|
|
148
|
+
'{'+$1+','+$2+'}'
|
|
149
|
+
when /\[(\d+)\]/
|
|
150
|
+
'{'+$1+'}'
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Scan pattern for parsing picture strings.
|
|
155
|
+
SCAN = /(\S)(\[.*?\])?/
|
|
156
|
+
|
|
157
|
+
# Mapping of picture characters to regex fragments.
|
|
158
|
+
REMAP = {
|
|
159
|
+
'X' => '.',
|
|
160
|
+
'9' => '\d',
|
|
161
|
+
'Z' => '\d*',
|
|
162
|
+
'0' => '\d',
|
|
163
|
+
'A' => '[A-Za-z]',
|
|
164
|
+
'W' => '\w',
|
|
165
|
+
'.' => '\.',
|
|
166
|
+
',' => '\,',
|
|
167
|
+
'-' => '\-',
|
|
168
|
+
'/' => '\/'
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: facets
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.2.
|
|
4
|
+
version: 3.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Thomas Sawyer
|
|
@@ -451,6 +451,7 @@ files:
|
|
|
451
451
|
- lib/core/facets/range/nudge.rb
|
|
452
452
|
- lib/core/facets/range/op_add.rb
|
|
453
453
|
- lib/core/facets/range/op_sub.rb
|
|
454
|
+
- lib/core/facets/range/overlap.rb
|
|
454
455
|
- lib/core/facets/range/quantile.rb
|
|
455
456
|
- lib/core/facets/range/to_rng.rb
|
|
456
457
|
- lib/core/facets/range/umbrella.rb
|
|
@@ -682,6 +683,7 @@ files:
|
|
|
682
683
|
- lib/standard/facets/multiton.rb
|
|
683
684
|
- lib/standard/facets/net/http.rb
|
|
684
685
|
- lib/standard/facets/nullclass.rb
|
|
686
|
+
- lib/standard/facets/opendsl.rb
|
|
685
687
|
- lib/standard/facets/opesc.rb
|
|
686
688
|
- lib/standard/facets/ostruct.rb
|
|
687
689
|
- lib/standard/facets/ostruct/initialize.rb
|
|
@@ -706,6 +708,7 @@ files:
|
|
|
706
708
|
- lib/standard/facets/pathname/uptodate.rb
|
|
707
709
|
- lib/standard/facets/pathname/visit.rb
|
|
708
710
|
- lib/standard/facets/pathname/work.rb
|
|
711
|
+
- lib/standard/facets/pic.rb
|
|
709
712
|
- lib/standard/facets/platform.rb
|
|
710
713
|
- lib/standard/facets/random.rb
|
|
711
714
|
- lib/standard/facets/rbconfig.rb
|