corefines 1.11.0 → 1.11.1

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: 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.