crystal_goodies 1.0.0 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +268 -2
- data/lib/crystal_goodies/enumerable.rb +0 -1
- data/lib/crystal_goodies/object.rb +7 -7
- data/lib/crystal_goodies/string.rb +5 -74
- data/lib/crystal_goodies/version.rb +1 -1
- data/sig/enumerable.rbs +1 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ea56dd113383c09a481ff17f3a762e3e7924a1b471404ab97cb3a86ea813cdd
|
4
|
+
data.tar.gz: 6306d0c2152e93bc8ac5bfc54c2936ddec63be85f2fc874cacd59e5b236ccf44
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c7085bd6883530c41ed175e8c61ec906df0e082d455584c24f681a37a952427184fb4dd7f2deac06f7b280f63505fe6b0120535cf6b1f247858a631cea9c051a
|
7
|
+
data.tar.gz: bfa816894dc44a773cb94ab0e68f6906d30e296e7f2dd5379fef9cf62ab040c41637f3e859bd6fad36b2e87e357f32c4c7d80a8fbf14b5dcc6b6579d49ea8e6d
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
## 💡 About
|
4
4
|
|
5
|
-
Class's methods port from Crystal.
|
5
|
+
Class's methods convenient for scripting port from Crystal.
|
6
6
|
|
7
7
|
## 📥 Installation
|
8
8
|
|
@@ -25,10 +25,276 @@ In Ruby do:
|
|
25
25
|
```rb
|
26
26
|
require 'crystal_goodies'
|
27
27
|
```
|
28
|
-
|
28
|
+
|
29
|
+
Only require methods to access through module `CrystalGoodies`.
|
30
|
+
|
31
|
+
```rb
|
32
|
+
require 'crystal_goodies/object'
|
33
|
+
require 'crystal_goodies/integer'
|
34
|
+
require 'crystal_goodies/string'
|
35
|
+
require 'crystal_goodies/array'
|
36
|
+
require 'crystal_goodies/enumerable'
|
37
|
+
```
|
38
|
+
|
39
|
+
Only require class extensions.
|
40
|
+
|
41
|
+
```rb
|
42
|
+
require 'crystal_goodies/object/extensions'
|
43
|
+
require 'crystal_goodies/integer/extensions'
|
44
|
+
require 'crystal_goodies/string/extensions'
|
45
|
+
require 'crystal_goodies/array/extensions'
|
46
|
+
require 'crystal_goodies/enumerable/extensions'
|
47
|
+
```
|
48
|
+
|
49
|
+
### Object
|
50
|
+
|
51
|
+
#### in?(*collection) -> true, false
|
52
|
+
|
53
|
+
Returns `true` if `self` is included in the *collection* argument.
|
54
|
+
|
55
|
+
```
|
56
|
+
10.in?(0..100) # => true
|
57
|
+
10.in?(0, 1, 10) # => true
|
58
|
+
10.in?(:foo, :bar) # => false
|
59
|
+
```
|
60
|
+
|
61
|
+
### Integer
|
62
|
+
|
63
|
+
#### divisible_by?(num) -> true, false
|
64
|
+
|
65
|
+
Returns `true` if `self` is divisible by *num*.
|
66
|
+
|
67
|
+
```
|
68
|
+
6.divisible_by? 3 # => true
|
69
|
+
6.divisible_by? 2 # => true
|
70
|
+
5.divisible_by? 3 # => false
|
71
|
+
```
|
72
|
+
|
73
|
+
#### to(limit) { |i| ... } -> self
|
74
|
+
|
75
|
+
Call `upto` or `downto` depend on the *limit*.
|
76
|
+
|
77
|
+
### String
|
78
|
+
|
79
|
+
#### camelcase(options, lower: false) -> String
|
80
|
+
|
81
|
+
Converts underscores to camelcase boundaries.
|
82
|
+
|
83
|
+
If *lower* is true, lower camelcase will be returned (the first letter is downcased).
|
84
|
+
|
85
|
+
```
|
86
|
+
"eiffel_tower".camelcase # => "EiffelTower"
|
87
|
+
"empire_state_building".camelcase(lower: true) # => "empireStateBuilding"
|
88
|
+
```
|
89
|
+
|
90
|
+
#### titleize(options) -> String
|
91
|
+
|
92
|
+
Returns a new `String` with the first letter after any space converted to uppercase and every
|
93
|
+
other letter converted to lowercase.
|
94
|
+
|
95
|
+
```
|
96
|
+
"hEllO tAb\tworld".titleize # => "Hello Tab\tWorld"
|
97
|
+
" spaces before".titleize # => " Spaces Before"
|
98
|
+
"x-men: the last stand".titleize # => "X-men: The Last Stand"
|
99
|
+
```
|
100
|
+
|
101
|
+
#### underscore(options) -> String
|
102
|
+
|
103
|
+
Converts camelcase boundaries to underscores.
|
104
|
+
|
105
|
+
```
|
106
|
+
"DoesWhatItSaysOnTheTin".underscore # => "does_what_it_says_on_the_tin"
|
107
|
+
"PartyInTheUSA".underscore # => "party_in_the_usa"
|
108
|
+
"HTTP_CLIENT".underscore # => "http_client"
|
109
|
+
"3.14IsPi".underscore # => "3.14_is_pi"
|
110
|
+
```
|
111
|
+
|
112
|
+
#### dasherize(options) -> String
|
113
|
+
|
114
|
+
Converts camelcase boundaries to kebabcase.
|
115
|
+
|
116
|
+
```
|
117
|
+
"DoesWhatItSaysOnTheTin".dasherize # => "does-what-it-says-on-the-tin"
|
118
|
+
"PartyInTheUSA".dasherize # => "party-in-the-usa"
|
119
|
+
"HTTP_CLIENT".dasherize # => "http-client"
|
120
|
+
"3.14IsPi".dasherize # => "3.14-is-pi"
|
121
|
+
```
|
122
|
+
|
123
|
+
#### blank? -> true, false
|
124
|
+
|
125
|
+
Returns `true` if this string consists exclusively of unicode whitespace.
|
126
|
+
|
127
|
+
```
|
128
|
+
"".blank? # => true
|
129
|
+
" ".blank? # => true
|
130
|
+
" a ".blank? # => false
|
131
|
+
```
|
132
|
+
|
133
|
+
#### presence -> self, nil
|
134
|
+
|
135
|
+
Returns `self` unless `#blank?` is `true` in which case it returns `nil`.
|
136
|
+
|
137
|
+
```
|
138
|
+
"a".presence # => "a"
|
139
|
+
"".presence # => nil
|
140
|
+
" ".presence # => nil
|
141
|
+
" a ".presence # => " a "
|
142
|
+
```
|
143
|
+
|
144
|
+
#### delete_at(...) -> String
|
145
|
+
|
146
|
+
Returns a new string that results from deleting characters with `slice`.
|
147
|
+
|
148
|
+
#### to(limit, exclusive = false) -> self
|
149
|
+
|
150
|
+
Call `upto` or `downto` depend on the *limit*.
|
151
|
+
|
152
|
+
### Array
|
153
|
+
|
154
|
+
#### skip(count) -> Array
|
155
|
+
|
156
|
+
Returns an `Array` with the first *count* elements removed
|
157
|
+
from the original array.
|
158
|
+
|
159
|
+
If *count* is bigger than the number of elements in the array, returns an empty array.
|
160
|
+
|
161
|
+
```
|
162
|
+
[1, 2, 3, 4, 5, 6].skip(3) # => [4, 5, 6]
|
163
|
+
```
|
164
|
+
|
165
|
+
#### truncate(...) -> elements
|
166
|
+
|
167
|
+
Removes all elements except the *count* or less (if there aren't enough)
|
168
|
+
elements starting at the given *start* index. Returns `self`.
|
169
|
+
|
170
|
+
Negative values of *start* count from the end of the array.
|
171
|
+
|
172
|
+
Raises `IndexError` if the *start* index is out of range.
|
173
|
+
|
174
|
+
Raises `ArgumentError` if *count* is negative.
|
175
|
+
|
176
|
+
```
|
177
|
+
a = [0, 1, 4, 9, 16, 25]
|
178
|
+
a.truncate(2, 3) # => [4, 9, 16]
|
179
|
+
a # => [4, 9, 16]
|
180
|
+
```
|
181
|
+
|
182
|
+
Or removes all elements except those within the given *range*. Returns `self`.
|
183
|
+
|
184
|
+
```
|
185
|
+
a = [0, 1, 4, 9, 16, 25]
|
186
|
+
a.truncate(1..-3) # => [1, 4, 9]
|
187
|
+
a # => [1, 4, 9]
|
188
|
+
```
|
189
|
+
|
190
|
+
### Enumerable
|
191
|
+
|
192
|
+
#### empty? -> true, false
|
193
|
+
|
194
|
+
Returns `true` if `self` is empty, `false` otherwise.
|
195
|
+
|
196
|
+
```
|
197
|
+
[].empty? # => true
|
198
|
+
[1].empty? # => false
|
199
|
+
```
|
200
|
+
|
201
|
+
#### compact_map { ... } -> Array
|
202
|
+
|
203
|
+
Returns an `Array` with the results of running the block against each element
|
204
|
+
of the collection, removing `nil` values.
|
205
|
+
|
206
|
+
```
|
207
|
+
["Alice", "Bob"].map { |name| name.match(/^A./) } # => [#<MatchData "Al">, nil]
|
208
|
+
["Alice", "Bob"].compact_map { |name| name.match(/^A./) } # => [#<MatchData "Al">]
|
209
|
+
```
|
210
|
+
|
211
|
+
#### in_groups_of(size, filled_up_with = nil) -> Array
|
212
|
+
|
213
|
+
Returns an `Array` with chunks in the given size, eventually filled up
|
214
|
+
with given value or `nil`.
|
215
|
+
|
216
|
+
```
|
217
|
+
[1, 2, 3].in_groups_of(2, 0) # => [[1, 2], [3, 0]]
|
218
|
+
[1, 2, 3].in_groups_of(2) # => [[1, 2], [3, nil]]
|
219
|
+
```
|
220
|
+
|
221
|
+
#### skip_while { ... } -> Array
|
222
|
+
|
223
|
+
Skips elements up to, but not including, the first element for which
|
224
|
+
the block is falsey, and returns an `Array`
|
225
|
+
containing the remaining elements.
|
226
|
+
|
227
|
+
```
|
228
|
+
[1, 2, 3, 4, 5, 0].skip_while { _1 < 3 } # => [3, 4, 5, 0]
|
229
|
+
```
|
230
|
+
|
231
|
+
#### index_by { ... } -> Hash
|
232
|
+
|
233
|
+
Converts an `Enumerable` to a `Hash` by using the value returned by the block
|
234
|
+
as the hash key.
|
235
|
+
Be aware, if two elements return the same value as a key one will override
|
236
|
+
the other. If you want to keep all values, then you should probably use
|
237
|
+
`group_by` instead.
|
238
|
+
|
239
|
+
```
|
240
|
+
["Anna", "Ary", "Alice"].index_by(&:size)
|
241
|
+
# => {4 => "Anna", 3 => "Ary", 5 => "Alice"}
|
242
|
+
["Anna", "Ary", "Alice", "Bob"].index_by(&:size)
|
243
|
+
# => {4 => "Anna", 3 => "Bob", 5 => "Alice"}
|
244
|
+
```
|
245
|
+
|
246
|
+
#### tally_by(hash = {}) { ... } -> Hash
|
247
|
+
|
248
|
+
Tallies the collection. Accepts a *hash* to count occurrences.
|
249
|
+
The value corresponding to each element must be an integer.
|
250
|
+
Returns *hash* where the keys are the
|
251
|
+
elements and the values are numbers of elements in the collection
|
252
|
+
that correspond to the key after transformation by the given block.
|
253
|
+
|
254
|
+
```
|
255
|
+
hash = {}
|
256
|
+
words = ["Crystal", "Ruby"]
|
257
|
+
words.each { |word| word.chars.tally_by(hash, &:downcase) }
|
258
|
+
hash # => {"c" => 1, "r" => 2, "y" => 2, "s" => 1, "t" => 1, "a" => 1, "l" => 1, "u" => 1, "b" => 1}
|
259
|
+
```
|
260
|
+
|
261
|
+
#### min_of? { ... } -> min_element
|
262
|
+
|
263
|
+
Returns the element for which the passed block returns with the maximum value.
|
264
|
+
|
265
|
+
It compares using `>` so the block must return a type that supports that method
|
266
|
+
|
267
|
+
```
|
268
|
+
["Alice", "Bob"].max_by(&:size) # => "Alice"
|
269
|
+
```
|
270
|
+
|
271
|
+
Return `nil` if the collection is empty.
|
272
|
+
|
273
|
+
#### max_of? { ... } -> max_element
|
274
|
+
|
275
|
+
Returns the element for which the passed block returns with the minimum value.
|
276
|
+
|
277
|
+
It compares using `<` so the block must return a type that supports that method
|
278
|
+
|
279
|
+
```
|
280
|
+
["Alice", "Bob"].min_by(&:size) # => "Bob"
|
281
|
+
```
|
282
|
+
|
283
|
+
Return `nil` if the collection is empty.
|
284
|
+
|
285
|
+
#### minmax_of? { ... } -> [min_element, max_element]
|
286
|
+
|
287
|
+
Returns a `Array` with both the minimum and maximum values according to the passed block.
|
288
|
+
|
289
|
+
```
|
290
|
+
["Alice", "Bob", "Carl"].minmax_by(&:size) # => ["Bob", "Alice"]
|
291
|
+
```
|
292
|
+
|
293
|
+
Return `[nil, nil]` if the collection is empty.
|
29
294
|
|
30
295
|
## 💌 Credits
|
31
296
|
|
32
297
|
- [**Crystal**](https://crystal-lang.org) by [it's contributors](https://github.com/crystal-lang/crystal/graphs/contributors)
|
298
|
+
- [**Ruby on Rails**](https://rubyonrails.org) by [it's contributors](https://github.com/rails/rails/graphs/contributors)
|
33
299
|
|
34
300
|
<a href="https://codeberg.org/NNB"><img width="100%" src="https://capsule-render.vercel.app/api?type=waving§ion=footer&color=DC2626&fontColor=FEF2F2&height=128&desc=Made%20with%20%26lt;3%20by%20NNB&descAlignY=80" /></a>
|
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
module CrystalGoodies
|
4
4
|
class Object
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
# Returns `true` if `self` is included in the *collection* argument.
|
6
|
+
#
|
7
|
+
# ```
|
8
|
+
# 10.in?(0..100) # => true
|
9
|
+
# 10.in?(0, 1, 10) # => true
|
10
|
+
# 10.in?(:foo, :bar) # => false
|
11
|
+
# ```
|
12
12
|
def in?(*collection)
|
13
13
|
(collection.one? ? collection.first : collection).include? self
|
14
14
|
end
|
@@ -61,78 +61,9 @@ module CrystalGoodies
|
|
61
61
|
# "3.14IsPi".underscore # => "3.14_is_pi"
|
62
62
|
# ```
|
63
63
|
def underscore(*options)
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
first = true
|
68
|
-
last_is_downcase = false
|
69
|
-
last_is_upcase = false
|
70
|
-
last_is_digit = false
|
71
|
-
mem = nil
|
72
|
-
|
73
|
-
each_char do |char|
|
74
|
-
if options.ascii?
|
75
|
-
digit = char.ascii_number?
|
76
|
-
downcase = digit || char.ascii_lowercase?
|
77
|
-
upcase = char.ascii_uppercase?
|
78
|
-
else
|
79
|
-
digit = char.number?
|
80
|
-
downcase = digit || char.lowercase?
|
81
|
-
upcase = char.uppercase?
|
82
|
-
end
|
83
|
-
|
84
|
-
if first
|
85
|
-
char.downcase(options) { |c| string << c }
|
86
|
-
elsif last_is_downcase && upcase
|
87
|
-
if mem
|
88
|
-
# This is the case of A1Bcd, we need to put 'mem' (not to need to convert as downcase
|
89
|
-
# ^
|
90
|
-
# because 'mem' is digit surely) before putting this char as downcase.
|
91
|
-
string << mem
|
92
|
-
mem = nil
|
93
|
-
end
|
94
|
-
# This is the case of AbcDe, we need to put an underscore before the 'D'
|
95
|
-
# ^
|
96
|
-
string << '_'
|
97
|
-
char.downcase(options) { |c| string << c }
|
98
|
-
elsif (last_is_upcase || last_is_digit) && (upcase || digit)
|
99
|
-
# This is the case of 1) A1Bcd, 2) A1BCd or 3) A1B_cd:if the next char is upcase (case 1) we need
|
100
|
-
# ^ ^ ^
|
101
|
-
# 1) we need to append this char as downcase
|
102
|
-
# 2) we need to append an underscore and then the char as downcase, so we save this char
|
103
|
-
# in 'mem' and decide later
|
104
|
-
# 3) we need to append this char as downcase and then a single underscore
|
105
|
-
if mem
|
106
|
-
# case 2
|
107
|
-
mem.downcase(options) { |c| string << c }
|
108
|
-
end
|
109
|
-
mem = char
|
110
|
-
else
|
111
|
-
if mem
|
112
|
-
if char == '_'
|
113
|
-
# case 3
|
114
|
-
elsif last_is_upcase && downcase
|
115
|
-
# case 1
|
116
|
-
string << '_'
|
117
|
-
end
|
118
|
-
mem.downcase(options) { |c| string << c }
|
119
|
-
mem = nil
|
120
|
-
end
|
121
|
-
|
122
|
-
char.downcase(options) { |c| string << c }
|
123
|
-
end
|
124
|
-
|
125
|
-
last_is_downcase = downcase
|
126
|
-
last_is_upcase = upcase
|
127
|
-
last_is_digit = digit
|
128
|
-
first = false
|
129
|
-
end
|
130
|
-
|
131
|
-
mem&.downcase(options) { |c| string << c }
|
132
|
-
|
133
|
-
FIXME
|
134
|
-
|
135
|
-
self
|
64
|
+
gsub(/([A-Z])(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) { (_1 || _2) << '_' }
|
65
|
+
.tr('-', '_')
|
66
|
+
.downcase(*options)
|
136
67
|
end
|
137
68
|
|
138
69
|
# Converts camelcase boundaries to kebabcase.
|
@@ -143,8 +74,8 @@ module CrystalGoodies
|
|
143
74
|
# "HTTP_CLIENT".dasherize # => "http-client"
|
144
75
|
# "3.14IsPi".dasherize # => "3.14-is-pi"
|
145
76
|
# ```
|
146
|
-
def dasherize
|
147
|
-
underscore.tr('_', '-')
|
77
|
+
def dasherize(*options)
|
78
|
+
underscore(*options).tr('_', '-')
|
148
79
|
end
|
149
80
|
|
150
81
|
# Returns `true` if this string consists exclusively of unicode whitespace.
|
data/sig/enumerable.rbs
CHANGED
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crystal_goodies
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- NNB
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-08-
|
11
|
+
date: 2023-08-16 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description: Class's methods port from Crystal.
|
13
|
+
description: Class's methods convenient for scripting port from Crystal.
|
14
14
|
email:
|
15
15
|
- nnbnh@protonmail.com
|
16
16
|
executables: []
|