hash-utils 0.11.1 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +13 -7
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/hash-utils.gemspec +3 -3
- data/lib/hash-utils/hash.rb +55 -0
- data/lib/hash-utils/object.rb +16 -0
- data/lib/hash-utils/string.rb +226 -0
- data/lib/hash-utils/symbol.rb +73 -0
- data/lib/hash-utils.rb +1 -0
- data/test +183 -21
- metadata +4 -4
data/README.md
CHANGED
@@ -1,9 +1,18 @@
|
|
1
1
|
Hash Utils
|
2
2
|
==========
|
3
3
|
|
4
|
-
**
|
5
|
-
are missing in Ruby
|
6
|
-
|
4
|
+
**hash-utils** adds more than 65 useful and frequently rather
|
5
|
+
fundamental methods which are missing in Ruby programming language,
|
6
|
+
to several core classes. It tries to be similar project to
|
7
|
+
[Ruby Facets][1] on principle, but less complex, more practical,
|
8
|
+
non-atomic and organized by better way.
|
9
|
+
|
10
|
+
- `Array` – 3 methods,
|
11
|
+
- `File` – 2 methods,
|
12
|
+
- `Hash` – 30 methods,
|
13
|
+
- `Object` – 3 methods,
|
14
|
+
- `String` – 23 methods,
|
15
|
+
- `Symbol` – 5 methods.
|
7
16
|
|
8
17
|
For full reference and methods lists, see **[documentation][3]**.
|
9
18
|
|
@@ -31,10 +40,7 @@ Copyright
|
|
31
40
|
Copyright © 2011 [Martin Kozák][10]. See `LICENSE.txt` for
|
32
41
|
further details.
|
33
42
|
|
34
|
-
[1]: http://
|
35
|
-
[2]: http://www.ruby-doc.org/core/classes/Hash.html
|
43
|
+
[1]: http://rubyworks.github.com/facets/
|
36
44
|
[3]: http://rubydoc.info/gems/hash-utils
|
37
|
-
[6]: http://www.ruby-doc.org/core/classes/Object.html
|
38
|
-
[8]: http://www.ruby-doc.org/core/classes/String.html
|
39
45
|
[9]: http://github.com/martinkozak/hash-utils/issues
|
40
46
|
[10]: http://www.martinkozak.net/
|
data/Rakefile
CHANGED
@@ -16,7 +16,7 @@ Jeweler::Tasks.new do |gem|
|
|
16
16
|
gem.name = "hash-utils"
|
17
17
|
gem.homepage = "http://github.com/martinkozak/hash-utils"
|
18
18
|
gem.license = "MIT"
|
19
|
-
gem.summary = 'Adds
|
19
|
+
gem.summary = 'Adds more than 65 useful and frequently rather fundamental methods which are missing in Ruby programming language, to Array, File, Hash, Object, String and Symbol classes. It tries to be similar project to Ruby Facets on principle, but less complex, more practical, non-atomic and organized by better way.'
|
20
20
|
gem.post_install_message = "\nHASH UTILS: Be warn, Hash#all? is deprecated since version 0.10.0 because of\nconflict with built-in one with in fact equivalent functionallity. It will be\nremoved around version 0.13.0. Please, check your code if you can and switch\nto Ruby's one.\n\n"
|
21
21
|
gem.email = "martinkozak@martinkozak.net"
|
22
22
|
gem.authors = ["Martin Kozák"]
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.12.0
|
data/hash-utils.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{hash-utils}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.12.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Martin Kozák"]
|
12
|
-
s.date = %q{2011-03-
|
12
|
+
s.date = %q{2011-03-20}
|
13
13
|
s.email = %q{martinkozak@martinkozak.net}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"LICENSE.txt",
|
@@ -46,7 +46,7 @@ to Ruby's one.
|
|
46
46
|
}
|
47
47
|
s.require_paths = ["lib"]
|
48
48
|
s.rubygems_version = %q{1.6.2}
|
49
|
-
s.summary = %q{Adds
|
49
|
+
s.summary = %q{Adds more than 65 useful and frequently rather fundamental methods which are missing in Ruby programming language, to Array, File, Hash, Object, String and Symbol classes. It tries to be similar project to Ruby Facets on principle, but less complex, more practical, non-atomic and organized by better way.}
|
50
50
|
|
51
51
|
if s.respond_to? :specification_version then
|
52
52
|
s.specification_version = 3
|
data/lib/hash-utils/hash.rb
CHANGED
@@ -505,4 +505,59 @@ class Hash
|
|
505
505
|
return result
|
506
506
|
end
|
507
507
|
|
508
|
+
##
|
509
|
+
# Merges two hashes recursively in place. Receives unlimited
|
510
|
+
# count of hashes for merging them in left to right order.
|
511
|
+
#
|
512
|
+
# @param [*Hash] hashs for merge from
|
513
|
+
# @return [Hash] hash for merge to
|
514
|
+
# @since 0.12.0
|
515
|
+
#
|
516
|
+
|
517
|
+
def deep_merge!(*args)
|
518
|
+
fm = args.map { |hash| [self, hash] }
|
519
|
+
|
520
|
+
while not fm.empty?
|
521
|
+
_in, _out = fm.shift
|
522
|
+
_out.each_pair do |k, v|
|
523
|
+
if v.kind_of? Hash
|
524
|
+
fm << [_in[k], _out[k]]
|
525
|
+
else
|
526
|
+
_in[k] = v
|
527
|
+
end
|
528
|
+
end
|
529
|
+
end
|
530
|
+
|
531
|
+
return self
|
532
|
+
end
|
533
|
+
|
534
|
+
##
|
535
|
+
# Merges two hashes recursively and returns new hash. Receives
|
536
|
+
# unlimited count of hashes for merging them in left to right order.
|
537
|
+
# Included hashes will be copied too.
|
538
|
+
#
|
539
|
+
# @param [*Hash] hashes for merge from
|
540
|
+
# @return [Hash] hash for merge to
|
541
|
+
# @since 0.12.0
|
542
|
+
#
|
543
|
+
|
544
|
+
def deep_merge(*args)
|
545
|
+
result = self.dup
|
546
|
+
fm = args.map { |hash| [result, hash] }
|
547
|
+
|
548
|
+
while not fm.empty?
|
549
|
+
_in, _out = fm.shift
|
550
|
+
_out.each_pair do |k, v|
|
551
|
+
if v.kind_of? Hash
|
552
|
+
_in[k] = _in[k].dup
|
553
|
+
fm << [_in[k], _out[k]]
|
554
|
+
else
|
555
|
+
_in[k] = v
|
556
|
+
end
|
557
|
+
end
|
558
|
+
end
|
559
|
+
|
560
|
+
return result
|
561
|
+
end
|
562
|
+
|
508
563
|
end
|
data/lib/hash-utils/object.rb
CHANGED
@@ -6,6 +6,7 @@
|
|
6
6
|
#
|
7
7
|
|
8
8
|
class Object
|
9
|
+
|
9
10
|
##
|
10
11
|
# Indicates object is in some object which supports +#include?+.
|
11
12
|
#
|
@@ -28,4 +29,19 @@ class Object
|
|
28
29
|
def to_b
|
29
30
|
!!self
|
30
31
|
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Multiplies object by +#dup+ n-times.
|
35
|
+
#
|
36
|
+
# @param [Integer] count required number of copies
|
37
|
+
# @return [Array] array with object copies
|
38
|
+
# @since 0.12.0
|
39
|
+
#
|
40
|
+
|
41
|
+
def **(count)
|
42
|
+
result = [ ]
|
43
|
+
count.times { result << self.dup }
|
44
|
+
return result
|
45
|
+
end
|
46
|
+
|
31
47
|
end
|
data/lib/hash-utils/string.rb
CHANGED
@@ -10,6 +10,7 @@ require "hash-utils/object"
|
|
10
10
|
#
|
11
11
|
|
12
12
|
class String
|
13
|
+
|
13
14
|
##
|
14
15
|
# Holds numeric matcher.
|
15
16
|
#
|
@@ -218,6 +219,230 @@ class String
|
|
218
219
|
self[-1].chr
|
219
220
|
end
|
220
221
|
|
222
|
+
##
|
223
|
+
# Returns required count of lines from beginning of string.
|
224
|
+
#
|
225
|
+
# @example
|
226
|
+
# "a\nb\nc\nd\n".first_lines(2)
|
227
|
+
# # will return ["a\n", "b\n"]
|
228
|
+
#
|
229
|
+
# @note Works well for UNIX strings only. Convert your string
|
230
|
+
# if necessary.
|
231
|
+
# @param [Integer] count required count of lines
|
232
|
+
# @return [Array] array of lines
|
233
|
+
# @since 0.12.0
|
234
|
+
#
|
235
|
+
|
236
|
+
def first_lines(count = 1)
|
237
|
+
result = [ ]
|
238
|
+
self.each_line do |line|
|
239
|
+
count -= 1
|
240
|
+
result << line
|
241
|
+
break if count == 0
|
242
|
+
end
|
243
|
+
|
244
|
+
return result
|
245
|
+
end
|
246
|
+
|
247
|
+
##
|
248
|
+
# Returns first line of the string.
|
249
|
+
#
|
250
|
+
# @example
|
251
|
+
# "a\nb\nc\nd\n".first_line
|
252
|
+
# # will return "a\n"
|
253
|
+
#
|
254
|
+
# @note Works well for UNIX strings only. Convert your string
|
255
|
+
# if necessary.
|
256
|
+
# @return [String] line with +\n+
|
257
|
+
# @since 0.12.0
|
258
|
+
#
|
259
|
+
|
260
|
+
def first_line
|
261
|
+
self.first_lines.first
|
262
|
+
end
|
263
|
+
|
264
|
+
##
|
265
|
+
# Returns required count of lines from end of string.
|
266
|
+
#
|
267
|
+
# @example
|
268
|
+
# "a\nb\nc\nd".last_lines(2)
|
269
|
+
# # will return ["c\n", "d"]
|
270
|
+
#
|
271
|
+
# @note Works well for UNIX strings only. Convert your string
|
272
|
+
# if necessary.
|
273
|
+
# @param [Integer] count required count of lines
|
274
|
+
# @return [Array] array of lines
|
275
|
+
# @since 0.12.0
|
276
|
+
#
|
277
|
+
|
278
|
+
def last_lines(count = 1)
|
279
|
+
buffer = ""
|
280
|
+
result = [ ]
|
281
|
+
(self.length - 1).downto(0) do |i|
|
282
|
+
chr = self[i]
|
283
|
+
if chr.ord == 10
|
284
|
+
count -= 1
|
285
|
+
result << buffer.reverse!
|
286
|
+
buffer = ""
|
287
|
+
break if count == 0
|
288
|
+
end
|
289
|
+
buffer << chr.chr
|
290
|
+
end
|
291
|
+
|
292
|
+
if count != 0
|
293
|
+
result << buffer.reverse!
|
294
|
+
end
|
295
|
+
return result.reverse!
|
296
|
+
end
|
297
|
+
|
298
|
+
##
|
299
|
+
# Returns last line of the string.
|
300
|
+
#
|
301
|
+
# @example
|
302
|
+
# "a\nb\nc\nd".last_line
|
303
|
+
# # will return "d"
|
304
|
+
#
|
305
|
+
# @note Works well for UNIX strings only. Convert your string
|
306
|
+
# if necessary.
|
307
|
+
# @return [String] line
|
308
|
+
# @since 0.12.0
|
309
|
+
#
|
310
|
+
|
311
|
+
def last_line
|
312
|
+
self.last_lines.last
|
313
|
+
end
|
314
|
+
|
315
|
+
##
|
316
|
+
# Removes given count of lines from beginning of file.
|
317
|
+
#
|
318
|
+
# @example
|
319
|
+
# str = "a\nb\nc\nd"
|
320
|
+
#
|
321
|
+
# str.shift_lines(2)
|
322
|
+
# # will return ["a\n", "b\n"]
|
323
|
+
# p str
|
324
|
+
# # will print out "c\nd"
|
325
|
+
#
|
326
|
+
# @note Works well for UNIX strings only. Convert your string
|
327
|
+
# if necessary.
|
328
|
+
# @param [Integer] count required number of lines
|
329
|
+
# @return [Array] removed lines
|
330
|
+
# @since 0.12.0
|
331
|
+
#
|
332
|
+
|
333
|
+
def shift_lines(count = 1)
|
334
|
+
lines = self.first_lines(count)
|
335
|
+
length = lines.inject(0) { |sum, i| sum + i.length }
|
336
|
+
self.replace(self[length..-1])
|
337
|
+
return lines
|
338
|
+
end
|
339
|
+
|
340
|
+
##
|
341
|
+
# Removes first line out from the string and returns it.
|
342
|
+
# @return [String] removed line
|
343
|
+
#
|
344
|
+
|
345
|
+
def shift_line
|
346
|
+
self.shift_lines.first
|
347
|
+
end
|
348
|
+
|
349
|
+
##
|
350
|
+
# Puts lines to begin of string.
|
351
|
+
#
|
352
|
+
# @param [Array] lines line bodies without +\n+
|
353
|
+
# @return [String] itself
|
354
|
+
# @since 0.12.0
|
355
|
+
#
|
356
|
+
|
357
|
+
def unshift_lines(*lines)
|
358
|
+
self.unshift(lines.join("\n") << "\n")
|
359
|
+
end
|
360
|
+
|
361
|
+
alias :unshift_line :unshift_lines
|
362
|
+
|
363
|
+
##
|
364
|
+
# Removes lines out of end of the string.
|
365
|
+
#
|
366
|
+
# @note Works well for UNIX strings only. Convert your string
|
367
|
+
# if necessary.
|
368
|
+
# @param [Integer] count required number of lines
|
369
|
+
# @return [Array] removed lines
|
370
|
+
# @since 0.12.0
|
371
|
+
#
|
372
|
+
|
373
|
+
def pop_lines(count = 1)
|
374
|
+
lines = self.last_lines(count)
|
375
|
+
length = lines.inject(0) { |sum, i| sum + i.length }
|
376
|
+
self.replace(self[0..(length - 1)])
|
377
|
+
return lines
|
378
|
+
end
|
379
|
+
|
380
|
+
##
|
381
|
+
# Removes last line out from the string and returns it.
|
382
|
+
# @return [String] removed line
|
383
|
+
#
|
384
|
+
|
385
|
+
def pop_line
|
386
|
+
self.pop_lines.first
|
387
|
+
end
|
388
|
+
|
389
|
+
##
|
390
|
+
# Joins lines to string.
|
391
|
+
#
|
392
|
+
# @param [Array] lines line bodies without +\n+
|
393
|
+
# @return [String] itself
|
394
|
+
# @since 0.12.0
|
395
|
+
#
|
396
|
+
|
397
|
+
def push_lines(*lines)
|
398
|
+
self.push("\n" << lines.join("\n"))
|
399
|
+
end
|
400
|
+
|
401
|
+
alias :push_line :push_lines
|
402
|
+
alias :push :<<
|
403
|
+
|
404
|
+
##
|
405
|
+
# Removes appropriate number of characters from end of string.
|
406
|
+
#
|
407
|
+
# @param [Integer] count required number of characters
|
408
|
+
# @return [String] removed characters
|
409
|
+
# @since 0.12.0
|
410
|
+
#
|
411
|
+
|
412
|
+
def pop(count = 1)
|
413
|
+
res = self[(self.length - count)..-1]
|
414
|
+
self.replace(self[0..-(count + 1)])
|
415
|
+
return res
|
416
|
+
end
|
417
|
+
|
418
|
+
##
|
419
|
+
# Removes appropriate number of characters from begin of string.
|
420
|
+
#
|
421
|
+
# @param [Integer] count required number of characters
|
422
|
+
# @return [String] removed characters
|
423
|
+
# @since 0.12.0
|
424
|
+
#
|
425
|
+
|
426
|
+
def shift(count = 1)
|
427
|
+
res = self[0...count]
|
428
|
+
self.replace(self[count..-1])
|
429
|
+
return res
|
430
|
+
end
|
431
|
+
|
432
|
+
##
|
433
|
+
# Puts content to begin of file.
|
434
|
+
#
|
435
|
+
# @param [String] string string for prepend
|
436
|
+
# @return [String] itself
|
437
|
+
# @since 0.12.0
|
438
|
+
#
|
439
|
+
|
440
|
+
def unshift(string)
|
441
|
+
self.replace(string << self)
|
442
|
+
end
|
443
|
+
|
444
|
+
alias :prepend :unshift
|
445
|
+
alias :append :<<
|
221
446
|
|
222
447
|
|
223
448
|
private
|
@@ -248,5 +473,6 @@ class String
|
|
248
473
|
|
249
474
|
block.call(newcall)
|
250
475
|
end
|
476
|
+
|
251
477
|
end
|
252
478
|
|
data/lib/hash-utils/symbol.rb
CHANGED
@@ -2,3 +2,76 @@
|
|
2
2
|
# (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
|
3
3
|
|
4
4
|
require "hash-utils/object"
|
5
|
+
|
6
|
+
##
|
7
|
+
# Symbol extension.
|
8
|
+
#
|
9
|
+
|
10
|
+
class Symbol
|
11
|
+
|
12
|
+
##
|
13
|
+
# Returns a new +Symbol+ containing integer copies of the receiver.
|
14
|
+
#
|
15
|
+
# @param [Integer] multi required number of copies
|
16
|
+
# @return [Symbol] new symbol
|
17
|
+
# @since 0.12.0
|
18
|
+
#
|
19
|
+
|
20
|
+
def *(multi)
|
21
|
+
(self.to_s * multi).to_sym
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Returns a new +Symbol+ containing +other_str+ concatenated
|
26
|
+
# to +str+.
|
27
|
+
#
|
28
|
+
# @param [Integer] other_str string for concatenating to
|
29
|
+
# @return [Symbol] new symbol
|
30
|
+
# @since 0.12.0
|
31
|
+
#
|
32
|
+
|
33
|
+
def +(other_str)
|
34
|
+
(self.to_s + other_str.to_s).to_sym
|
35
|
+
end
|
36
|
+
|
37
|
+
alias :concat :+
|
38
|
+
|
39
|
+
##
|
40
|
+
# Works by the same way as +String#slice on +Symbol+.
|
41
|
+
#
|
42
|
+
# @return [String]
|
43
|
+
# @see http://www.ruby-doc.org/core/classes/String.html#M001128
|
44
|
+
# @since 0.12.0
|
45
|
+
#
|
46
|
+
|
47
|
+
def [](*args)
|
48
|
+
self.to_s[*args]
|
49
|
+
end
|
50
|
+
|
51
|
+
alias :slice :[]
|
52
|
+
|
53
|
+
##
|
54
|
+
# Returns true if +Symbol+ starts with a prefix given.
|
55
|
+
#
|
56
|
+
# @param [String+] prefix prefixes for check
|
57
|
+
# @return [Boolean] +true+ if yes, +false+ in otherwise
|
58
|
+
# @since 0.12.0
|
59
|
+
#
|
60
|
+
|
61
|
+
def start_with?(*prefix)
|
62
|
+
self.to_s.start_with?(*prefix)
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# Returns true if +Symbol+ ends with a prefix given.
|
67
|
+
#
|
68
|
+
# @param [String+] prefix prefixes for check
|
69
|
+
# @return [Boolean] +true+ if yes, +false+ in otherwise
|
70
|
+
# @since 0.12.0
|
71
|
+
#
|
72
|
+
|
73
|
+
def end_with?(*suffix)
|
74
|
+
self.to_s.end_with?(*suffix)
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
data/lib/hash-utils.rb
CHANGED
data/test
CHANGED
@@ -9,38 +9,200 @@ require "riot"
|
|
9
9
|
|
10
10
|
## FILE
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
12
|
+
# Filozofové mají Kanta rádi. Matematici mají Kanta také rádi, jen si
|
13
|
+
# myslí, že většina z toho, co vymyslel, je blbost.
|
14
|
+
#
|
15
|
+
# doc. Jiří Souček
|
17
16
|
|
18
|
-
context "File
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
context "File" do
|
18
|
+
asserts("#touch") do
|
19
|
+
File.touch("./~test1")
|
20
|
+
File.exists? "./~test1"
|
21
|
+
end
|
22
|
+
asserts("#write") do
|
23
|
+
File.write("./~test2", "some string")
|
24
|
+
File.read("./~test2") == "some string"
|
25
|
+
end
|
26
|
+
|
27
|
+
teardown do
|
28
|
+
File.unlink("./~test1")
|
29
|
+
File.unlink("./~test2")
|
30
|
+
end
|
22
31
|
end
|
23
32
|
|
24
33
|
## HASH
|
25
34
|
|
26
|
-
context "Hash
|
27
|
-
setup
|
28
|
-
|
35
|
+
context "Hash" do
|
36
|
+
setup do
|
37
|
+
{ :a => 1, :b => 2 }
|
38
|
+
end
|
39
|
+
|
40
|
+
asserts("#compact") do
|
41
|
+
t = { :a => 1, :b => nil }
|
42
|
+
t = t.compact
|
43
|
+
t == { :a => 1 }
|
44
|
+
end
|
45
|
+
asserts("#compact!") do
|
46
|
+
t = { :a => 1, :b => nil }
|
47
|
+
t.compact!
|
48
|
+
t == { :a => 1 }
|
49
|
+
end
|
50
|
+
asserts("#map_values") do
|
51
|
+
topic.map_values { |i| i + 1 } == { :a => 2, :b => 3 }
|
52
|
+
end
|
53
|
+
asserts("#map_values!") do
|
54
|
+
t = topic.dup
|
55
|
+
t.map_values! { |i| i + 1 }
|
56
|
+
t == { :a => 2, :b => 3 }
|
57
|
+
end
|
58
|
+
asserts("#deep_merge") do
|
59
|
+
h1 = {:a => {:b => :c, :d => :e}}
|
60
|
+
h2 = {:a => {:d => :f, :h => :i}}
|
61
|
+
h = h1.deep_merge(h2)
|
62
|
+
(h == {:a => {:b => :c, :d => :f, :h => :i}}) and (h1 == {:a => {:b => :c, :d => :e}})
|
63
|
+
end
|
64
|
+
asserts("#deep_merge!") do
|
65
|
+
h = {:a => {:b => :c, :d => :e}}
|
66
|
+
h.deep_merge!({:a => {:d => :f, :h => :i}})
|
67
|
+
h == {:a => {:b => :c, :d => :f, :h => :i}}
|
68
|
+
end
|
29
69
|
end
|
30
70
|
|
31
|
-
|
32
|
-
|
33
|
-
|
71
|
+
## OBJECT
|
72
|
+
|
73
|
+
context "Object" do
|
74
|
+
asserts("#**") do
|
75
|
+
"ab" ** 5 == ["ab", "ab", "ab", "ab", "ab"]
|
76
|
+
end
|
77
|
+
asserts("#in?") do
|
78
|
+
5.in? 1..7
|
79
|
+
end
|
80
|
+
asserts("#to_b") do
|
81
|
+
(nil.to_b === false) and ("ab".to_b === true)
|
82
|
+
end
|
34
83
|
end
|
35
84
|
|
36
85
|
## STRING
|
37
86
|
|
38
|
-
context "String
|
39
|
-
|
40
|
-
|
87
|
+
context "String" do
|
88
|
+
asserts("#first") do
|
89
|
+
"abc".first == ?a
|
90
|
+
end
|
91
|
+
asserts("#first_line") do
|
92
|
+
res = true
|
93
|
+
res &= "a\nb\nc\n".first_line == "a\n"
|
94
|
+
res &= "a".first_line == "a"
|
95
|
+
end
|
96
|
+
asserts("#first_lines") do
|
97
|
+
res = true
|
98
|
+
res &= "a\nb".first_lines(2) == ["a\n", "b"]
|
99
|
+
res &= "a\nb\nc\n".first_lines(4) == ["a\n", "b\n", "c\n"]
|
100
|
+
end
|
101
|
+
asserts("#last") do
|
102
|
+
"abc".last == ?c
|
103
|
+
end
|
104
|
+
asserts("#last_line") do
|
105
|
+
res = true
|
106
|
+
res &= "a\nb\nc\n".last_line == ""
|
107
|
+
res &= "a\nb\nc".last_line == "c"
|
108
|
+
res &= "a".last_line == "a"
|
109
|
+
end
|
110
|
+
asserts("#last_lines") do
|
111
|
+
res = true
|
112
|
+
res &= "a\nb".last_lines(2) == ["a\n", "b"]
|
113
|
+
res &= "a\nb\nc\n".last_lines(4) == ["a\n", "b\n", "c\n", ""]
|
114
|
+
end
|
115
|
+
asserts("#pop") do
|
116
|
+
res = true
|
117
|
+
str = "abcd"
|
118
|
+
res &= str.pop == "d"
|
119
|
+
res &= str == "abc"
|
120
|
+
str = "abcd"
|
121
|
+
res &= str.pop(2) == "cd"
|
122
|
+
res &= str == "ab"
|
123
|
+
end
|
124
|
+
asserts("#pop_line") do
|
125
|
+
res = true
|
126
|
+
str = "a\nb\nc\nd"
|
127
|
+
res &= str.pop_line == "d"
|
128
|
+
res &= str = "a\nb\nc\n"
|
129
|
+
end
|
130
|
+
asserts("#pop_lines") do
|
131
|
+
res = true
|
132
|
+
str = "a\nb\nc\nd\n"
|
133
|
+
res &= str.pop_lines(2) == ["d\n", ""]
|
134
|
+
res &= str = "a\nb\nc\n"
|
135
|
+
end
|
136
|
+
asserts("#push_line") do
|
137
|
+
res = true
|
138
|
+
str = "a\nb\nc\nd"
|
139
|
+
res &= str.push_line("1") == "a\nb\nc\nd\n1"
|
140
|
+
res &= str == "a\nb\nc\nd\n1"
|
141
|
+
end
|
142
|
+
asserts("#push_lines") do
|
143
|
+
res = true
|
144
|
+
str = "a\nb\nc\nd"
|
145
|
+
res &= str.push_lines("1", "2") == "a\nb\nc\nd\n1\n2"
|
146
|
+
res &= str == "a\nb\nc\nd\n1\n2"
|
147
|
+
end
|
148
|
+
asserts("#shift") do
|
149
|
+
res = true
|
150
|
+
str = "abcd"
|
151
|
+
res &= str.shift == "a"
|
152
|
+
res &= str == "bcd"
|
153
|
+
str = "abcd"
|
154
|
+
res &= str.shift(2) == "ab"
|
155
|
+
res &= str == "cd"
|
156
|
+
end
|
157
|
+
asserts("#shift_line") do
|
158
|
+
res = true
|
159
|
+
str = "a\nb\nc\nd\n"
|
160
|
+
res &= str.shift_line == "a\n"
|
161
|
+
res &= str = "b\nc\nd\n"
|
162
|
+
end
|
163
|
+
asserts("#shift_lines") do
|
164
|
+
res = true
|
165
|
+
str = "a\nb\nc\nd\n"
|
166
|
+
res &= str.shift_lines(2) == ["a\n", "b\n"]
|
167
|
+
res &= str = "c\nd\n"
|
168
|
+
end
|
169
|
+
asserts("#unshift") do
|
170
|
+
res = true
|
171
|
+
str = "abcd"
|
172
|
+
res &= str.unshift("123") == "123abcd"
|
173
|
+
res &= str == "123abcd"
|
174
|
+
end
|
175
|
+
asserts("#unshift_line") do
|
176
|
+
res = true
|
177
|
+
str = "a\nb\nc\nd\n"
|
178
|
+
res &= str.unshift_line("1") == "1\na\nb\nc\nd\n"
|
179
|
+
res &= str == "1\na\nb\nc\nd\n"
|
180
|
+
end
|
181
|
+
asserts("#unshift_lines") do
|
182
|
+
res = true
|
183
|
+
str = "a\nb\nc\nd\n"
|
184
|
+
res &= str.unshift_lines("1", "2") == "1\n2\na\nb\nc\nd\n"
|
185
|
+
res &= str == "1\n2\na\nb\nc\nd\n"
|
186
|
+
end
|
187
|
+
|
41
188
|
end
|
42
189
|
|
43
|
-
|
44
|
-
|
45
|
-
|
190
|
+
## SYMBOL
|
191
|
+
|
192
|
+
context "Symbol" do
|
193
|
+
asserts("#*") do
|
194
|
+
:a * 5 == :aaaaa
|
195
|
+
end
|
196
|
+
asserts("#+") do
|
197
|
+
:a + :b == :ab
|
198
|
+
end
|
199
|
+
asserts("#[]") do
|
200
|
+
:abcde[0...3] == "abc"
|
201
|
+
end
|
202
|
+
asserts("#end_with?") do
|
203
|
+
:abcde.end_with? "ghi", "cde"
|
204
|
+
end
|
205
|
+
asserts("#start_with?") do
|
206
|
+
:abcde.start_with? "ghi", "abc"
|
207
|
+
end
|
46
208
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: hash-utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.12.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- "Martin Koz\xC3\xA1k"
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-03-
|
13
|
+
date: 2011-03-20 00:00:00 +01:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -92,7 +92,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
92
92
|
requirements:
|
93
93
|
- - ">="
|
94
94
|
- !ruby/object:Gem::Version
|
95
|
-
hash: -
|
95
|
+
hash: -4395191142645509098
|
96
96
|
segments:
|
97
97
|
- 0
|
98
98
|
version: "0"
|
@@ -108,6 +108,6 @@ rubyforge_project:
|
|
108
108
|
rubygems_version: 1.6.2
|
109
109
|
signing_key:
|
110
110
|
specification_version: 3
|
111
|
-
summary: Adds
|
111
|
+
summary: Adds more than 65 useful and frequently rather fundamental methods which are missing in Ruby programming language, to Array, File, Hash, Object, String and Symbol classes. It tries to be similar project to Ruby Facets on principle, but less complex, more practical, non-atomic and organized by better way.
|
112
112
|
test_files: []
|
113
113
|
|