corefines 1.6.0 → 1.7.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.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +7 -0
- data/README.adoc +7 -4
- data/lib/corefines/array.rb +60 -0
- data/lib/corefines/enumerable.rb +67 -0
- data/lib/corefines/string.rb +7 -3
- data/lib/corefines/version.rb +1 -1
- data/spec/array/wrap_spec.rb +50 -0
- data/spec/enumerable/many_spec.rb +66 -0
- data/spec/enumerable/map_to_spec.rb +15 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea0feea695c1bc742c15a3ca74b9e4aa98d1d632
|
4
|
+
data.tar.gz: cce9dd830c78ddec528b274c8a42119dd79bf51d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36952b5e7ac736ae14986a44737fd7232a7ead39091ac4075b67b470dee862e260876511b757b316e326e95aa869fac6415adf6a7c775e7da9f34c72fe43bdcf
|
7
|
+
data.tar.gz: b70e5551f42ad5f19f44e65427bbf9d09c59b78a167e46e022ee1c33a65b81ae283fd497cd52b0acbd83ad5e416b8c3ba6932e0993e0900b47120d3a7cabd547
|
data/CHANGELOG.adoc
CHANGED
@@ -3,6 +3,13 @@
|
|
3
3
|
:doc-base-url: http://www.rubydoc.info/github/jirutka/corefines/Corefines
|
4
4
|
:issue-uri: {repo-uri}/issues
|
5
5
|
|
6
|
+
== 1.7.0 (2015-07-05)
|
7
|
+
|
8
|
+
* Add new refinement {doc-base-url}/Enumerable/MapTo[Enumerable#map_to].
|
9
|
+
* Add new refinement {doc-base-url}/Array/Wrap[Array#wrap].
|
10
|
+
* Add new refinement {doc-base-url}/Enumerable/Many[Enumerable#many?].
|
11
|
+
|
12
|
+
|
6
13
|
== 1.6.0 (2015-05-16)
|
7
14
|
|
8
15
|
* Add new refinement {doc-base-url}/String/Camelcase[String#camelcase].
|
data/README.adoc
CHANGED
@@ -11,14 +11,14 @@ ifdef::env-github[:idprefix: user-content-]
|
|
11
11
|
:gh-name: jirutka/{gem-name}
|
12
12
|
:gh-branch: master
|
13
13
|
:badge-style: flat
|
14
|
-
:doc-base-url: http://www.rubydoc.info/github/
|
14
|
+
:doc-base-url: http://www.rubydoc.info/github/{gh-name}/{gh-branch}/Corefines
|
15
15
|
|
16
16
|
ifdef::env-github[]
|
17
17
|
image:https://img.shields.io/travis/{gh-name}/{gh-branch}.svg?style={badge-style}[Build Status, link="https://travis-ci.org/{gh-name}"]
|
18
18
|
image:https://img.shields.io/codeclimate/coverage/github/{gh-name}.svg?style={badge-style}[Test Coverage, link="https://codeclimate.com/github/{gh-name}"]
|
19
19
|
image:https://img.shields.io/codeclimate/github/{gh-name}.svg?style={badge-style}[Code Climate, link="https://codeclimate.com/github/{gh-name}"]
|
20
20
|
image:https://img.shields.io/gem/v/{gem-name}.svg?style={badge-style}[Gem Version, link="https://rubygems.org/gems/{gem-name}"]
|
21
|
-
image:https://img.shields.io/badge/yard-docs-blue.svg?style={badge-style}[Yard Docs, link="http://www.rubydoc.info/github/{gh-name}/
|
21
|
+
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}"]
|
22
22
|
endif::env-github[]
|
23
23
|
|
24
24
|
Corefines is a collection of general purpose _refinements_ for extending the core capabilities of Ruby’s built-in classes.
|
@@ -41,12 +41,12 @@ TODO
|
|
41
41
|
Add this line to your application’s Gemfile:
|
42
42
|
|
43
43
|
[source]
|
44
|
-
gem 'corefines', '~> 1.
|
44
|
+
gem 'corefines', '~> 1.7'
|
45
45
|
|
46
46
|
or to your gemspec:
|
47
47
|
|
48
48
|
[source]
|
49
|
-
s.add_runtime_dependency 'corefines', '~> 1.
|
49
|
+
s.add_runtime_dependency 'corefines', '~> 1.7'
|
50
50
|
|
51
51
|
and then execute:
|
52
52
|
|
@@ -132,9 +132,12 @@ Not ideal indeed, but probably the best of what we can achieve.
|
|
132
132
|
* {doc-base-url}/Array[Array]
|
133
133
|
** {doc-base-url}/Array/Second[#second]
|
134
134
|
** {doc-base-url}/Array/Third[#third]
|
135
|
+
** {doc-base-url}/Array/Wrap[.wrap]
|
135
136
|
* {doc-base-url}/Enumerable[Enumerable]
|
136
137
|
** {doc-base-url}/Enumerable/IndexBy[#index_by]
|
138
|
+
** {doc-base-url}/Enumerable/Many[#many?]
|
137
139
|
** {doc-base-url}/Enumerable/MapSend[#map_send]
|
140
|
+
** {doc-base-url}/Enumerable/MapTo[#map_to]
|
138
141
|
* {doc-base-url}/Hash[Hash]
|
139
142
|
** {doc-base-url}/Hash/OpAdd[#+]
|
140
143
|
** {doc-base-url}/Hash/Compact[#compact]
|
data/lib/corefines/array.rb
CHANGED
@@ -25,6 +25,66 @@ module Corefines
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
##
|
29
|
+
# @!method self.wrap(object)
|
30
|
+
# Wraps its argument in an array unless it is already an array (or
|
31
|
+
# array-like).
|
32
|
+
#
|
33
|
+
# Specifically:
|
34
|
+
#
|
35
|
+
# * If the argument is +nil+ an empty list is returned.
|
36
|
+
# * Otherwise, if the argument responds to +to_ary+ it is invoked, and
|
37
|
+
# its result returned.
|
38
|
+
# * Otherwise, returns an array with the argument as its single element.
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# Array.wrap(nil) # => []
|
42
|
+
# Array.wrap([1, 2, 3]) # => [1, 2, 3]
|
43
|
+
# Array.wrap(0) # => [0]
|
44
|
+
#
|
45
|
+
# This method is similar in purpose to <tt>Kernel#Array</tt>, but there
|
46
|
+
# are some differences:
|
47
|
+
#
|
48
|
+
# * If the argument responds to +to_ary+ the method is invoked.
|
49
|
+
# <tt>Kernel#Array</tt> moves on to try +to_a+ if the returned value is
|
50
|
+
# +nil+, but <tt>Array.wrap</tt> returns +nil+ right away.
|
51
|
+
# * If the returned value from +to_ary+ is neither +nil+ nor an +Array+
|
52
|
+
# object, <tt>Kernel#Array</tt> raises an exception, while
|
53
|
+
# <tt>Array.wrap</tt> does not, it just returns the value.
|
54
|
+
# * It does not call +to_a+ on the argument, but returns an empty array
|
55
|
+
# if argument is +nil+.
|
56
|
+
#
|
57
|
+
# The second point is easily explained with some enumerables:
|
58
|
+
#
|
59
|
+
# Array(foo: :bar) # => [[:foo, :bar]]
|
60
|
+
# Array.wrap(foo: :bar) # => [{:foo=>:bar}]
|
61
|
+
#
|
62
|
+
# There's also a related idiom that uses the splat operator:
|
63
|
+
#
|
64
|
+
# [*object]
|
65
|
+
#
|
66
|
+
# which returns <tt>[]</tt> for +nil+, but calls to
|
67
|
+
# <tt>Array(object)</tt> otherwise.
|
68
|
+
#
|
69
|
+
# The differences with <tt>Kernel#Array</tt> explained above apply to the
|
70
|
+
# rest of <tt>object</tt>s.
|
71
|
+
#
|
72
|
+
# @return [Array]
|
73
|
+
#
|
74
|
+
module Wrap
|
75
|
+
refine ::Array.singleton_class do
|
76
|
+
def wrap(object)
|
77
|
+
if object.nil?
|
78
|
+
[]
|
79
|
+
elsif object.respond_to? :to_ary
|
80
|
+
object.to_ary || [object]
|
81
|
+
else
|
82
|
+
[object]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
28
88
|
include Support::AliasSubmodules
|
29
89
|
end
|
30
90
|
end
|
data/lib/corefines/enumerable.rb
CHANGED
@@ -36,6 +36,47 @@ module Corefines
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
##
|
40
|
+
# @!method many?
|
41
|
+
# Returns +true+ if the enumerable has more than one element.
|
42
|
+
#
|
43
|
+
# This method is functionally equivalent to <tt>enum.to_a.size > 1</tt>,
|
44
|
+
# or <tt>enum.select { ... }.length > 1</tt> when the block is given.
|
45
|
+
#
|
46
|
+
# @example
|
47
|
+
# [1].many? # => false
|
48
|
+
# [1, 2].many? # => true
|
49
|
+
# [1, 2, 3].many? # => true
|
50
|
+
# [1, nil].many? # => true
|
51
|
+
# [1, 2, 3].many? { |n| n > 2 } # => false
|
52
|
+
#
|
53
|
+
# @overload many?
|
54
|
+
# @return [Boolean] +true+ if the enumerable has more than one element.
|
55
|
+
#
|
56
|
+
# @overload many?(&block)
|
57
|
+
# @yield [obj] gives each element to the block.
|
58
|
+
# @return [Boolean] +true+ if the block returns a truthy value (i.e.
|
59
|
+
# other than +nil+ and +false+) more than once.
|
60
|
+
#
|
61
|
+
module Many
|
62
|
+
Support.classes_including_module(::Enumerable) do |klass|
|
63
|
+
|
64
|
+
refine klass do
|
65
|
+
def many?
|
66
|
+
cnt = 0
|
67
|
+
if block_given?
|
68
|
+
any? do |element|
|
69
|
+
cnt += 1 if yield element
|
70
|
+
cnt > 1
|
71
|
+
end
|
72
|
+
else
|
73
|
+
any? { (cnt += 1) > 1 }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
39
80
|
##
|
40
81
|
# @!method map_send(method_name, *args, &block)
|
41
82
|
# Sends a message to each element and collects the result.
|
@@ -59,6 +100,32 @@ module Corefines
|
|
59
100
|
end
|
60
101
|
end
|
61
102
|
|
103
|
+
##
|
104
|
+
# @!method map_to(klass)
|
105
|
+
# Maps each element of this _enum_ into the _klass_ via constructor.
|
106
|
+
#
|
107
|
+
# @example
|
108
|
+
# ['/tmp', '/var/tmp'].map_to(Pathname) # => [#<Pathname:/tmp>, #<Pathname:/var/tmp>]
|
109
|
+
#
|
110
|
+
# @param klass [#new] the klass to map each element to.
|
111
|
+
# @return [Enumerable] a new array with instances of the _klass_ for
|
112
|
+
# every element in _enum_.
|
113
|
+
#
|
114
|
+
module MapTo
|
115
|
+
Support.classes_including_module(::Enumerable) do |klass|
|
116
|
+
|
117
|
+
refine klass do
|
118
|
+
def map_to(klass)
|
119
|
+
map { |e| klass.new(e) }
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
62
125
|
include Support::AliasSubmodules
|
126
|
+
|
127
|
+
class << self
|
128
|
+
alias_method :many?, :many
|
129
|
+
end
|
63
130
|
end
|
64
131
|
end
|
data/lib/corefines/string.rb
CHANGED
@@ -25,6 +25,10 @@ module Corefines
|
|
25
25
|
# "camel::ca-se-y".camelcase(':', '-') # => "camelCaSeY"
|
26
26
|
# "camel42case".camelcase(/[0-9]+/) # => "camelCase"
|
27
27
|
#
|
28
|
+
# @param *separators [String, Regexp] the patterns used to determine
|
29
|
+
# where capitalization should occur. Defaults to <tt>/_+/</tt> and
|
30
|
+
# <tt>\s+</tt>.
|
31
|
+
#
|
28
32
|
# @overload camelcase(first_letter, *separators)
|
29
33
|
# @example
|
30
34
|
# "camel case".camelcase(:upper) # => "CamelCase"
|
@@ -33,10 +37,10 @@ module Corefines
|
|
33
37
|
# @param first_letter [:upper, :lower] desired case of the first
|
34
38
|
# character of a word - +:upper+ to be upcased, or +:lower+ to
|
35
39
|
# be downcased.
|
40
|
+
# @param *separators [String, Regexp] the patterns used to determine
|
41
|
+
# where capitalization should occur. Defaults to <tt>/_+/</tt> and
|
42
|
+
# <tt>\s+</tt>.
|
36
43
|
#
|
37
|
-
# @param *separators [String, Regexp] the patterns used to determine
|
38
|
-
# where capitalization should occur. Defaults to <tt>/_+/</tt> and
|
39
|
-
# <tt>\s+</tt>.
|
40
44
|
# @return [String] a copy of the _str_ converted to camelcase.
|
41
45
|
#
|
42
46
|
module Camelcase
|
data/lib/corefines/version.rb
CHANGED
@@ -0,0 +1,50 @@
|
|
1
|
+
describe Array do
|
2
|
+
using Corefines::Array::wrap
|
3
|
+
|
4
|
+
describe '.wrap' do
|
5
|
+
|
6
|
+
context "array" do
|
7
|
+
it "returns the given array unchanged" do
|
8
|
+
ary = ['foo', 'bar']
|
9
|
+
expect( Array.wrap(ary) ).to be ary
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "nil" do
|
14
|
+
it "returns an empty array" do
|
15
|
+
expect( Array.wrap(nil) ).to eq []
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "an object" do
|
20
|
+
it "returns it wrapped in an array" do
|
21
|
+
o = Object.new
|
22
|
+
expect( Array.wrap(o) ).to eq [o]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "string" do
|
27
|
+
it "returns it wrapped in an array" do
|
28
|
+
expect( Array.wrap("foo\nbar") ).to eq ["foo\nbar"]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "object with #to_ary" do
|
33
|
+
|
34
|
+
it "returns result of #to_ary" do
|
35
|
+
o = Class.new { def to_ary; ['foo', 'bar'] end }.new
|
36
|
+
expect( Array.wrap(o) ).to eq o.to_ary
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns wrapped if #to_ary returns nil" do
|
40
|
+
o = Class.new { def to_ary; nil end }.new
|
41
|
+
expect( Array.wrap(o) ).to eq [o]
|
42
|
+
end
|
43
|
+
|
44
|
+
it "doesn't complain if #to_ary doesn't return an array" do
|
45
|
+
o = Class.new { def to_ary; :not_an_array end }.new
|
46
|
+
expect( Array.wrap(o) ).to eq o.to_ary
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
describe Enumerable do
|
2
|
+
using Corefines::Enumerable::many?
|
3
|
+
|
4
|
+
describe '#many?' do
|
5
|
+
|
6
|
+
shared_examples :without_block do |enum, expected|
|
7
|
+
context enum.class do
|
8
|
+
it { expect( enum.many? ).to be expected }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context "when empty" do
|
13
|
+
[ [], Set.new, {} ].each do |enum|
|
14
|
+
include_examples :without_block, enum, false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "when one element" do
|
19
|
+
[ [42], Set.new([42]), {a: 42} ].each do |enum|
|
20
|
+
include_examples :without_block, enum, false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when two elements" do
|
25
|
+
[ [1, 2], Set.new([1, 2]), {a: 1, b: 2} ].each do |enum|
|
26
|
+
include_examples :without_block, enum, true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when two nil elements" do
|
31
|
+
[ [nil, nil], {a: nil, b: nil} ].each do |enum|
|
32
|
+
include_examples :without_block, enum, true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when more than two elements" do
|
37
|
+
[ [1, 2, 3], Set.new([1, 2, 3]), {a: 1, b: 2, c: 3} ].each do |enum|
|
38
|
+
include_examples :without_block, enum, true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
context "with block" do
|
44
|
+
|
45
|
+
context "that yields true for one element" do
|
46
|
+
context Array do
|
47
|
+
it { expect( [1, 2].many? { |n| n > 1 } ).to eq false }
|
48
|
+
end
|
49
|
+
|
50
|
+
context Hash do
|
51
|
+
it { expect( {a: 1, b: 2}.many? { |k, v| v > 1 } ).to eq false }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "that yield true for two elements" do
|
56
|
+
context Array do
|
57
|
+
it { expect( [1, 2].many? { |n| n > 0 } ).to eq true }
|
58
|
+
end
|
59
|
+
|
60
|
+
context Hash do
|
61
|
+
it { expect( {a: 1, b: 2}.many? { |k, v| k.is_a?(Symbol) } ).to eq true }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
describe Enumerable do
|
4
|
+
using Corefines::Enumerable::map_to
|
5
|
+
|
6
|
+
describe '#map_to' do
|
7
|
+
|
8
|
+
context Array do
|
9
|
+
it "creates instance of the klass for every element and collects the result" do
|
10
|
+
ary = ['/tmp', '/var/tmp']
|
11
|
+
expect( ary.map_to(Pathname) ).to eq ary.map { |e| Pathname.new(e) }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
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.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jakub Jirutka
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-05
|
11
|
+
date: 2015-07-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|
@@ -122,8 +122,11 @@ files:
|
|
122
122
|
- lib/corefines/version.rb
|
123
123
|
- spec/array/second_spec.rb
|
124
124
|
- spec/array/third_spec.rb
|
125
|
+
- spec/array/wrap_spec.rb
|
125
126
|
- spec/enumerable/index_by_spec.rb
|
127
|
+
- spec/enumerable/many_spec.rb
|
126
128
|
- spec/enumerable/map_send_spec.rb
|
129
|
+
- spec/enumerable/map_to_spec.rb
|
127
130
|
- spec/hash/compact_spec.rb
|
128
131
|
- spec/hash/except_spec.rb
|
129
132
|
- spec/hash/only_spec.rb
|