facets 3.2.2 → 4.0.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.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +44 -15
  3. data/HISTORY.md +99 -0
  4. data/LICENSE.txt +1 -1
  5. data/README.md +50 -219
  6. data/lib/core/facets/array/nonuniq.rb +2 -2
  7. data/lib/core/facets/array/standard_deviation.rb +1 -1
  8. data/lib/core/facets/array/uniq_by.rb +5 -1
  9. data/lib/core/facets/array.rb +5 -1
  10. data/lib/core/facets/binding/self.rb +2 -1
  11. data/lib/core/facets/comparable/clip.rb +2 -1
  12. data/lib/core/facets/dir/recurse.rb +17 -4
  13. data/lib/core/facets/enumerable/compact_map.rb +1 -1
  14. data/lib/core/facets/enumerable/defer.rb +1 -1
  15. data/lib/core/facets/enumerable/frequency.rb +1 -1
  16. data/lib/core/facets/enumerable/hashify.rb +2 -2
  17. data/lib/core/facets/enumerable/hinge.rb +1 -1
  18. data/lib/core/facets/enumerable/map_with_index.rb +1 -1
  19. data/lib/core/facets/enumerable/mash.rb +2 -1
  20. data/lib/core/facets/enumerable/uniq_by.rb +3 -1
  21. data/lib/core/facets/essentials.rb +4 -1
  22. data/lib/core/facets/exception/error_print.rb +4 -2
  23. data/lib/core/facets/file/null.rb +2 -1
  24. data/lib/core/facets/file/read_binary.rb +2 -1
  25. data/lib/core/facets/file.rb +1 -1
  26. data/lib/core/facets/hash/fetch_nested.rb +2 -1
  27. data/lib/core/facets/hash/update_keys.rb +2 -1
  28. data/lib/core/facets/hash/update_values.rb +2 -1
  29. data/lib/core/facets/hash.rb +6 -4
  30. data/lib/core/facets/kernel/eigenclass.rb +2 -1
  31. data/lib/core/facets/kernel/extension.rb +2 -1
  32. data/lib/core/facets/kernel/instance_class.rb +2 -1
  33. data/lib/core/facets/kernel/instance_send.rb +2 -1
  34. data/lib/core/facets/kernel/like.rb +7 -2
  35. data/lib/core/facets/kernel/load_relative.rb +2 -1
  36. data/lib/core/facets/kernel/memo.rb +2 -1
  37. data/lib/core/facets/kernel/meta.rb +1 -1
  38. data/lib/core/facets/kernel/object_class.rb +2 -1
  39. data/lib/core/facets/kernel/object_send.rb +2 -1
  40. data/lib/core/facets/kernel/qua_class.rb +2 -1
  41. data/lib/core/facets/kernel/returning.rb +3 -1
  42. data/lib/core/facets/kernel/silence.rb +38 -30
  43. data/lib/core/facets/kernel/tee.rb +3 -0
  44. data/lib/core/facets/kernel/try.rb +25 -14
  45. data/lib/core/facets/kernel/with.rb +15 -9
  46. data/lib/core/facets/kernel.rb +1 -1
  47. data/lib/core/facets/module/alias_method_chain.rb +3 -1
  48. data/lib/core/facets/module/alias_module_function.rb +4 -1
  49. data/lib/core/facets/module/can.rb +2 -1
  50. data/lib/core/facets/objectspace/op_fetch.rb +2 -1
  51. data/lib/core/facets/proc/compose.rb +4 -2
  52. data/lib/core/facets/rails_bridge.rb +27 -0
  53. data/lib/core/facets/string/camelcase.rb +6 -0
  54. data/lib/core/facets/string/similarity.rb +3 -2
  55. data/lib/core/facets/struct/attributes.rb +1 -1
  56. data/lib/core/facets/time/to_time.rb +7 -2
  57. data/lib/core/facets/time/trunc.rb +2 -1
  58. data/lib/core/facets/unboundmethod/arguments.rb +1 -1
  59. data/lib/core/facets/version.rb +1 -1
  60. data/lib/rails/facets/hash/to_options.rb +14 -0
  61. data/lib/{core → rails}/facets/module/mattr.rb +30 -30
  62. data/lib/standard/facets/cloneable.rb +2 -1
  63. data/lib/standard/facets/continuation.rb +2 -1
  64. data/lib/standard/facets/enumargs.rb +14 -2
  65. data/lib/standard/facets/getoptlong.rb +2 -1
  66. data/lib/standard/facets/interval.rb +4 -3
  67. data/lib/standard/facets/load_monitor.rb +2 -1
  68. data/lib/standard/facets/pathname/null.rb +2 -1
  69. data/lib/standard/facets/random.rb +8 -4
  70. metadata +14 -12
  71. data/lib/core/facets/hash/to_options.rb +0 -1
  72. /data/lib/{core → rails}/facets/array/extract_options.rb +0 -0
  73. /data/lib/{core → rails}/facets/cattr.rb +0 -0
  74. /data/lib/{core → rails}/facets/class/cattr.rb +0 -0
  75. /data/lib/{standard → rails}/facets/date.rb +0 -0
  76. /data/lib/{core → rails}/facets/file/atomic_write.rb +0 -0
  77. /data/lib/{core → rails}/facets/hash/slice.rb +0 -0
  78. /data/lib/{core → rails}/facets/hash/stringify_keys.rb +0 -0
  79. /data/lib/{core → rails}/facets/hash/symbolize_keys.rb +0 -0
  80. /data/lib/{core → rails}/facets/module/cattr.rb +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: da62aa5e36dc4d4fbe19984071e7f4bf38acc53a7812c285a50a36b714115f23
4
- data.tar.gz: 7244c28aff76e1073f723148e6a9e3006246a26cd59c047dab8a2d8f765a3e3d
3
+ metadata.gz: af1581fdee797dd22551c3257c73b76e2d0e5ee659ecb60690eee877672a5a00
4
+ data.tar.gz: 8693eedfa8dc78cfa8c47964cac6f2834996337dc00bbf0e9672c2b664bc2cea
5
5
  SHA512:
6
- metadata.gz: acc7199da1618757142fede6aece2bdbc324a7d8d95525f4ff40a0ef1085484ec42d3727eb3adcd65be3eccfa210e599d1488dafde8640b04375947b6df96c7b
7
- data.tar.gz: 0e561c34ccac85af4fa6b1ce7c28a2396d4326ff75917b6fde31c6618be7cdb46c959fec59454b1a6b4df5a2c3a6812cae72c68ce5bd0a96714afa1dc43bd344
6
+ metadata.gz: e4a41b846c6bf81d6103ec0fcac3f8b729f5ab324676ab7f2b25a4126bfe878ec36a7113d58b4a7c32c5d1748cd4a1a9ae4ebba80fa82e7226c83bc7d7220af1
7
+ data.tar.gz: 5c32bd85bdeb4336d5774689023e73d5c7e74ee86eff5003e5ef4da1644f10c6de5c897b6a0f268f09c7976055b28acaba10cf420b546380ae21c4d73508da86
data/CONTRIBUTING.md CHANGED
@@ -18,14 +18,14 @@
18
18
  The Lemon unit tests are for testing a method in detail whereas the QED
19
19
  demos are for demonstrating usage.
20
20
 
21
- * Facets is divided into two parts, *core* and *standard* libraries.
22
- Almost all of the core library can be loaded at once using `require 'facets'`
23
- The standard library (also called the *more* library) must be required
24
- per-script.
21
+ * Facets groups libraries into `core`, `standard`, and `rails` areas.
22
+ Almost all core extensions can be loaded at once with `require 'facets'`.
23
+ Standard and rails extensions should be required by file.
25
24
 
26
- * Some core methods are included on a *trial* basis, and these are not
27
- necessary loaded automatically with `require 'facets'`. These should be
28
- documented as such in the method comments.
25
+ * Some core methods are *uncommon* and are not loaded by `require 'facets'`.
26
+ Mark them with an `@uncommon` tag in the method comments, showing the
27
+ require line, and comment out their line in the aggregator file with
28
+ `# uncommon`.
29
29
 
30
30
  * Standard libraries that are not extensions of existing standard libraries
31
31
  do not have to be divvied up into individual method files. But note that
@@ -102,11 +102,40 @@ explanation if needed, including *when* and *why* the method could be useful.
102
102
 
103
103
  ## Testing
104
104
 
105
- * Methods in `lib/core/facets/{class}/{method}.rb` will be tested in `test/foo/{class}/test_{method}.rb`.
106
- * If `lib/core/facets/{class}/{method}.rb` consists only of a require statement, no test file is expected.
107
- * If `lib/core/facets/{class}/{method}.rb` consists only of a require and an alias, then `test/foo/{class}/{method}.rb`, only needs to test the existence of the alias and not the underlying code. But it's okay if the alias is tested further.
108
- * Methods in `lib/core/facets/{class}/{method}.rb` will be demoed in `demo/core/{class}/{method}.md`.
109
- * Require only files will have a full demo of it's method or methods. Code in a single file may be split into multiple demos, named after the method. This is to promote discoverability in the documentation.
110
- * Demos of aliases will have a simple demo, and a reference to the file it aliases
111
-
112
-
105
+ The test suite uses four tools:
106
+
107
+ * **RubyTest** provides the test runner interface; `rubytest-cli` supplies the
108
+ `ruby-test` command used by the Rake tasks.
109
+ * **Lemon** defines the `test_case`, `method`, and `test` structure of the unit
110
+ tests.
111
+ * **AE** provides assertions such as `.assert` and `expect`, used in both the
112
+ unit tests and the QED demos. It is installed as a Lemon dependency.
113
+ * **QED** runs the executable examples in `demo/`. They show how a method is
114
+ intended to be used as well as checking its behavior.
115
+
116
+ Install the development dependencies and run the same two suites as CI:
117
+
118
+ ```sh
119
+ bundle install
120
+ bundle exec rake test
121
+ bundle exec rake qed
122
+ ```
123
+
124
+ For a focused unit test, set `TESTS` to a test file, for example:
125
+
126
+ ```sh
127
+ TESTS=test/core/array/test_average.rb bundle exec rake test
128
+ ```
129
+
130
+ The Rakefile also provides `test:core`, `test:standard`, `test:rails` and the
131
+ corresponding `qed:*` tasks for each library area.
132
+
133
+ * A core method in `lib/core/facets/{class}/{method}.rb` normally has a Lemon
134
+ test in `test/core/{class}/test_{method}.rb` and a QED demo in
135
+ `demo/core/{class}/{method}.md`. Standard and rails libraries use
136
+ their respective `test/` and `demo/` directories.
137
+ * A file that only requires another file does not need its own unit test. A file
138
+ that also defines an alias can test the alias without repeating every test
139
+ for the underlying method.
140
+ * Demos should show the behavior of each method. An alias can have a short demo
141
+ that points readers to the main method's demo.
data/HISTORY.md CHANGED
@@ -1,5 +1,100 @@
1
1
  # Facets Release History
2
2
 
3
+ ## 4.0.0 / 2026-09-27
4
+
5
+ A major release, because it changes behavior: `Kernel#try!` is now the
6
+ lenient variant and `#try` is strict, `require 'facets'` no longer loads
7
+ `Kernel#with`, and Rails-compatible methods move to the new `lib/rails`
8
+ area (still loaded by `require 'facets'` with a warning until 2027-09-30).
9
+ Every deprecation now names that same removal date.
10
+
11
+ Changes:
12
+
13
+ * Breaking
14
+
15
+ * `Kernel#try!` now returns `nil` when the receiver doesn't respond to the
16
+ method (or it is private), instead of raising `NoMethodError`. `#try`
17
+ stays strict. This is deliberately the opposite of ActiveSupport, which
18
+ since Rails 4.0 makes `#try` lenient and `#try!` strict. In Ruby the bang
19
+ marks the more dangerous method, and quietly ignoring a missing method is
20
+ the dangerous behavior. The docs no longer claim ActiveSupport
21
+ compatibility.
22
+ * `require 'facets'` no longer loads `Kernel#with`, since a global `with`
23
+ breaks other libraries' methods of that name, such as RSpec's
24
+ `receive(...).with` (#290). It is still available, deprecated, with
25
+ `require 'facets/kernel/with'`.
26
+ * `Kernel#try` no longer calls private methods. It now behaves exactly like
27
+ a normal call or `&.`, raising `NoMethodError` for them.
28
+
29
+ * Enhancements
30
+
31
+ * New `lib/rails` library for Rails-compatible methods that Facets carries
32
+ but doesn't endorse as its own: `Hash#symbolize_keys`/`#stringify_keys`,
33
+ `Hash#to_options`, `Hash#slice!`, `Array#extract_options!`,
34
+ `Module#mattr_*`/`#cattr_*`, `File.atomic_write` and the `facets/date`
35
+ extensions. Require paths are unchanged (`require 'facets/hash/slice'`
36
+ still works), and `require 'facets'` still provides the same methods.
37
+
38
+ * Deprecations
39
+
40
+ * `require 'facets'` will stop providing the lib/rails methods after
41
+ 2027-09-30. Until then, the first call to one of them through
42
+ `require 'facets'` warns and names the file to require. Requiring that
43
+ file directly avoids the warning.
44
+ * `Kernel#returning`, `Module#alias_method_chain`, `Array#uniq_by!`,
45
+ `Enumerable#uniq_by`, `Kernel#silence_stream` and Facets' fallback
46
+ `Time#to_time` are scheduled for removal after 2027-09-30. Each warns
47
+ with its replacement and the removal date.
48
+ * Every existing deprecation now names a removal date, 2027-09-30, in its
49
+ `@deprecated` note and its warning. `String#upper_camelcase`/
50
+ `#lower_camelcase`, `Kernel#equate?`, `facets/kernel/tee` and
51
+ `Interval#each(n, d)` were deprecated in docs only (or "will be") and
52
+ now warn as well.
53
+ * `Kernel#with` is deprecated in favor of `instance_eval`, also for removal
54
+ after 2027-09-30. Rails 7.1's unrelated `Object#with` (which temporarily
55
+ sets attributes) was silently replaced by it when both were loaded.
56
+ * `Kernel#silence` now does the stream silencing itself; `silently`,
57
+ `silence_stderr` and `silence_stdout` use it and do not warn.
58
+
59
+ * Bug Fixes
60
+
61
+ * `Hash#to_options` and `#to_options!` now exist. `facets/hash/to_options`
62
+ only loaded `symbolize_keys` and never defined the aliases.
63
+ * `Module#alias_module_function` now aliases the singleton method directly.
64
+ On JRuby, the singleton method `module_function` created turned private
65
+ when aliased again, which broke `URI.hash_to_query` under the test suite.
66
+ * `Dir.recurse` and `Dir.ls_r` once again return an Array that leaves out
67
+ the starting directory. Deprecating them in favor of `Dir.find` had
68
+ quietly changed both.
69
+ * `Enumerable::Argumentable#min` and `#max` now pass their arguments to
70
+ `#each`, as documented, rather than to Ruby's own `min(n)`/`max(n)`.
71
+ * `String#similarity` now divides the shared length by the longer string's
72
+ length, not length + 1, so 9 of 10 matching characters score 0.9 as its
73
+ docs said (it gave 0.818). Scores for non-identical strings rise slightly.
74
+ * `require 'facets'` no longer crashes on Ruby 4.1, which removed
75
+ `ObjectSpace._id2ref`. `ObjectSpace[]` is only defined where `_id2ref`
76
+ exists.
77
+ * `Kernel#silence` now supports `:verbose`/`:warnings` and `:debug`, as its
78
+ docs always said, instead of raising `NoMethodError`. They set `$VERBOSE`
79
+ to nil and `$DEBUG` to false within the block.
80
+
81
+ * Internal
82
+
83
+ * Run the qed demos in CI.
84
+ * Remove leftover build files that nothing reads anymore: `MANIFEST`,
85
+ `Assembly` (Detroit), `.index`, `Indexfile` and `lib/core/facets.yml`.
86
+ The Rakefile takes its version from `Facets::VERSION` (`.index` still said
87
+ 3.1.1), and `rake package` no longer needs the `mast` and `index` tools.
88
+ * The gemspec reads its version from `Facets::VERSION`, so the version now
89
+ lives in one place, `lib/core/facets/version.rb`.
90
+ * Fix the qed demos, which had 8 failures and 2 errors. Most were stale
91
+ expectations (`Array#from`, `#step`, `#arrange`, `String#similarity`)
92
+ and the date demo held pasted irb output.
93
+ * CONTRIBUTING.md explains the test stack (RubyTest, Lemon, AE and QED)
94
+ and the `@uncommon` convention.
95
+ * The `String#trim` demo no longer drops random cases, so the QED
96
+ assertion count is the same on every run.
97
+
3
98
  ## 3.2.2 / 2026-06-15
4
99
 
5
100
  Patch release with cross-version fixes surfaced by CI on Ruby 3.1–3.4.
@@ -64,6 +159,10 @@ Changes:
64
159
  Modernization release targeting Ruby 3.1+. Cleans up long-standing
65
160
  compatibility issues and incorporates community contributions.
66
161
 
162
+ **Note:** This release removed methods and raised the minimum Ruby version
163
+ to 3.1, so it should have been released as 4.0.0. Treat the 3.2 series as a
164
+ major upgrade from 3.1, and review the Removals below before upgrading.
165
+
67
166
  Changes:
68
167
 
69
168
  * New Features
data/LICENSE.txt CHANGED
@@ -1,5 +1,5 @@
1
1
  Ruby Facets
2
- Copyright (c) 2005, Thomas Sawyer
2
+ Copyright (c) 2004, Thomas Sawyer
3
3
  All rights reserved.
4
4
 
5
5
  (BSD-2 LICENSE)
data/README.md CHANGED
@@ -1,253 +1,84 @@
1
- # Ruby Facets
1
+ # Ruby Facets <img src="docs/assets/images/cherries.svg" alt="cherries" width="34" height="34">
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/facets.svg)](https://rubygems.org/gems/facets)
4
4
  [![CI](https://github.com/rubyworks/facets/actions/workflows/ci.yml/badge.svg)](https://github.com/rubyworks/facets/actions/workflows/ci.yml)
5
5
 
6
+ **More of Ruby, one method at a time.** Facets is a collection of extensions to Ruby's core classes and standard library, plus a few small, reusable classes and modules. Most methods live in their own files, so you can load one extension, a class's extensions, or the core collection.
6
7
 
7
- *"ALL YOUR BASE ARE BELONG TO RUBY"*
8
+ Facets took its name in 2004, growing out of a small methods library started in 2002, and is still maintained. The current release is **3.2.2**, which requires **Ruby 3.1 or newer**. See the [release history](HISTORY.md) for changes and migration notes from earlier versions. The `main` branch also contains changes awaiting the next release.
8
9
 
10
+ ## Install
9
11
 
10
- ## Introduction
12
+ ```sh
13
+ gem install facets
14
+ ```
11
15
 
12
- Ruby Facets is the premier collection of general purpose method
13
- extensions and standard additions for the Ruby programming language.
16
+ With Bundler, add this to your Gemfile:
14
17
 
15
- Facets houses the largest single collection of methods available for
16
- extending the core capabilities of Ruby's built-in classes and modules.
17
- This collection of extension methods are unique by virtue of their atomicity.
18
- The methods are stored in individual files so that each can be required
19
- independently. This gives developers the potential for much finer control over
20
- which extra methods to bring into their code.
18
+ ```ruby
19
+ gem 'facets', require: false
20
+ ```
21
21
 
22
- In addition Facets provides a collection of extensions to Ruby standard library
23
- plus a small collection of add-on classes and modules. Together these
24
- libraries constitute an reliable source of reusable components, suitable
25
- to a wide variety of usecases.
22
+ `require: false` lets you choose which extensions to load. Omit it if you want Bundler to load the core collection automatically.
26
23
 
24
+ ## Choose how much to load
27
25
 
28
- ## Resources
26
+ ### One method
29
27
 
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
28
+ ```ruby
29
+ require 'facets/array/to_ranges'
34
30
 
31
+ [1, 2, 3, 6, 7].to_ranges
32
+ #=> [1..3, 6..7]
33
+ ```
35
34
 
36
- ## Documentation
37
-
38
- Facets has special documentation needs due to its extensive breadth.
39
- The documentation generated when installing via RubyGems, or the YARD
40
- docs provided by rubydoc.info can be somewhat unwieldy because it
41
- combines all of Facets in one large set. When using these resources,
42
- it is important to remain aware of the source location of particular
43
- methods.
44
-
45
- For better organized online documentation, generated to separate core
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.
47
-
48
-
49
- ## Installation
50
-
51
- ### Bundler
52
-
53
- If you are using Bundler with your project, add the facets gem to the project's
54
- Gemfile. Unless you want all of facets loaded be sure to add the `:require => false`
55
- option.
56
-
57
- gem "facets", require: false
58
-
59
- ### RubyGems
60
-
61
- The easiest way to install is via RubyGems.
62
-
63
- $ gem install facets
64
-
65
- ### Requirements
66
-
67
- Facets 3.2+ requires Ruby 3.1 or higher.
68
-
69
-
70
- ## Mission
71
-
72
- Facets holds to the notion that the more we can *reasonably* integrate into
73
- a common foundation, directed toward general needs, the better that foundation
74
- will be able to serve the community. There are a number of advantages here:
75
-
76
- * Better Code-reuse
77
- * Collaborative Improvements
78
- * Greater Name Consistency
79
- * One-stop Shop and Installation
80
-
81
-
82
- ## Usage
83
-
84
- ### CORE Library
85
-
86
- At the heart of Ruby Facets is the CORE extensions library. CORE provides
87
- a sizable collection of generally useful methods, along with a few supporting
88
- classes, that extend the functionality of Ruby's core classes and modules.
89
-
90
- With the exception of a few *uncommon* extensions, CORE contains anything that
91
- will load automatically when issuing:
92
-
93
- require 'facets'
94
-
95
- This loads all the CORE functionality at once. If you plan to use more then a
96
- handful of Facets core methods it is recommended that you require the library in
97
- this way. However, you can also "cherry pick" the CORE library as you prefer.
98
- And for uncommon extensions this must be done. The general require statement for
99
- a core extension library is:
100
-
101
- require 'facets/<class|module>/<method>'
102
-
103
- For example:
104
-
105
- require 'facets/time/stamp'
106
-
107
- Most "atoms" contain only one method, but exceptions occur when methods
108
- are closely tied together.
35
+ ### One class's core extensions
109
36
 
110
- You can load per-class or per-module groups of core methods by requiring the
111
- class or module by name. For example"
37
+ ```ruby
38
+ require 'facets/string'
112
39
 
113
- require 'facets/time'
40
+ 'Ruby Facets'.snakecase
41
+ #=> "ruby_facets"
42
+ ```
114
43
 
115
- Will require all the core Time method extensions.
44
+ ### The core collection
116
45
 
117
- Note that some methods that were part of CORE in 1.8 and earlier are now part
118
- of MORE libraries. A good example is 'random.rb'. There were separated because
119
- they had more specialized use cases, where as CORE extensions are intended as
120
- general purpose.
46
+ ```ruby
47
+ require 'facets'
121
48
 
122
- #### Method File Names
49
+ [1, 2, 3].average
50
+ #=> 2.0
51
+ ```
123
52
 
124
- Operator method redirect files are stored using English names. For instance
125
- `Proc#*` is `proc/op_mul`.
53
+ `require 'facets'` loads the broadly useful **core** extensions: roughly 860 methods from 448 files, adding about 35 ms of load time and 2 MB of memory (Ruby 3.3, Linux). Some specialized core extensions are opt-in; require their method file directly. To load Facets extensions to a Ruby standard library, require that library through Facets:
126
54
 
127
- For reference, here is the chart.
55
+ ```ruby
56
+ require 'facets/ostruct'
57
+ ```
128
58
 
129
- +@ => op_plus
130
- -@ => op_minus
131
- + => op_add
132
- - => op_sub
133
- ** => op_pow
134
- * => op_mul
135
- / => op_div
136
- % => op_mod
137
- ~ => op_tilde
138
- <=> => op_cmp
139
- << => op_lshift
140
- >> => op_rshift
141
- < => op_lt
142
- > => op_gt
143
- === => op_case
144
- == => op_equal
145
- =~ => op_apply
146
- <= => op_lt_eq
147
- >= => op_gt_eq
148
- | => op_or
149
- & => op_and
150
- ^ => op_xor
151
- []= => op_store
152
- [] => op_fetch
59
+ This loads `ostruct` and Facets' OpenStruct extensions. On Ruby 3.5+, declare the `ostruct` gem separately because it is no longer a default gem.
153
60
 
154
- Facets simply takes the '*' and translates it into a string acceptable to all
155
- file systems. Also, if a method ends in '=', '?' or '!' it is simply removed.
156
-
157
-
158
- ### MORE Library (aka Standard Library)
159
-
160
- On top of the extensive CORE library, Facets provides extensions for Ruby's
161
- standard library, as well as a small collection of additional modules and
162
- classes to supplement it.
163
-
164
- Use this library like you would any other 3rd party library.
165
- The only difference between Facet's Standard library and other libraries
166
- is the lack of any enclosing `Facets::` namespace.
167
-
168
- When using Facets extended versions of Ruby's standard libraries,
169
- the libraries have to loaded individually. However you do not need
170
- to load Ruby's library first, as the Facets' library will do that
171
- automatically.
172
-
173
- For example, normally one load Ruby's OpenStruct class via:
174
-
175
- require 'ostruct'
176
-
177
- To load 'ostruct.rb' plus Facets extensions for it simply use:
178
-
179
- require 'facets/ostruct'
61
+ ## Documentation
180
62
 
181
- For details pertaining to the functionality of each feature,
182
- please see the API documentation.
63
+ - [Getting started and loading guide](https://rubyworks.github.io/facets/learn.html)
64
+ - [Generated API documentation on RubyDoc.info](https://www.rubydoc.info/gems/facets) (check the displayed version)
65
+ - [Release history](HISTORY.md)
183
66
 
67
+ The split between `lib/core`, `lib/standard` and `lib/rails` is visible in API source paths. This helps you tell whether a method is loaded by `require 'facets'` or needs an explicit require. The `lib/rails` area, new in 4.0.0, holds Rails-compatible helpers; see the release history for details.
184
68
 
185
69
  ## Contribute
186
70
 
187
- This project thrives on contribution!
188
-
189
- If you have any extension methods, classes or modules that you think have
190
- very general applicability and would like to see them included in
191
- this project, don't hesitate to submit. Also, if you have better versions
192
- of any thing already included or simply have a patch, they are more than
193
- welcome. We want Ruby Facets to be of the highest quality.
194
-
195
-
196
- ## Development
197
-
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
203
-
204
- Continuous integration runs on GitHub Actions (see `.github/workflows/ci.yml`).
205
-
206
-
207
- ## Authors
208
-
209
- Much of this collection was written and/or inspired by a variety of great Ruby
210
- developers. Fortunately nearly all utilized works were copyrighted under the same
211
- open licenses, the Ruby License or the more liberal BSD and MIT licenses. In the
212
- one or two exceptions the copyright notice has been included with the source code.
213
- We have since received permission from the various authors to normalize the licensing
214
- to a single license. For this purpose we have chosen the BSD 2 Clause License.
215
- This is the license Ruby itself now uses, so it seemed the most appropriate choice.
216
- It is also almost identical to the MIT license. Any code file not specifically labeled
217
- otherwise shall fall under the this license (which is BSD 2-clause).
218
-
219
- In all cases, every effort has been made to give credit where credit is due.
220
- You will find these acknowledgments embedded in the source code. You can see
221
- them in "CREDIT:" and/or "@author" lines.
222
- Also see the [Contributors page](https://github.com/rubyworks/facets/wiki/Contributors)
223
- on the Wiki for a list of all contributing Rubyists. If anyone is missing from
224
- the list, please let us know so we can correct. Thanks.
225
-
226
- This collection was put together by, and much of it written by [trans](https://github.com/trans).
227
- If need be, he can be reached via email at transfire at gmail.com.
228
-
229
-
230
- ## License
231
-
232
- The collection PER COLLECTION is licensed as follows:
233
-
234
- Ruby Facets
235
- Copyright (c) 2005 Rubyworks
236
-
237
- Distributed under the terms of the BSD-2 License (same as Ruby license).
238
-
239
- The BSD 2 Clause License is a simple open source license. The complete text of the
240
- license accompany this document (see the enclosed LICENSE file).
241
-
242
- Acknowledgments and Copyrights for particular snippets of borrowed code
243
- are given in their respective source. At this point, all licensing has been normalized
244
- for all included code. Original authors have given permission for inclusion of their
245
- code under such license, with appropriate credit citations.
71
+ Issues and pull requests are welcome. Start with [CONTRIBUTING.md](CONTRIBUTING.md) for the library's method organization, demos, and test conventions. The test suite runs with:
246
72
 
73
+ ```sh
74
+ bundle install
75
+ bundle exec rake test
76
+ ```
247
77
 
248
- ## "ALL YOUR BASE ARE BELONG TO RUBY!"
78
+ [Source](https://github.com/rubyworks/facets) · [Issues](https://github.com/rubyworks/facets/issues) · [Website](https://rubyworks.github.io/facets/)
249
79
 
250
- Ruby Facets, Copyright (c) 2005 Rubyworks
80
+ ## License and credits
251
81
 
252
- Do you Ruby? (https://ruby-lang.org)
82
+ Facets is distributed under the [BSD 2-Clause License](LICENSE.txt). Thomas Sawyer started the project, and many Rubyists have contributed code, ideas, tests, and documentation. Individual files record additional credits where applicable.
253
83
 
84
+ *All your base are belong to Ruby.*
@@ -11,14 +11,14 @@ class Array
11
11
  # CREDIT: Martin DeMello
12
12
 
13
13
  def nonuniq
14
- warn "Array#nonuniq is deprecated. Use Array#duplicates instead.", uplevel: 1
14
+ warn "Array#nonuniq is deprecated. Use Array#duplicates instead. It will be removed after 2027-09-30.", uplevel: 1
15
15
  duplicates
16
16
  end
17
17
 
18
18
  # Same as `#nonuniq` but acts in place.
19
19
 
20
20
  def nonuniq!
21
- warn "Array#nonuniq! is deprecated. Use Array#duplicates instead.", uplevel: 1
21
+ warn "Array#nonuniq! is deprecated. Use Array#duplicates instead. It will be removed after 2027-09-30.", uplevel: 1
22
22
  self.replace(duplicates)
23
23
  end
24
24
 
@@ -20,7 +20,7 @@ class Array
20
20
  alias sd stddev
21
21
 
22
22
  def standard_deviation
23
- warn "Array#standard_deviation is deprecated. Use Array#stddev or Array#sd instead.", uplevel: 1
23
+ warn "Array#standard_deviation is deprecated. Use Array#stddev or Array#sd instead. It will be removed after 2027-09-30.", uplevel: 1
24
24
  stddev
25
25
  end
26
26
  end
@@ -15,8 +15,12 @@ class Array
15
15
  #
16
16
  # Returns [Array] of unique elements.
17
17
  #
18
+ # @deprecated Use Array#uniq! with a block instead (Ruby 1.9.2+).
19
+ # Scheduled for removal after 2027-09-30.
20
+ #
18
21
  def uniq_by!(&block) #:yield:
19
- warn "Array#uniq_by! is deprecated. Use Array#uniq!(&block) instead.", uplevel: 1
22
+ warn "Array#uniq_by! is deprecated. Use Array#uniq!(&block) instead. " \
23
+ "It will be removed after 2027-09-30.", uplevel: 1
20
24
  uniq!(&block)
21
25
  end
22
26
 
@@ -15,7 +15,6 @@ require_relative 'array/duplicates.rb'
15
15
  require_relative 'array/each_pair.rb'
16
16
  require_relative 'array/each_value.rb'
17
17
  require_relative 'array/entropy.rb'
18
- require_relative 'array/extract_options.rb'
19
18
  require_relative 'array/from.rb'
20
19
  require_relative 'array/indexable.rb'
21
20
  #require_relative 'array/intersection.rb' # too new
@@ -47,3 +46,8 @@ require_relative 'array/thru.rb'
47
46
  require_relative 'array/traverse.rb'
48
47
  require_relative 'array/uniq_by.rb'
49
48
 
49
+
50
+ # Rails-compatible methods from lib/rails; see facets/rails_bridge.
51
+ require_relative 'rails_bridge.rb'
52
+ Facets.rails_bridge(Array, 'facets/array/extract_options', :extract_options!)
53
+ Facets.rails_bridge(Hash, 'facets/array/extract_options', :extractable_options?)
@@ -1,8 +1,9 @@
1
1
  class Binding
2
2
 
3
3
  # @deprecated Use Binding#receiver instead (built-in since Ruby 2.6).
4
+ # Scheduled for removal after 2027-09-30.
4
5
  def self
5
- warn "Binding#self is deprecated. Use Binding#receiver instead.", uplevel: 1
6
+ warn "Binding#self is deprecated. Use Binding#receiver instead. It will be removed after 2027-09-30.", uplevel: 1
6
7
  receiver
7
8
  end
8
9
 
@@ -1,8 +1,9 @@
1
1
  module Comparable
2
2
 
3
3
  # @deprecated Use Comparable#clamp instead (built-in since Ruby 2.4).
4
+ # Scheduled for removal after 2027-09-30.
4
5
  def clip(lower, upper=nil)
5
- warn "Comparable#clip is deprecated. Use Comparable#clamp instead.", uplevel: 1
6
+ warn "Comparable#clip is deprecated. Use Comparable#clamp instead. It will be removed after 2027-09-30.", uplevel: 1
6
7
  upper ? clamp(lower, upper) : clamp(lower..)
7
8
  end
8
9
 
@@ -2,16 +2,29 @@ require 'facets/dir/find'
2
2
 
3
3
  class Dir
4
4
 
5
+ # Recursively list every entry below +path+ (not +path+ itself),
6
+ # yielding each one to the block if given.
7
+ #
5
8
  # @deprecated Use Dir.find or Find.find instead.
9
+ # Scheduled for removal after 2027-09-30.
6
10
  def self.recurse(path='.', &block)
7
- warn "Dir.recurse is deprecated. Use Dir.find or Find.find instead.", uplevel: 1
8
- Dir.find(path, &block)
11
+ warn "Dir.recurse is deprecated. Use Dir.find or Find.find instead. It will be removed after 2027-09-30.", uplevel: 1
12
+ recurse_entries(path, &block)
9
13
  end
10
14
 
11
15
  # @deprecated Use Dir.find or Find.find instead.
16
+ # Scheduled for removal after 2027-09-30.
12
17
  def self.ls_r(path='.', &block)
13
- warn "Dir.ls_r is deprecated. Use Dir.find or Find.find instead.", uplevel: 1
14
- Dir.find(path, &block)
18
+ warn "Dir.ls_r is deprecated. Use Dir.find or Find.find instead. It will be removed after 2027-09-30.", uplevel: 1
19
+ recurse_entries(path, &block)
15
20
  end
16
21
 
22
+ # Dir.find yields +path+ first; the old #recurse did not include it.
23
+ def self.recurse_entries(path, &block)
24
+ list = Dir.find(path).drop(1)
25
+ list.each(&block) if block
26
+ list
27
+ end
28
+ private_class_method :recurse_entries
29
+
17
30
  end
@@ -15,7 +15,7 @@ module Enumerable
15
15
  # does almost the same thing and enum.map{}.compact works too.
16
16
 
17
17
  def compact_map(&block)
18
- warn "Enumerable#compact_map is deprecated. Use Enumerable#filter_map instead.", uplevel: 1
18
+ warn "Enumerable#compact_map is deprecated. Use Enumerable#filter_map instead. It will be removed after 2027-09-30.", uplevel: 1
19
19
  filter_map(&block)
20
20
  end
21
21
 
@@ -27,7 +27,7 @@ module Enumerable
27
27
  # to output each result and discard it.
28
28
  #
29
29
  def defer(&blk)
30
- warn "Enumerable#defer is deprecated. Use Enumerable#lazy instead.", uplevel: 1
30
+ warn "Enumerable#defer is deprecated. Use Enumerable#lazy instead. It will be removed after 2027-09-30.", uplevel: 1
31
31
  lazy
32
32
  end
33
33
 
@@ -16,7 +16,7 @@ module Enumerable
16
16
  #++
17
17
 
18
18
  def frequency
19
- warn "Enumerable#frequency is deprecated. Use Enumerable#tally instead.", uplevel: 1
19
+ warn "Enumerable#frequency is deprecated. Use Enumerable#tally instead. It will be removed after 2027-09-30.", uplevel: 1
20
20
  tally
21
21
  end
22
22