facets 2.1.3 → 2.2.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.
- data/AUTHORS +14 -12
- data/CHANGES +45 -2
- data/NOTES +9 -7
- data/lib/core/facets/1stclassmethod.rb +15 -11
- data/lib/core/facets/array.rb +0 -1
- data/lib/core/facets/array/conjoin.rb +40 -8
- data/lib/core/facets/array/delete.rb +8 -2
- data/lib/core/facets/array/indexable.rb +30 -3
- data/lib/core/facets/array/merge.rb +11 -0
- data/lib/core/facets/array/only.rb +3 -3
- data/lib/core/facets/array/pad.rb +4 -46
- data/lib/core/facets/array/rotate.rb +4 -4
- data/lib/core/facets/array/select.rb +2 -0
- data/lib/core/facets/array/splice.rb +16 -2
- data/lib/core/facets/array/stackable.rb +6 -40
- data/lib/core/facets/binding.rb +3 -0
- data/lib/core/facets/binding/cflow.rb +10 -64
- data/lib/core/facets/binding/defined.rb +10 -0
- data/lib/core/facets/binding/eval.rb +10 -76
- data/lib/core/facets/binding/here.rb +9 -0
- data/lib/core/facets/binding/self.rb +10 -0
- data/lib/core/facets/binding/vars.rb +0 -45
- data/lib/core/facets/boolean.rb +31 -103
- data/lib/core/facets/class/descendents.rb +17 -44
- data/lib/core/facets/comparable/bound.rb +8 -70
- data/lib/core/facets/comparable/cmp.rb +12 -92
- data/lib/core/facets/conversion.rb +122 -321
- data/lib/core/facets/dir/multiglob.rb +0 -13
- data/lib/core/facets/dir/traverse.rb +61 -111
- data/lib/core/facets/enumerable.rb +4 -2
- data/lib/core/facets/enumerable/cartesian.rb +36 -85
- data/lib/core/facets/enumerable/collect.rb +64 -152
- data/lib/core/facets/enumerable/combination.rb +40 -42
- data/lib/core/facets/enumerable/count.rb +99 -174
- data/lib/core/facets/enumerable/each.rb +86 -0
- data/lib/core/facets/enumerable/mash.rb +58 -0
- data/lib/core/facets/enumerable/permutation.rb +39 -44
- data/lib/core/facets/enumerable/probability.rb +16 -90
- data/lib/core/facets/enumerable/split.rb +113 -0
- data/lib/core/facets/exception/detail.rb +1 -2
- data/lib/core/facets/facets.rb +3 -2
- data/lib/core/facets/file/read.rb +4 -59
- data/lib/core/facets/file/topath.rb +8 -96
- data/lib/core/facets/file/write.rb +21 -49
- data/lib/core/facets/filetest/root.rb +4 -3
- data/lib/core/facets/functor.rb +5 -43
- data/lib/core/facets/hash/at.rb +7 -37
- data/lib/core/facets/hash/delete.rb +9 -58
- data/lib/core/facets/hash/has_keys.rb +4 -43
- data/lib/core/facets/hash/insert.rb +5 -38
- data/lib/core/facets/hash/inverse.rb +2 -41
- data/lib/core/facets/hash/iterate.rb +4 -45
- data/lib/core/facets/hash/keyize.rb +24 -92
- data/lib/core/facets/hash/merge.rb +4 -38
- data/lib/core/facets/hash/new.rb +5 -38
- data/lib/core/facets/hash/op.rb +20 -66
- data/lib/core/facets/hash/rekey.rb +9 -87
- data/lib/core/facets/hash/select.rb +1 -1
- data/lib/core/facets/hash/slice.rb +42 -0
- data/lib/core/facets/hash/traverse.rb +6 -46
- data/lib/core/facets/hash/update.rb +27 -67
- data/lib/core/facets/hash/weave.rb +22 -42
- data/lib/core/facets/indexable.rb +42 -14
- data/lib/core/facets/integer/bitmask.rb +69 -106
- data/lib/core/facets/integer/factorial.rb +1 -44
- data/lib/core/facets/integer/multiples.rb +27 -22
- data/lib/core/facets/integer/of.rb +1 -33
- data/lib/core/facets/kernel.rb +4 -2
- data/lib/core/facets/kernel/ask.rb +15 -3
- data/lib/core/facets/kernel/callstack.rb +38 -69
- data/lib/core/facets/kernel/constant.rb +2 -38
- data/lib/core/facets/kernel/deepcopy.rb +3 -55
- data/lib/core/facets/kernel/dir.rb +2 -0
- data/lib/core/facets/kernel/ergo.rb +2 -2
- data/lib/core/facets/kernel/instance.rb +51 -120
- data/lib/core/facets/kernel/metaid.rb +35 -73
- data/lib/core/facets/kernel/object.rb +14 -39
- data/lib/core/facets/kernel/op_esc.rb +24 -2
- data/lib/core/facets/kernel/populate.rb +6 -69
- data/lib/core/facets/kernel/report.rb +28 -33
- data/lib/core/facets/kernel/require.rb +7 -21
- data/lib/core/facets/kernel/respond.rb +11 -1
- data/lib/core/facets/kernel/returning.rb +50 -0
- data/lib/core/facets/kernel/silence.rb +12 -24
- data/lib/core/facets/kernel/super.rb +12 -76
- data/lib/core/facets/kernel/tap.rb +25 -107
- data/lib/core/facets/kernel/val.rb +7 -46
- data/lib/core/facets/kernel/withattr.rb +6 -64
- data/lib/core/facets/matchdata/matchset.rb +8 -50
- data/lib/core/facets/module.rb +3 -1
- data/lib/core/facets/module/abstract.rb +9 -47
- data/lib/core/facets/module/alias.rb +11 -68
- data/lib/core/facets/module/attr.rb +36 -15
- data/lib/core/facets/module/cattr.rb +8 -76
- data/lib/core/facets/module/clone.rb +15 -66
- data/lib/core/facets/module/include.rb +54 -114
- data/lib/core/facets/module/methods.rb +15 -13
- data/lib/core/facets/module/modify.rb +20 -206
- data/lib/core/facets/module/name.rb +19 -83
- data/lib/core/facets/module/require.rb +48 -53
- data/lib/core/facets/module/traits.rb +74 -33
- data/lib/core/facets/nilclass/status.rb +25 -2
- data/lib/core/facets/numeric/round.rb +24 -89
- data/lib/core/facets/proc/bind.rb +16 -59
- data/lib/core/facets/proc/compose.rb +6 -40
- data/lib/core/facets/proc/fn.rb +2 -0
- data/lib/core/facets/range/combine.rb +15 -51
- data/lib/core/facets/range/overlap.rb +8 -64
- data/lib/core/facets/regexp/arity.rb +6 -41
- data/lib/core/facets/stackable.rb +43 -4
- data/lib/core/facets/string.rb +2 -0
- data/lib/core/facets/string/align.rb +45 -55
- data/lib/core/facets/string/blank.rb +2 -46
- data/lib/core/facets/string/bracket.rb +14 -87
- data/lib/core/facets/string/case.rb +45 -32
- data/lib/core/facets/string/crypt.rb +3 -40
- data/lib/core/facets/string/filter.rb +7 -49
- data/lib/core/facets/string/format.rb +24 -126
- data/lib/core/facets/string/indexable.rb +50 -133
- data/lib/core/facets/string/interpolate.rb +24 -59
- data/lib/core/facets/string/natcmp.rb +5 -39
- data/lib/core/facets/string/nchar.rb +37 -45
- data/lib/core/facets/string/op.rb +13 -0
- data/lib/core/facets/string/partitions.rb +38 -99
- data/lib/core/facets/string/range.rb +8 -49
- data/lib/core/facets/string/regesc.rb +9 -42
- data/lib/core/facets/string/scan.rb +6 -52
- data/lib/core/facets/string/splice.rb +8 -13
- data/lib/core/facets/string/tabs.rb +16 -153
- data/lib/core/facets/symbol.rb +3 -1
- data/lib/core/facets/symbol/chomp.rb +11 -29
- data/lib/core/facets/symbol/generate.rb +4 -43
- data/lib/core/facets/symbol/not.rb +13 -25
- data/lib/core/facets/symbol/shadow.rb +2 -40
- data/lib/core/facets/symbol/succ.rb +14 -13
- data/lib/core/facets/symbol/to_proc.rb +33 -28
- data/lib/core/facets/time.rb +1 -0
- data/lib/core/facets/time/change.rb +5 -38
- data/lib/core/facets/time/elapse.rb +2 -41
- data/lib/core/facets/time/stamp.rb +47 -0
- data/lib/core/facets/unboundmethod.rb +3 -0
- data/lib/core/facets/unboundmethod/arguments.rb +27 -4
- data/lib/core/facets/unboundmethod/name.rb +21 -7
- data/lib/methods/facets/enumerable/cluster_by.rb +1 -1
- data/lib/methods/facets/enumerable/collate.rb +1 -0
- data/lib/methods/facets/enumerable/divide.rb +1 -1
- data/lib/methods/facets/enumerable/each_by.rb +1 -1
- data/lib/methods/facets/enumerable/each_pair.rb +1 -1
- data/lib/methods/facets/enumerable/eachn.rb +1 -1
- data/lib/methods/facets/enumerable/graph.rb +1 -1
- data/lib/methods/facets/enumerable/group_by.rb +1 -1
- data/lib/methods/facets/enumerable/inject.rb +1 -0
- data/lib/methods/facets/enumerable/map_send.rb +1 -0
- data/lib/methods/facets/enumerable/modulate.rb +1 -0
- data/lib/methods/facets/enumerable/partition_by.rb +1 -1
- data/lib/methods/facets/hash/collate.rb +1 -1
- data/lib/methods/facets/hash/except.rb +1 -0
- data/lib/methods/facets/hash/graph.rb +1 -1
- data/lib/methods/facets/hash/mash.rb +1 -0
- data/lib/methods/facets/kernel/Bit.rb +1 -0
- data/lib/methods/facets/kernel/complete.rb +1 -1
- data/lib/methods/facets/kernel/here.rb +1 -1
- data/lib/methods/facets/kernel/non_nil.rb +1 -0
- data/lib/methods/facets/kernel/respond_with_value.rb +1 -0
- data/lib/methods/facets/kernel/with.rb +1 -1
- data/lib/methods/facets/module/class_def.rb +1 -0
- data/lib/methods/facets/string/camelcase.rb +1 -0
- data/lib/methods/facets/string/op_minus.rb +1 -0
- data/lib/methods/facets/string/snakecase.rb +1 -0
- data/lib/more/facets/attributes.rb +5 -5
- data/lib/more/facets/basicobject.rb +0 -62
- data/lib/{core/facets/continuation/create.rb → more/facets/continuation.rb} +4 -21
- data/lib/more/facets/duration.rb +534 -0
- data/lib/more/facets/lazy.rb +3 -3
- data/lib/more/facets/namespace.rb +23 -71
- data/lib/more/facets/rbsystem.rb +42 -8
- data/lib/more/facets/stylize.rb +6 -3
- data/lib/more/facets/thread.rb +55 -0
- data/meta/MANIFEST +49 -18
- data/meta/ROLLRC +1 -1
- data/meta/project.yaml +2 -2
- data/task/install +1 -1
- data/task/test/general +8 -2
- data/test/unit/array/test_pad.rb +30 -45
- data/test/unit/array/test_stackable.rb +14 -28
- data/test/unit/binding/test_cflow.rb +34 -49
- data/test/unit/binding/test_defined.rb +17 -0
- data/test/unit/binding/test_eval.rb +11 -39
- data/test/unit/binding/test_here.rb +17 -0
- data/test/unit/binding/test_self.rb +17 -0
- data/test/unit/binding/test_vars.rb +22 -37
- data/test/unit/class/test_descendents.rb +15 -30
- data/test/unit/class/test_initializer.rb +1 -8
- data/test/unit/comparable/test_bound.rb +38 -53
- data/test/unit/comparable/test_cmp.rb +45 -60
- data/test/unit/dir/test_traverse.rb +56 -0
- data/test/unit/enumerable/test_cartesian.rb +34 -47
- data/test/unit/enumerable/test_collect.rb +16 -125
- data/test/unit/enumerable/test_combination.rb +1 -8
- data/test/unit/enumerable/test_count.rb +51 -66
- data/test/unit/enumerable/test_each.rb +77 -0
- data/test/unit/enumerable/test_mash.rb +51 -0
- data/test/unit/enumerable/test_permutation.rb +1 -7
- data/test/unit/enumerable/test_probability.rb +42 -55
- data/test/unit/enumerable/test_split.rb +52 -0
- data/test/unit/exception/test_detail.rb +19 -0
- data/test/unit/file/test_read.rb +34 -0
- data/test/unit/file/test_topath.rb +17 -25
- data/test/unit/file/test_write.rb +6 -12
- data/test/unit/filetest/test_root.rb +14 -0
- data/test/unit/hash/test_at.rb +9 -21
- data/test/unit/hash/test_delete.rb +22 -37
- data/test/unit/hash/test_has_keys.rb +13 -28
- data/test/unit/hash/test_insert.rb +9 -23
- data/test/unit/hash/test_inverse.rb +11 -26
- data/test/unit/hash/test_iterate.rb +16 -31
- data/test/unit/hash/test_keyize.rb +40 -55
- data/test/unit/hash/test_merge.rb +10 -25
- data/test/unit/hash/test_new.rb +9 -24
- data/test/unit/hash/test_op.rb +1 -7
- data/test/unit/hash/test_rekey.rb +47 -62
- data/test/unit/hash/test_traverse.rb +17 -32
- data/test/unit/hash/test_update.rb +30 -45
- data/test/unit/hash/test_weave.rb +10 -23
- data/test/unit/integer/test_bitmask.rb +48 -44
- data/test/unit/integer/test_factorial.rb +11 -26
- data/test/unit/integer/test_multiples.rb +1 -5
- data/test/unit/integer/test_of.rb +14 -29
- data/test/unit/kernel/test_callstack.rb +13 -28
- data/test/unit/kernel/test_constant.rb +14 -28
- data/test/unit/kernel/test_deepcopy.rb +20 -35
- data/test/unit/kernel/test_instance.rb +46 -61
- data/test/unit/kernel/test_metaid.rb +42 -57
- data/test/unit/kernel/test_object.rb +14 -29
- data/test/unit/kernel/test_populate.rb +38 -53
- data/test/unit/kernel/test_report.rb +1 -7
- data/test/unit/kernel/test_returning.rb +16 -0
- data/test/unit/kernel/test_silence.rb +8 -23
- data/test/unit/kernel/test_super.rb +41 -56
- data/test/unit/kernel/test_tap.rb +15 -39
- data/test/unit/kernel/test_val.rb +7 -20
- data/test/unit/kernel/test_withattr.rb +29 -44
- data/test/unit/matchdata/test_matchset.rb +20 -35
- data/test/unit/module/test_abstract.rb +15 -30
- data/test/unit/module/test_alias.rb +32 -45
- data/test/unit/module/test_cattr.rb +39 -54
- data/test/unit/module/test_clone.rb +31 -43
- data/test/unit/module/test_include.rb +1 -35
- data/test/unit/module/test_modify.rb +102 -114
- data/test/unit/module/test_name.rb +1 -7
- data/test/unit/numeric/test_round.rb +46 -61
- data/test/unit/proc/test_bind.rb +29 -44
- data/test/unit/proc/test_compose.rb +20 -35
- data/test/unit/range/test_combine.rb +14 -29
- data/test/unit/range/test_overlap.rb +34 -51
- data/test/unit/regexp/test_arity.rb +14 -29
- data/test/unit/string/test_align.rb +13 -27
- data/test/unit/string/test_blank.rb +12 -27
- data/test/unit/string/test_bracket.rb +52 -67
- data/test/unit/string/test_case.rb +19 -38
- data/test/unit/string/test_crypt.rb +10 -25
- data/test/unit/string/test_filter.rb +1 -7
- data/test/unit/string/test_format.rb +2 -7
- data/test/unit/string/test_indexable.rb +54 -69
- data/test/unit/string/test_interpolate.rb +8 -21
- data/test/unit/string/test_natcmp.rb +11 -26
- data/test/unit/string/test_nchar.rb +1 -14
- data/test/unit/string/test_op.rb +14 -0
- data/test/unit/string/test_partitions.rb +39 -54
- data/test/unit/string/test_range.rb +17 -32
- data/test/unit/string/test_regesc.rb +1 -7
- data/test/unit/string/test_scan.rb +23 -38
- data/test/unit/string/test_stackable.rb +79 -98
- data/test/unit/string/test_tabs.rb +1 -7
- data/test/unit/symbol/test_chomp.rb +10 -21
- data/test/unit/symbol/test_generate.rb +7 -22
- data/test/unit/symbol/test_not.rb +10 -25
- data/test/unit/symbol/test_shadow.rb +8 -23
- data/test/unit/symbol/test_succ.rb +1 -7
- data/test/unit/symbol/test_to_proc.rb +1 -7
- data/test/unit/test_attributes.rb +1 -1
- data/test/unit/test_continuation.rb +13 -0
- data/test/unit/test_conversion.rb +1 -14
- data/test/unit/test_namespace.rb +30 -3
- data/test/unit/test_thread.rb +23 -0
- data/test/unit/time/test_change.rb +11 -26
- data/test/unit/time/test_elapse.rb +10 -25
- data/test/unit/time/test_stamp.rb +28 -0
- metadata +65 -25
- data/lib/core/facets/array/unzip.rb +0 -14
- data/lib/core/facets/continuation.rb +0 -1
- data/lib/core/facets/enumerable/collate.rb +0 -104
- data/lib/core/facets/kernel/require_esc.rb +0 -44
- data/lib/more/facets/mapsend.rb +0 -98
- data/lib/more/facets/pp_s.rb +0 -30
- data/log/history.rd +0 -38
- data/log/todo.rd +0 -4
- data/task/special/quickopts +0 -15
- data/test/unit/continuation/test_create.rb +0 -28
- data/test/unit/enumerable/test_collate.rb +0 -51
- data/test/unit/kernel/test_require_esc.rb +0 -29
- data/test/unit/test_mapsend.rb +0 -18
- data/test/unit/test_pp_s.rb +0 -17
@@ -1,16 +1,3 @@
|
|
1
|
-
# TITLE:
|
2
|
-
#
|
3
|
-
# Hash Traversal Extensions
|
4
|
-
#
|
5
|
-
# SUMMARY:
|
6
|
-
#
|
7
|
-
# Traversal extensions for Hash class.
|
8
|
-
#
|
9
|
-
# CREDITS:
|
10
|
-
#
|
11
|
-
# - Thomas Sawyer
|
12
|
-
|
13
|
-
#
|
14
1
|
class Hash
|
15
2
|
|
16
3
|
# Returns a new hash created by traversing the hash and its subhashes,
|
@@ -21,10 +8,14 @@ class Hash
|
|
21
8
|
# g = h.traverse { |k,v| [k.downcase, v] }
|
22
9
|
# g #=> { "a"=>"A", "b"=>"B" }
|
23
10
|
#
|
11
|
+
#
|
12
|
+
# CREDIT: Trans
|
13
|
+
#
|
24
14
|
#--
|
25
15
|
# TODO Testing value to see if it is a Hash also catches subclasses of Hash.
|
26
16
|
# This is probably not the right thing to do and should catch Hashes only (?)
|
27
17
|
#++
|
18
|
+
|
28
19
|
def traverse(&b)
|
29
20
|
inject({}) do |h,(k,v)|
|
30
21
|
v = ( Hash === v ? v.traverse(&b) : v )
|
@@ -41,41 +32,10 @@ class Hash
|
|
41
32
|
# h.traverse! { |k,v| [k.downcase, v] }
|
42
33
|
# h #=> { "a"=>"A", "b"=>"B" }
|
43
34
|
#
|
35
|
+
# CREDIT: Trans
|
36
|
+
|
44
37
|
def traverse!(&b)
|
45
38
|
self.replace( self.traverse(&b) )
|
46
39
|
end
|
47
40
|
|
48
41
|
end
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
# _____ _
|
53
|
-
# |_ _|__ ___| |_
|
54
|
-
# | |/ _ \/ __| __|
|
55
|
-
# | | __/\__ \ |_
|
56
|
-
# |_|\___||___/\__|
|
57
|
-
#
|
58
|
-
=begin test
|
59
|
-
|
60
|
-
require 'test/unit'
|
61
|
-
|
62
|
-
class TestHashTraverse < Test::Unit::TestCase
|
63
|
-
|
64
|
-
def test_traverse
|
65
|
-
h = { "A" => "x", "B" => "y" }
|
66
|
-
h2 = h.traverse { |k,v| [k.downcase, v.upcase] }
|
67
|
-
e = { "a" => "X", "b" => "Y" }
|
68
|
-
assert_not_equal( h, h2 )
|
69
|
-
assert_equal( e, h2 )
|
70
|
-
end
|
71
|
-
|
72
|
-
def test_traverse!
|
73
|
-
h = { "A" => "x", "B" => "y" }
|
74
|
-
h.traverse! { |k,v| [k.downcase, v.upcase] }
|
75
|
-
e = { "a" => "X", "b" => "Y" }
|
76
|
-
assert_equal( e, h )
|
77
|
-
end
|
78
|
-
|
79
|
-
end
|
80
|
-
|
81
|
-
=end
|
@@ -1,93 +1,53 @@
|
|
1
|
-
# TITLE:
|
2
|
-
#
|
3
|
-
# Hash Update Extensions
|
4
|
-
#
|
5
|
-
# SUMMARY:
|
6
|
-
#
|
7
|
-
# Update related extensions for Hash class.
|
8
|
-
#
|
9
|
-
# CREDITS:
|
10
|
-
#
|
11
|
-
# - Thomas Sawyer
|
12
|
-
|
13
|
-
#
|
14
1
|
class Hash
|
15
2
|
|
16
3
|
# Same as #update_each, but deletes the key element first.
|
4
|
+
#
|
5
|
+
# CREDIT: Trans
|
6
|
+
|
17
7
|
def replace_each # :yield:
|
18
|
-
dup.
|
8
|
+
dup.each do |k,v|
|
9
|
+
delete(k)
|
10
|
+
update(yield(k,v))
|
11
|
+
end
|
19
12
|
self
|
20
13
|
end
|
21
14
|
|
22
15
|
# Iterates through each pair and updates a the hash
|
23
|
-
# in place. This is formally equivalent to #
|
24
|
-
# But does not use #
|
25
|
-
# Hence #update_each is probably a
|
26
|
-
|
27
|
-
#
|
28
|
-
# it expects the block to return a "mini-hash" pair.
|
29
|
-
#++
|
16
|
+
# in place. This is formally equivalent to #mash!
|
17
|
+
# But does not use #mash to accomplish the task.
|
18
|
+
# Hence #update_each is probably a touch faster.
|
19
|
+
#
|
20
|
+
# CREDIT: Trans
|
30
21
|
|
31
22
|
def update_each # :yield:
|
32
|
-
dup.
|
23
|
+
dup.each do |k,v|
|
24
|
+
update(yield(k,v))
|
25
|
+
end
|
33
26
|
self
|
34
27
|
end
|
35
28
|
|
29
|
+
# Iterate over hash updating kust the keys.
|
30
|
+
#
|
31
|
+
# h = {:a=>1, :b=>2}
|
32
|
+
# h.update_keys{ |k,v| "#{k}#{v}" }
|
33
|
+
# h #=> { "a1"=>2, "b2"=>3 }
|
36
34
|
#
|
35
|
+
# CREDIT: Trans
|
37
36
|
|
38
37
|
def update_keys #:yield:
|
39
38
|
each{ |k,v| delete(k) ; store(yield(k), v) }
|
40
39
|
end
|
41
40
|
|
41
|
+
# Iterate over hash updating just the values.
|
42
42
|
#
|
43
|
+
# h = {:a=>1, :b=>2}
|
44
|
+
# h.update_values{ |k,v| v+1 }
|
45
|
+
# h #=> { a:=>2, :b=>3 }
|
46
|
+
#
|
47
|
+
# CREDIT: Trans
|
43
48
|
|
44
49
|
def update_values #:yield:
|
45
50
|
each{ |k,v| store(k, yield(v)) }
|
46
51
|
end
|
47
52
|
|
48
53
|
end
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
# _____ _
|
53
|
-
# |_ _|__ ___| |_
|
54
|
-
# | |/ _ \/ __| __|
|
55
|
-
# | | __/\__ \ |_
|
56
|
-
# |_|\___||___/\__|
|
57
|
-
#
|
58
|
-
=begin test
|
59
|
-
|
60
|
-
require 'test/unit'
|
61
|
-
|
62
|
-
class TestHashUpdate < Test::Unit::TestCase
|
63
|
-
|
64
|
-
def test_replace_each
|
65
|
-
a = { :a => 1, :b => 2, :c => 3 }
|
66
|
-
e = { :a => 2, :b => 3, :c => 4 }
|
67
|
-
a.replace_each{ |k,v| { k => v+1 } }
|
68
|
-
assert_equal( e, a )
|
69
|
-
end
|
70
|
-
|
71
|
-
def test_update_each
|
72
|
-
a = { :a => 1, :b => 2, :c => 3 }
|
73
|
-
e = { :a => 2, :b => 3, :c => 4 }
|
74
|
-
a.update_each{ |k,v| { k => v+1 } }
|
75
|
-
assert_equal( e, a )
|
76
|
-
end
|
77
|
-
|
78
|
-
def test_update_keys
|
79
|
-
h = { 'A' => 1, 'B' => 2 }
|
80
|
-
h.update_keys{ |k| k.downcase }
|
81
|
-
assert_equal( { 'a' => 1, 'b' => 2 }, h)
|
82
|
-
end
|
83
|
-
|
84
|
-
def test_update_values
|
85
|
-
h = { 1 => 'A', 2 => 'B' }
|
86
|
-
h.update_values{ |v| v.downcase }
|
87
|
-
assert_equal( { 1 => 'a', 2 => 'b' }, h )
|
88
|
-
end
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
=end
|
93
|
-
|
@@ -1,21 +1,12 @@
|
|
1
|
-
# TITLE:
|
2
|
-
#
|
3
|
-
# Hash Weave Extension
|
4
|
-
#
|
5
|
-
# SUMMARY:
|
6
|
-
#
|
7
|
-
# Weave is a very uniqe hash operator. I is designed
|
8
|
-
# to merge to complex hashes in according to sensible,
|
9
|
-
# regular pattern. The effect is akin to inheritance.
|
10
|
-
#
|
11
|
-
# CREDITS:
|
12
|
-
#
|
13
|
-
# - Thomas Sawyer
|
14
|
-
|
15
1
|
class Hash
|
16
2
|
|
17
|
-
#
|
18
|
-
# to
|
3
|
+
# Weave is a very uniqe hash operator. I is designed
|
4
|
+
# to merge to complex hashes in according to sensible,
|
5
|
+
# regular pattern. The effect is akin to inheritance.
|
6
|
+
#
|
7
|
+
# Two hashes are weaved together to produce a new hash.
|
8
|
+
# The two hashes need to be compatible according to the
|
9
|
+
# following rules for each node:
|
19
10
|
#
|
20
11
|
# <tt>
|
21
12
|
# hash, hash => hash (recursive +)
|
@@ -29,10 +20,23 @@ class Hash
|
|
29
20
|
# value1, value2 => value2
|
30
21
|
# </tt>
|
31
22
|
#
|
32
|
-
#
|
23
|
+
# Here is a basic example:
|
24
|
+
#
|
25
|
+
# h1 = { :a => 1, :b => [ 1 ], :c => { :x => 1 } }
|
26
|
+
# => {:b=>[1], :c=>{:x=>1}, :a=>1}
|
27
|
+
#
|
28
|
+
# h2 = { :a => 2, :b => [ 2 ], :c => { :x => 2 } }
|
29
|
+
# => {:b=>[2], :c=>{:x=>2}, :a=>2}
|
33
30
|
#
|
34
|
-
#
|
31
|
+
# h1.weave(h2)
|
32
|
+
# => {:b=>[1, 2], :c=>{:x=>2}, :a=>2}
|
35
33
|
#
|
34
|
+
# Weave follows the most expected pattern of unifying two complex
|
35
|
+
# hashes. It is especially useful for implementing overridable
|
36
|
+
# configuration schemes.
|
37
|
+
#
|
38
|
+
# CREDIT: Thomas Sawyer
|
39
|
+
|
36
40
|
def weave(h)
|
37
41
|
raise ArgumentError, "Hash expected" unless h.kind_of?(Hash)
|
38
42
|
s = self.clone
|
@@ -75,27 +79,3 @@ class Hash
|
|
75
79
|
end
|
76
80
|
|
77
81
|
end
|
78
|
-
|
79
|
-
|
80
|
-
# _____ _
|
81
|
-
# |_ _|__ ___| |_
|
82
|
-
# | |/ _ \/ __| __|
|
83
|
-
# | | __/\__ \ |_
|
84
|
-
# |_|\___||___/\__|
|
85
|
-
#
|
86
|
-
=begin test
|
87
|
-
|
88
|
-
require 'test/unit'
|
89
|
-
|
90
|
-
class TestHashWeave < Test::Unit::TestCase
|
91
|
-
|
92
|
-
def test_weave
|
93
|
-
b = { :a=>1, :b=>[1,2,3], :c=>{ :x=>'X' } }
|
94
|
-
c = { :a=>2, :b=>[4,5,6], :c=>{ :x=>'A', :y => 'B' } }
|
95
|
-
r = { :a=>2, :b=>[1,2,3,4,5,6], :c=>{ :x => 'A', :y => 'B' } }
|
96
|
-
assert_equal( r, b.weave(c) )
|
97
|
-
end
|
98
|
-
|
99
|
-
end
|
100
|
-
|
101
|
-
=end
|
@@ -16,7 +16,19 @@
|
|
16
16
|
#
|
17
17
|
# AUTHORS:
|
18
18
|
#
|
19
|
-
#
|
19
|
+
# - Thomas Sawyer
|
20
|
+
|
21
|
+
# Indexable is a mixin that provides index based methods,
|
22
|
+
# working soley with four methods: #index, #slice, #splice
|
23
|
+
# and #size.
|
24
|
+
#
|
25
|
+
# These methods work in harmony. Where #index returns a
|
26
|
+
# position of a given element, #slice returns elements
|
27
|
+
# for given positions. #splice is like #slice but replaces
|
28
|
+
# the given position with new values. This mehtod is not
|
29
|
+
# part of ruby core, but it generally just an alias for #[]=,
|
30
|
+
# just as #slice is an alias of #[]. #size of course simply
|
31
|
+
# returns the total length of the indexable object.
|
20
32
|
|
21
33
|
module Indexable
|
22
34
|
|
@@ -24,7 +36,7 @@ module Indexable
|
|
24
36
|
# in a new array.
|
25
37
|
#
|
26
38
|
# [1,2,3].head #=> [1]
|
27
|
-
|
39
|
+
|
28
40
|
def head
|
29
41
|
slice(0,1)
|
30
42
|
end
|
@@ -32,7 +44,7 @@ module Indexable
|
|
32
44
|
# Returns an array from second element to last element.
|
33
45
|
#
|
34
46
|
# [1,2,3].tail #=> [2,3]
|
35
|
-
|
47
|
+
|
36
48
|
def tail
|
37
49
|
slice(1,length-1)
|
38
50
|
end
|
@@ -41,7 +53,7 @@ module Indexable
|
|
41
53
|
# in an array.
|
42
54
|
#
|
43
55
|
# [1,2,3].foot #=> [3]
|
44
|
-
|
56
|
+
|
45
57
|
def foot
|
46
58
|
slice(-1,1)
|
47
59
|
end
|
@@ -54,6 +66,7 @@ module Indexable
|
|
54
66
|
#--
|
55
67
|
# Better name for this? (bulk, perhaps?)
|
56
68
|
#++
|
69
|
+
|
57
70
|
def body
|
58
71
|
slice(0,size-1)
|
59
72
|
end
|
@@ -71,6 +84,7 @@ module Indexable
|
|
71
84
|
# In other words, If there are an even number of elements the
|
72
85
|
# higher-indexed of the two center elements is indexed as
|
73
86
|
# orgin (0).
|
87
|
+
|
74
88
|
def mid(offset=0)
|
75
89
|
slice((size / 2) + offset)
|
76
90
|
end
|
@@ -83,6 +97,7 @@ module Indexable
|
|
83
97
|
# [1,2,3,4,5,6].middle #=> [3,4]
|
84
98
|
#
|
85
99
|
# In contrast to #mid which utilizes an offset.
|
100
|
+
|
86
101
|
def middle
|
87
102
|
if size % 2 == 0
|
88
103
|
slice( (size / 2) - 1, 2 )
|
@@ -96,7 +111,7 @@ module Indexable
|
|
96
111
|
#
|
97
112
|
# [1,2,3,4,5].thru(0,2) #=> [1,2,3]
|
98
113
|
# [1,2,3,4,5].thru(2,4) #=> [3,4,5]
|
99
|
-
|
114
|
+
|
100
115
|
def thru(from, to)
|
101
116
|
a = []
|
102
117
|
i = from
|
@@ -110,7 +125,7 @@ module Indexable
|
|
110
125
|
# Returns first _n_ elements.
|
111
126
|
#
|
112
127
|
# "Hello World".first(3) #=> "Hel"
|
113
|
-
|
128
|
+
|
114
129
|
def first(n=1)
|
115
130
|
slice(0, n.to_i)
|
116
131
|
end
|
@@ -118,7 +133,7 @@ module Indexable
|
|
118
133
|
# Returns last _n_ elements.
|
119
134
|
#
|
120
135
|
# "Hello World".last(3) #=> "rld"
|
121
|
-
|
136
|
+
|
122
137
|
def last(n=1)
|
123
138
|
n = n.to_i
|
124
139
|
return self if n > size
|
@@ -130,7 +145,7 @@ module Indexable
|
|
130
145
|
# a = ["a","y","z"]
|
131
146
|
# a.first = "x"
|
132
147
|
# p a #=> ["x","y","z"]
|
133
|
-
|
148
|
+
|
134
149
|
def first=(x)
|
135
150
|
splice(0,x)
|
136
151
|
end
|
@@ -140,19 +155,27 @@ module Indexable
|
|
140
155
|
# a = [1,2,5]
|
141
156
|
# a.last = 3
|
142
157
|
# p a #=> [1,2,3]
|
143
|
-
|
158
|
+
|
144
159
|
def last=(x)
|
145
160
|
splice(-1,x)
|
146
161
|
end
|
147
162
|
|
148
163
|
# Remove and return the first element.
|
149
164
|
#
|
165
|
+
# a = [1,2,3]
|
166
|
+
# a.first! #=> 1
|
167
|
+
# a #=> [2,3]
|
168
|
+
|
150
169
|
def first!
|
151
170
|
splice(0)
|
152
171
|
end
|
153
172
|
|
154
173
|
# Remove and return the last element.
|
155
174
|
#
|
175
|
+
# a = [1,2,3]
|
176
|
+
# a.last! #=> 3
|
177
|
+
# a #=> [1,2]
|
178
|
+
|
156
179
|
def last!
|
157
180
|
splice(-1)
|
158
181
|
end
|
@@ -164,6 +187,7 @@ module Indexable
|
|
164
187
|
# [1,2,3,4,5].ends #=> 4
|
165
188
|
#
|
166
189
|
# This nearly equivalent to +size - 1+.
|
190
|
+
|
167
191
|
def ends
|
168
192
|
return nil if size == 0
|
169
193
|
size - 1
|
@@ -174,7 +198,7 @@ module Indexable
|
|
174
198
|
#
|
175
199
|
# [1,2,3,4,5].pos(1) #=> 0
|
176
200
|
# [1,2,3,4,5].pos(-1) #=> 4
|
177
|
-
|
201
|
+
|
178
202
|
def pos(i)
|
179
203
|
if i > 0
|
180
204
|
return i - 1
|
@@ -183,9 +207,13 @@ module Indexable
|
|
183
207
|
end
|
184
208
|
end
|
185
209
|
|
186
|
-
#
|
187
|
-
|
188
|
-
#
|
210
|
+
# Returns the index of the first element to satisfy the block
|
211
|
+
# condition. This is simply #index with a block.
|
212
|
+
#
|
213
|
+
# [1,2,3,4].index_of { |e| e == 3 } #=> 2
|
214
|
+
# [1,2,3,4].index_of { |e| e > 3 } #=> 3
|
215
|
+
#
|
216
|
+
# TODO: Remove Array#index_of when Ruby 1.9 adds block to #index.
|
189
217
|
|
190
218
|
def index_of(obj=nil,&blk)
|
191
219
|
return index(obj) unless block_given?
|
@@ -201,7 +229,7 @@ module Indexable
|
|
201
229
|
#
|
202
230
|
# ['a','b','c','d'].range #=> 0..3
|
203
231
|
# ['a','b','c','d'].range('b','d') #=> 1..2
|
204
|
-
|
232
|
+
|
205
233
|
def range(a=nil,z=nil)
|
206
234
|
if !a
|
207
235
|
0..(size-1)
|