corefines 1.11.0 → 1.11.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: cc488d6deade84992853796d2e3e315e23a2bb32
4
- data.tar.gz: 4f671bc5963d4002509d54a90dc41024a9efa676
2
+ SHA256:
3
+ metadata.gz: e1786b22dad695d512f646e225334eeae9ecb2621a067461dc5c01151137ead0
4
+ data.tar.gz: 128135d2233f9b74976347ee1bbb4cae8b91327227aa4ed0e13432011f51d689
5
5
  SHA512:
6
- metadata.gz: 96553f167a0dc42ce8c556ef92e3542940bd6093ab1b5e368c58e7627e3f83ed479368bc5b552be845ee84c68ee52e254781ab42eb44777ad53d75e20c19108f
7
- data.tar.gz: 5ca6dc072b0ecf10503271b7d18ab2bee23efdf1663050f59a9c38e5c68409a19636ea9979986542848f11a960132361575e3b5142fdf225525b27e559ab3986
6
+ metadata.gz: 5159cba9976f0b56054472b43a3f0c28ce100eda5e6efe79896b97fdba42f078edc91327066b7dd99c3e9698b87c7ae643ad6989057ccf9d1b728f315bfd990d
7
+ data.tar.gz: a0158e47cc535f3e604a992ffac923812b1df13af300a2b91c56e77ab9a1983a374a5f630dfb11f005bbfd29926ca0504a17c976504b7feb0abf206a5b6f7b47
data/CHANGELOG.adoc ADDED
@@ -0,0 +1,78 @@
1
+ = Corefines Changelog
2
+ :repo-uri: https://github.com/jirutka/corefines
3
+ :doc-base-url: http://www.rubydoc.info/github/jirutka/corefines/Corefines
4
+ :issue-uri: {repo-uri}/issues
5
+
6
+
7
+ == 1.11.1 (2021-07-21)
8
+
9
+ * Fix String#rekey with symbol proc (e.g. `&:to_s`) failing on Ruby 3.0.
10
+
11
+
12
+ == 1.11.0 (2017-09-15)
13
+
14
+ * Add new refinement {doc-base-url}/Hash/Recurse[Hash#recurse].
15
+ * Add new refinement {doc-base-url}/Hash/FlatMap[Hash#flat_map].
16
+
17
+
18
+ == 1.10.0 (2017-07-26)
19
+
20
+ * Replace deprecated `Fixnum` with `Integer`.
21
+
22
+
23
+ == 1.9.0 (2016-02-03)
24
+
25
+ * Add new refinement {doc-base-url}/Enumerable/MapBy[Enumerable#map_by].
26
+
27
+
28
+ == 1.8.0 (2015-07-06)
29
+
30
+ * Add new refinement {doc-base-url}/Class/Descendants[Class#descendants].
31
+
32
+
33
+ == 1.7.0 (2015-07-05)
34
+
35
+ * Add new refinement {doc-base-url}/Enumerable/MapTo[Enumerable#map_to].
36
+ * Add new refinement {doc-base-url}/Array/Wrap[Array#wrap].
37
+ * Add new refinement {doc-base-url}/Enumerable/Many[Enumerable#many?].
38
+
39
+
40
+ == 1.6.0 (2015-05-16)
41
+
42
+ * Add new refinement {doc-base-url}/String/Camelcase[String#camelcase].
43
+ * Add new refinement {doc-base-url}/String/SnakeCase[String#snake_case].
44
+
45
+
46
+ == 1.5.0 (2015-05-03)
47
+
48
+ * Rename String refinement `#to_regexp` to `#to_re` to avoid bug https://bugs.ruby-lang.org/issues/11117[#11117] in MRI.
49
+
50
+
51
+ == 1.4.0 (2015-05-03)
52
+
53
+ * Add new refinement {doc-base-url}/String/ForceUTF8[String#force_utf8].
54
+
55
+
56
+ == 1.3.0 (2015-04-29)
57
+
58
+ * Add new refinement {doc-base-url}/String/ToRegexp[String#to_regexp].
59
+ * Add new refinement {doc-base-url}/String/RelativePathFrom[String#relative_path_from].
60
+ * Add new refinement {doc-base-url}/Hash/Except[Hash#except].
61
+ * Add new refinement {doc-base-url}/Hash/Only[Hash#only].
62
+
63
+
64
+ == 1.2.0 (2015-04-27)
65
+
66
+ * Add new refinement {doc-base-url}/String/Indent[String#indent].
67
+
68
+
69
+ == 1.1.0 (2015-04-25)
70
+
71
+ * Add new refinement {doc-base-url}/String/ToB[String#to_b].
72
+ * Change alias for operator `+` from `OpPlus` to `OpAdd` and for operator `-` from `OpMinus` to `OpSub`.
73
+ * Support operators `+@` (alias `OpPlus`) and `-@` (alias `OpMinus`).
74
+
75
+
76
+ == 1.0.0 (2015-04-02)
77
+
78
+ The first stable release.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright 2015-2017 Jakub Jirutka <jakub@jirutka.cz>.
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.adoc ADDED
@@ -0,0 +1,215 @@
1
+ = Corefines
2
+ Jakub Jirutka <https://github.com/jirutka[@jirutka]>
3
+ :source-language: ruby
4
+ // custom
5
+ :gem-name: corefines
6
+ :gem-version: 1.11.1
7
+ :gh-name: jirutka/{gem-name}
8
+ :gh-branch: master
9
+ :badge-style: flat
10
+ :doc-base-url: http://www.rubydoc.info/github/{gh-name}/{gh-branch}/Corefines
11
+
12
+ ifdef::env-github[]
13
+ image:https://img.shields.io/travis/{gh-name}/{gh-branch}.svg?style={badge-style}[Build Status, link="https://travis-ci.org/{gh-name}"]
14
+ image:https://img.shields.io/codeclimate/coverage/github/{gh-name}.svg?style={badge-style}[Test Coverage, link="https://codeclimate.com/github/{gh-name}"]
15
+ image:https://img.shields.io/codeclimate/github/{gh-name}.svg?style={badge-style}[Code Climate, link="https://codeclimate.com/github/{gh-name}"]
16
+ image:https://img.shields.io/gem/v/{gem-name}.svg?style={badge-style}[Gem Version, link="https://rubygems.org/gems/{gem-name}"]
17
+ image:https://img.shields.io/badge/yard-docs-blue.svg?style={badge-style}[Yard Docs, link="http://www.rubydoc.info/github/{gh-name}/{gh-branch}"]
18
+ endif::env-github[]
19
+
20
+ Corefines is a collection of general purpose _refinements_ for extending the core capabilities of Ruby’s built-in classes.
21
+ It also provides a <<compatibility-mode>> for older Ruby versions and alternative Ruby implementations that don’t support refinements (yet).
22
+
23
+
24
+ == Why refinements?
25
+
26
+ Extending core classes with so called monkey-paching pollutes the _global_ scope, so it affects all files on the `$LOAD_PATH`, i.e. whole application including used gems.
27
+ It’s not usually so big deal when you’re doing it in your application, but it’s very dangerous when used in a gem (library).
28
+ This can result in strange and hard to debug behaviour if another gem overrides a core class with the same method as your gem, but different implementation, and both gems are used together.
29
+
30
+ Refinements basically allows you to put monkey patches in an isolated namespace, so that your changes to core classes don’t affect other code.
31
+
32
+ TODO
33
+
34
+
35
+ == Installation
36
+
37
+ Add this line to your application’s Gemfile:
38
+
39
+ [source, subs="+attributes"]
40
+ gem '{gem-name}', '~> {gem-version}'
41
+
42
+ or to your gemspec:
43
+
44
+ [source, subs="+attributes"]
45
+ s.add_runtime_dependency '{gem-name}', '~> {gem-version}'
46
+
47
+ and then execute:
48
+
49
+ [source, sh]
50
+ $ bundle install
51
+
52
+
53
+ == Using
54
+
55
+ First, you must require `corefines` prior using:
56
+
57
+ [source]
58
+ require 'corefines'
59
+
60
+ This will _not_ activate any extensions (just register them), even when running in compatibility mode.
61
+ Extensions (refinements) are activated selectively with the method http://ruby-doc.org/core-2.2.0/Module.html#method-i-using[`using`].
62
+
63
+ Refinements are organized into modules by class which they refine, and further into submodules for individual methods.
64
+ When an extension refines multiple classes, then it’s included in a module named after their nearest common ancestor (superclass).
65
+
66
+ [source, plain]
67
+ Corefines::<CLASS>::<METHOD>
68
+
69
+ A single extension can be imported into the current scope classically, e.g.:
70
+
71
+ [source]
72
+ using Corefines::Object::ThenIf
73
+
74
+ or preferably using its “alias”:
75
+
76
+ [source]
77
+ using Corefines::Object::then_if
78
+
79
+ If you want to include all extensions for the class, then you can just import the parent module, e.g.:
80
+
81
+ [source]
82
+ using Corefines::Object
83
+
84
+ But more often you want to include multiple extensions for the class, but not all of them, e.g.:
85
+
86
+ [source]
87
+ using Corefines::Object::then_if
88
+ using Corefines::Object::in?
89
+
90
+ this can be abbreviated to:
91
+
92
+ [source]
93
+ using Corefines::Object[:then_if, :in?]
94
+
95
+ If you feel that _Corefines_ is too long, then you can also use abbreviation _CF_ instead:
96
+
97
+ [source]
98
+ using CF::Object::then_if
99
+
100
+ Refinements can be activated (with `using`) at top-level (per file), inside a class, module or a method.
101
+
102
+
103
+ == Compatibility mode
104
+
105
+ Refinements are still a young feature, so there’s a possibility that your gem or application will have to work on a Ruby platform that doesn’t fully support refinements yet.
106
+
107
+ The main Ruby implementation, https://en.wikipedia.org/wiki/Ruby_MRI[MRI] (aka CRuby), supports refinements since version 2.1.0 (https://www.ruby-lang.org/en/news/2013/12/25/ruby-2-1-0-is-released/[released in 25 Dec 2013]).
108
+ footnote:[Actually, refinements has been introduced to MRI in 2.0.0, as an experimental feature. However, its design and implementation has been changed then, so refinements in 2.0.x and 2.1+ behaves quite differently.]
109
+ Version 2.0.0 (https://www.ruby-lang.org/en/news/2013/02/24/ruby-2-0-0-p0-is-released/[released in 24 Feb 2013]) is still supported though.
110
+ http://www.jruby.org/[JRuby] doesn’t support refinements yet, it’s planned in the upcoming version 9.0.0.0 (https://github.com/jruby/jruby/issues/1062[#1062]).
111
+ http://rubini.us/[Rubinius] also doesn’t support refinements yet.
112
+
113
+ This gem is a collection of pure refinements, and yet, it works even on older Rubies that don’t support refinements.
114
+ Wait… how?
115
+ Well, when you use the gem with an older Ruby, it’s actually cheating.
116
+ Instead of locally scoped changes, it falls back to global monkey-patching.
117
+
118
+ The Corefines gem adds `refine` and `using` methods to the core classes, so you can define and use refinements just like in newer Rubies.
119
+ But internally it works very differently.
120
+ The `refine` method adds a given block to a collection of pending “refinements” inside its module.
121
+ When `using` is called _first time_ for the module, it _evaluates_ module’s “refinements” in context of the target classes (i.e. do a monkey-patch).
122
+
123
+ Not ideal indeed, but probably the best of what we can achieve.
124
+
125
+
126
+ == List of refinements
127
+
128
+ * {doc-base-url}/Array[Array]
129
+ ** {doc-base-url}/Array/Second[#second]
130
+ ** {doc-base-url}/Array/Third[#third]
131
+ ** {doc-base-url}/Array/Wrap[.wrap]
132
+ * {doc-base-url}/Class[Class]
133
+ ** {doc-base-url}/Class/Descendants[#descendants]
134
+ * {doc-base-url}/Enumerable[Enumerable]
135
+ ** {doc-base-url}/Enumerable/IndexBy[#index_by]
136
+ ** {doc-base-url}/Enumerable/Many[#many?]
137
+ ** {doc-base-url}/Enumerable/MapBy[#map_by]
138
+ ** {doc-base-url}/Enumerable/MapSend[#map_send]
139
+ ** {doc-base-url}/Enumerable/MapTo[#map_to]
140
+ * {doc-base-url}/Hash[Hash]
141
+ ** {doc-base-url}/Hash/OpAdd[#+]
142
+ ** {doc-base-url}/Hash/Compact[#compact]
143
+ ** {doc-base-url}/Hash/Compact[#compact!]
144
+ ** {doc-base-url}/Hash/Except[#except]
145
+ ** {doc-base-url}/Hash/Except[#except!]
146
+ ** {doc-base-url}/Hash/FlatMap[#flat_map]
147
+ ** {doc-base-url}/Hash/Only[#only]
148
+ ** {doc-base-url}/Hash/Only[#only!]
149
+ ** {doc-base-url}/Hash/Recurse[#recurse]
150
+ ** {doc-base-url}/Hash/Rekey[#rekey]
151
+ ** {doc-base-url}/Hash/Rekey[#rekey!]
152
+ ** {doc-base-url}/Hash/SymbolizeKeys[#symbolize_keys]
153
+ ** {doc-base-url}/Hash/SymbolizeKeys[#symbolize_keys!]
154
+ * {doc-base-url}/Module[Module]
155
+ ** {doc-base-url}/Module/AliasClassMethod[#alias_class_method]
156
+ ** {doc-base-url}/Module/AliasMethodChain[#alias_method_chain]
157
+ * {doc-base-url}/Object[Object]
158
+ ** {doc-base-url}/Object/Blank[#blank?]
159
+ ** {doc-base-url}/Object/DeepDup[#deep_dup]
160
+ ** {doc-base-url}/Object/Else[#else]
161
+ ** {doc-base-url}/Object/In[#in?]
162
+ ** {doc-base-url}/Object/InstanceValues[#instance_values]
163
+ ** {doc-base-url}/Object/Blank[#presence]
164
+ ** {doc-base-url}/Object/Then[#then]
165
+ ** {doc-base-url}/Object/ThenIf[#then_if]
166
+ ** {doc-base-url}/Object/Try[#try]
167
+ ** {doc-base-url}/Object/Try[#try!]
168
+ * {doc-base-url}/String[String]
169
+ ** {doc-base-url}/String/Camelcase[#camelcase]
170
+ ** {doc-base-url}/String/Color[#color]
171
+ ** {doc-base-url}/String/Concat[#concat!]
172
+ ** {doc-base-url}/String/Decolor[#decolor]
173
+ ** {doc-base-url}/String/ForceUTF8[#force_utf8]
174
+ ** {doc-base-url}/String/ForceUTF8[#force_utf8!]
175
+ ** {doc-base-url}/String/Indent[#indent]
176
+ ** {doc-base-url}/String/RelativePathFrom[#relative_path_from]
177
+ ** {doc-base-url}/String/Remove[#remove]
178
+ ** {doc-base-url}/String/SnakeCase[#snake_case]
179
+ ** {doc-base-url}/String/ToB[#to_b]
180
+ ** {doc-base-url}/String/ToRe[#to_re]
181
+ ** {doc-base-url}/String/Unindent[#unindent] (alias `#strip_heredoc`)
182
+ * {doc-base-url}/Symbol[Symbol]
183
+ ** {doc-base-url}/Symbol/Call[#call]
184
+
185
+
186
+ == Acknowledgement
187
+
188
+ Most of the extension methods are based on, or highly inspired from:
189
+
190
+ * https://github.com/rails/rails/tree/master/activesupport[Active Support (Ruby extensions)]
191
+ * https://github.com/rubyworks/facets[Ruby Facets]
192
+ * https://github.com/gregwebs/methodchain[methodchain]
193
+ * https://github.com/fazibear/colorize[colorize]
194
+ * https://github.com/seamusabshere/to_regexp[to_regexp]
195
+
196
+ Very useful articles about refinements and how to “trick” them:
197
+
198
+ * https://www.new-bamboo.co.uk/blog/2014/02/05/refinements-under-the-knife/[
199
+ Refinements under the knife] by https://github.com/leemachin[@leemachin]
200
+ * http://qiita.com/joker1007/items/68d066a12bc763bd2cb4[Refinement関係の小技とできない事をまとめてみた] by https://github.com/joker1007[@joker1007]
201
+
202
+
203
+ == Contributing
204
+
205
+ . Fork it.
206
+ . Create your feature branch (`git checkout -b my-new-feature`).
207
+ . Commit your changes (`git commit -am 'Add some feature'`).
208
+ . Push to the branch (`git push origin my-new-feature`).
209
+ . Create a new Pull Request.
210
+
211
+
212
+ == License
213
+
214
+ This project is licensed under http://opensource.org/licenses/MIT/[MIT License].
215
+ For the full text of the license, see the link:LICENSE[LICENSE] file.
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ begin
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :test => :spec
9
+ task :default => :spec
10
+
11
+ rescue LoadError => e
12
+ warn "#{e.path} is not available"
13
+ end
14
+
15
+ begin
16
+ require 'yard'
17
+
18
+ # options are defined in .yardopts
19
+ YARD::Rake::YardocTask.new(:yard)
20
+
21
+ rescue LoadError => e
22
+ warn "#{e.path} is not available"
23
+ end
@@ -179,7 +179,11 @@ module Corefines
179
179
  #
180
180
  # @example
181
181
  # hash = {"a" => 1, "b" => {"c" => {"e" => 5}, "d" => 4}}
182
- # hash.recurse!(&:symbolize_keys!) # => {a: 1, b: {c: {e: 5}, d: 4}}
182
+ #
183
+ # hash.recurse { |h| h.symbolize_keys } # => {a: 1, b: {c: {e: 5}, d: 4}}
184
+ # hash # => {"a" => 1, "b" => {"c" => {"e" => 5}, "d" => 4}}
185
+ #
186
+ # hash.recurse { |h| h.symbolize_keys! } # => {a: 1, b: {c: {e: 5}, d: 4}}
183
187
  # hash # => {a: 1, b: {c: {e: 5}, d: 4}}
184
188
  #
185
189
  # @yield [Hash] gives this hash and every sub-hash (recursively).
@@ -243,20 +247,28 @@ module Corefines
243
247
  refine ::Hash do
244
248
  def rekey(key_map = nil, &block)
245
249
  fail ArgumentError, "provide key_map, or block, not both" if key_map && block
246
- block = ->(k, _) { k.to_sym rescue k } if !key_map && !block
247
250
 
248
251
  # Note: self.dup is used to preserve the default_proc.
249
- if block
250
- # This is needed for "symbol procs" (e.g. &:to_s).
251
- transform_key = block.arity.abs == 1 ? ->(k, _) { block[k] } : block
252
+ if key_map
253
+ key_map.each_with_object(dup) do |(from, to), hash|
254
+ hash[to] = hash.delete(from) if hash.key? from
255
+ end
256
+ else
257
+ transform_key = if !block
258
+ ->(k, _) { k.to_sym rescue k }
259
+ elsif block.arity.abs == 1 || block.lambda? && block.arity != 2
260
+ # This is needed for "symbol procs" (e.g. &:to_s). It behaves
261
+ # differently since Ruby 3.0!
262
+ # Ruby <3.0: block.arity => -1, block.lambda? => false
263
+ # Ruby 3.0: block.arity => -2, block.lambda? => true
264
+ ->(k, _) { block[k] }
265
+ else
266
+ block
267
+ end
252
268
 
253
269
  each_with_object(dup.clear) do |(key, value), hash|
254
270
  hash[ transform_key[key, value] ] = value
255
271
  end
256
- else
257
- key_map.each_with_object(dup) do |(from, to), hash|
258
- hash[to] = hash.delete(from) if hash.key? from
259
- end
260
272
  end
261
273
  end
262
274
 
@@ -1,3 +1,3 @@
1
1
  module Corefines
2
- VERSION = '1.11.0'.freeze
2
+ VERSION = '1.11.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: corefines
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.11.0
4
+ version: 1.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jakub Jirutka
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-15 00:00:00.000000000 Z
11
+ date: 2021-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '10.0'
47
+ version: '12.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '10.0'
54
+ version: '12.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +86,14 @@ dependencies:
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0.8'
89
+ version: '0.9'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0.8'
96
+ version: '0.9'
97
97
  description: |
98
98
  Corefines is a collection of general purpose refinements for extending the core
99
99
  capabilities of Ruby's built-in classes. It also provides a compatibility mode
@@ -104,6 +104,10 @@ executables: []
104
104
  extensions: []
105
105
  extra_rdoc_files: []
106
106
  files:
107
+ - CHANGELOG.adoc
108
+ - LICENSE
109
+ - README.adoc
110
+ - Rakefile
107
111
  - lib/corefines.rb
108
112
  - lib/corefines/array.rb
109
113
  - lib/corefines/class.rb
@@ -181,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
185
  version: '0'
182
186
  requirements: []
183
187
  rubyforge_project:
184
- rubygems_version: 2.6.13
188
+ rubygems_version: 2.7.3
185
189
  signing_key:
186
190
  specification_version: 4
187
191
  summary: A collection of refinements for Ruby core classes.