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
@@ -0,0 +1,47 @@
|
|
1
|
+
class Time
|
2
|
+
|
3
|
+
#
|
4
|
+
|
5
|
+
unless const_defined?('FORMAT')
|
6
|
+
FORMAT = {
|
7
|
+
:db => "%Y-%m-%d %H:%M:%S",
|
8
|
+
:dbase => "%Y-%m-%d %H:%M:%S",
|
9
|
+
:datbase => "%Y-%m-%d %H:%M:%S",
|
10
|
+
:utc => "%Y-%m-%d %H:%M:%S",
|
11
|
+
:short => "%d %b %H:%M",
|
12
|
+
:long => "%B %d, %Y %H:%M",
|
13
|
+
:day1st => "%d-%m-%Y %H:%M",
|
14
|
+
:dmYHM => "%d-%m-%Y %H:%M",
|
15
|
+
:rfc822 => "%a, %d %b %Y %H:%M:%S %z",
|
16
|
+
nil => "%a %b %d %H:%M:%S %Z %Y"
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
# Produce time stamp for Time.now. See #stamp.
|
21
|
+
#
|
22
|
+
# CREDIT: Trans
|
23
|
+
|
24
|
+
def self.stamp(*args)
|
25
|
+
now.stamp(*args)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Create a time stamp.
|
29
|
+
#
|
30
|
+
# Time.now.stamp(:short) #=> "01 Dec 15:15"
|
31
|
+
#
|
32
|
+
# Supported formats come from the Time::FORMAT constant.
|
33
|
+
#
|
34
|
+
# CREDIT: Trans
|
35
|
+
|
36
|
+
def stamp(fmt = nil)
|
37
|
+
unless String === fmt
|
38
|
+
fmt = FORMAT[fmt]
|
39
|
+
end
|
40
|
+
strftime(fmt).strip
|
41
|
+
end
|
42
|
+
|
43
|
+
# DEPRECATED.
|
44
|
+
# Enhance #to_s by aliasing to #stamp.
|
45
|
+
#alias_method :to_s, :stamp
|
46
|
+
|
47
|
+
end
|
@@ -1,19 +1,42 @@
|
|
1
1
|
class UnboundMethod
|
2
2
|
|
3
3
|
# Resolves the arguments of the method to have an
|
4
|
-
#
|
4
|
+
# identical signiture --useful for preserving arity.
|
5
|
+
#
|
6
|
+
# class X
|
7
|
+
# def foo(a, b); end
|
8
|
+
# def bar(a, b=1); end
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# foo_method = X.instance_method(:foo)
|
12
|
+
# foo_method.arguments #=> "a0, a1"
|
13
|
+
#
|
14
|
+
# bar_method = X.instance_method(:bar)
|
15
|
+
# bar_method.arguments #=> "a0, *args"
|
16
|
+
#
|
17
|
+
# When defaults are used the arguments must end in "*args".
|
18
|
+
#
|
19
|
+
# CREDIT: Trans
|
5
20
|
|
6
21
|
def arguments
|
7
|
-
|
22
|
+
ar = arity
|
23
|
+
case ar <=> 0
|
24
|
+
when 1
|
8
25
|
args = []
|
9
26
|
ar.times do |i|
|
10
27
|
args << "a#{i}"
|
11
28
|
end
|
12
29
|
args = args.join(", ")
|
13
|
-
|
30
|
+
when 0
|
14
31
|
args = ""
|
15
32
|
else
|
16
|
-
|
33
|
+
ar = -ar - 1
|
34
|
+
args = []
|
35
|
+
ar.times do |i|
|
36
|
+
args << "a#{i}"
|
37
|
+
end
|
38
|
+
args << "*args"
|
39
|
+
args = args.join(", ")
|
17
40
|
end
|
18
41
|
return args
|
19
42
|
end
|
@@ -1,12 +1,26 @@
|
|
1
|
+
# DEPRECATE for 1.9
|
2
|
+
unless (RUBY_VERSION[0,3] == '1.9')
|
1
3
|
|
2
|
-
class UnboundMethod
|
4
|
+
class UnboundMethod
|
5
|
+
|
6
|
+
# Return the name of the method.
|
7
|
+
# Is this already in 1.9+ ?
|
8
|
+
#
|
9
|
+
# class X
|
10
|
+
# def foo; end
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# meth = X.instance_method(:foo)
|
14
|
+
#
|
15
|
+
# meth.name #=> "foo"
|
16
|
+
#
|
17
|
+
# CREDIT: Trans
|
18
|
+
|
19
|
+
def name
|
20
|
+
i = to_s.rindex('#')
|
21
|
+
to_s.slice(i+1...-1)
|
22
|
+
end
|
3
23
|
|
4
|
-
# Return the name of the method.
|
5
|
-
# Is this already in 1.9+ ?
|
6
|
-
#
|
7
|
-
def name
|
8
|
-
i = to_s.rindex('#')
|
9
|
-
to_s.slice(i+1...-1)
|
10
24
|
end
|
11
25
|
|
12
26
|
end
|
@@ -1 +1 @@
|
|
1
|
-
require 'facets/enumerable/
|
1
|
+
require 'facets/enumerable/split.rb'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'facets/enumerable/mash.rb'
|
@@ -1 +1 @@
|
|
1
|
-
require 'facets/enumerable/
|
1
|
+
require 'facets/enumerable/split.rb'
|
@@ -1 +1 @@
|
|
1
|
-
require 'facets/enumerable/
|
1
|
+
require 'facets/enumerable/each.rb'
|
@@ -1 +1 @@
|
|
1
|
-
require 'facets/enumerable/
|
1
|
+
require 'facets/enumerable/each.rb'
|
@@ -1 +1 @@
|
|
1
|
-
require 'facets/enumerable/
|
1
|
+
require 'facets/enumerable/each.rb'
|
@@ -1 +1 @@
|
|
1
|
-
require 'facets/enumerable/
|
1
|
+
require 'facets/enumerable/mash.rb'
|
@@ -1 +1 @@
|
|
1
|
-
require 'facets/enumerable/
|
1
|
+
require 'facets/enumerable/split.rb'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'facets/enumerable/collect.rb'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'facets/enumerable/collect.rb'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'facets/enumerable/split.rb'
|
@@ -1 +1 @@
|
|
1
|
-
require 'facets/enumerable/
|
1
|
+
require 'facets/enumerable/split.rb'
|
@@ -1 +1 @@
|
|
1
|
-
require 'facets/enumerable/
|
1
|
+
require 'facets/enumerable/mash.rb'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'facets/hash/slice.rb'
|
@@ -1 +1 @@
|
|
1
|
-
require 'facets/enumerable/
|
1
|
+
require 'facets/enumerable/mash.rb'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'facets/enumerable/mash.rb'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'facets/integer/bitmask.rb'
|
@@ -1 +1 @@
|
|
1
|
-
require 'facets/kernel/
|
1
|
+
require 'facets/kernel/returning.rb'
|
@@ -1 +1 @@
|
|
1
|
-
require 'facets/binding/
|
1
|
+
require 'facets/binding/here.rb'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'facets/kernel/val.rb'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'facets/kernel/respond.rb'
|
@@ -1 +1 @@
|
|
1
|
-
require 'facets/kernel/
|
1
|
+
require 'facets/kernel/returning.rb'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'facets/kernel/metaid.rb'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'facets/string/case.rb'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'facets/string/op.rb'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'facets/string/case.rb'
|
@@ -48,7 +48,7 @@ require 'facets/inheritor.rb'
|
|
48
48
|
|
49
49
|
class ::Module
|
50
50
|
|
51
|
-
inheritor :
|
51
|
+
inheritor :instance_attributes, [], :|
|
52
52
|
|
53
53
|
def attr( *args )
|
54
54
|
args.flatten!
|
@@ -92,7 +92,7 @@ class ::Module
|
|
92
92
|
a = a.to_sym
|
93
93
|
ann(a,harg)
|
94
94
|
}
|
95
|
-
|
95
|
+
instance_attributes!.concat( args ) #merge!
|
96
96
|
|
97
97
|
# Use this callback to customize for your needs.
|
98
98
|
if respond_to?(:attr_callback)
|
@@ -120,11 +120,11 @@ class ::Module
|
|
120
120
|
# attr_accessor :age, Fixnum
|
121
121
|
# end
|
122
122
|
#
|
123
|
-
# MyClass.
|
123
|
+
# MyClass.instance_attributes # => [:test, :name, :age, :body]
|
124
124
|
# MyClass.classified_attributes # => [:name, :age]
|
125
125
|
|
126
126
|
def classified_attributes
|
127
|
-
|
127
|
+
instance_attributes.find_all do |a|
|
128
128
|
self.ann(a, :class)
|
129
129
|
end
|
130
130
|
end
|
@@ -151,7 +151,7 @@ end
|
|
151
151
|
|
152
152
|
def test_09_001
|
153
153
|
a = A.new
|
154
|
-
assert_equal( [:x], A.
|
154
|
+
assert_equal( [:x], A.instance_attributes )
|
155
155
|
end
|
156
156
|
end
|
157
157
|
|
@@ -232,65 +232,3 @@ class Module
|
|
232
232
|
end
|
233
233
|
=end
|
234
234
|
|
235
|
-
|
236
|
-
# _____ _
|
237
|
-
# |_ _|__ ___| |_
|
238
|
-
# | |/ _ \/ __| __|
|
239
|
-
# | | __/\__ \ |_
|
240
|
-
# |_|\___||___/\__|
|
241
|
-
#
|
242
|
-
|
243
|
-
=begin test
|
244
|
-
|
245
|
-
require 'test/unit'
|
246
|
-
|
247
|
-
class TCBasicObject < Test::Unit::TestCase
|
248
|
-
|
249
|
-
class A < BasicObject
|
250
|
-
end
|
251
|
-
|
252
|
-
def setup
|
253
|
-
@a = A.new
|
254
|
-
end
|
255
|
-
|
256
|
-
def test_001
|
257
|
-
assert( ! @a.object_class.method_defined?( :id ) )
|
258
|
-
assert( ! @a.object_class.method_defined?( :class ) )
|
259
|
-
end
|
260
|
-
|
261
|
-
def test_002
|
262
|
-
assert( @a.object_class.method_defined?( :__id__ ) )
|
263
|
-
assert( @a.object_class.method_defined?( :__send__ ) )
|
264
|
-
assert( @a.object_class.method_defined?( :object_self ) )
|
265
|
-
assert( @a.object_class.method_defined?( :dup ) )
|
266
|
-
assert( @a.object_class.method_defined?( :as ) )
|
267
|
-
end
|
268
|
-
|
269
|
-
def test_003
|
270
|
-
assert_equal( A, @a.object_self.class )
|
271
|
-
end
|
272
|
-
|
273
|
-
def test_004
|
274
|
-
Kernel.module_eval { def xxx ; end }
|
275
|
-
assert( ! @a.object_class.method_defined?( :xxx ) )
|
276
|
-
end
|
277
|
-
|
278
|
-
def test_005
|
279
|
-
Object.class_eval { def yyy ; end }
|
280
|
-
assert( ! @a.object_class.method_defined?( :yyy ) )
|
281
|
-
end
|
282
|
-
|
283
|
-
def test_006
|
284
|
-
Object.class_eval { def yyy ; end }
|
285
|
-
assert( ! @a.object_self.methods.include?( 'yyy' ) )
|
286
|
-
end
|
287
|
-
|
288
|
-
def test_007
|
289
|
-
Object.class_eval { def yyy ; end }
|
290
|
-
assert( ! @a.object_class.method_defined?( :methods ) )
|
291
|
-
assert( ! @a.object_self.methods.include?( :methods ) )
|
292
|
-
end
|
293
|
-
|
294
|
-
end
|
295
|
-
|
296
|
-
=end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
# There is no continuation in Ruby 1.9.
|
2
|
+
|
3
|
+
raise "Ruby 1.9+ does not support continuations." unless Continuation
|
1
4
|
|
2
5
|
# Creates a continuation in a way that is easier to use than callcc.
|
3
6
|
# On the initial call this will return the created Continuation and
|
@@ -42,30 +45,10 @@
|
|
42
45
|
# end
|
43
46
|
# [1,2,3,4,5].cc_inject { |acc, n| acc + n } # => 15
|
44
47
|
#
|
48
|
+
|
45
49
|
def Continuation.create(*args, &block)
|
46
50
|
args = [args] if not args.nil? and not args.is_a? Array # 1.6.8 compatibility
|
47
51
|
cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?}
|
48
52
|
result ||= args
|
49
53
|
return *[cc, *result]
|
50
54
|
end
|
51
|
-
|
52
|
-
|
53
|
-
# _____ _
|
54
|
-
# |_ _|__ ___| |_
|
55
|
-
# | |/ _ \/ __| __|
|
56
|
-
# | | __/\__ \ |_
|
57
|
-
# |_|\___||___/\__|
|
58
|
-
#
|
59
|
-
=begin test
|
60
|
-
|
61
|
-
require 'test/unit'
|
62
|
-
|
63
|
-
class TCContinuation < Test::Unit::TestCase
|
64
|
-
|
65
|
-
def test_Continuation_create
|
66
|
-
assert_nothing_raised { c, r = Continuation.create }
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
=end
|
@@ -0,0 +1,534 @@
|
|
1
|
+
# = Title:
|
2
|
+
#
|
3
|
+
# Duration
|
4
|
+
#
|
5
|
+
# = Synopsis:
|
6
|
+
#
|
7
|
+
# Duration is a simple class that provides ways of easily manipulating durations
|
8
|
+
# (timespans) and formatting them as well.
|
9
|
+
#
|
10
|
+
# = Copying:
|
11
|
+
#
|
12
|
+
# Copyright (c) 2006 Matthew Harris <shugotenshi at gmail.com>
|
13
|
+
#
|
14
|
+
# = Author:
|
15
|
+
#
|
16
|
+
# Matthew Harris (mailto:shugotenshi@gmail.com)
|
17
|
+
#
|
18
|
+
# = Notes:
|
19
|
+
#
|
20
|
+
# - This library comes from the orginal Duration project.
|
21
|
+
# See: http://www.rubyforge.org/projects/duration
|
22
|
+
#
|
23
|
+
|
24
|
+
# = Duration
|
25
|
+
#
|
26
|
+
# Duration is a simple class that provides ways of easily manipulating durations
|
27
|
+
# (timespans) and formatting them as well.
|
28
|
+
#
|
29
|
+
# == Usage:
|
30
|
+
#
|
31
|
+
# require 'duration'
|
32
|
+
# => true
|
33
|
+
# d = Duration.new(60 * 60 * 24 * 10 + 120 + 30)
|
34
|
+
# => #<Duration: 1 week, 3 days, 2 minutes and 30 seconds>
|
35
|
+
# d.to_s
|
36
|
+
# => "1 week, 3 days, 2 minutes and 30 seconds"
|
37
|
+
# [d.weeks, d.days]
|
38
|
+
# => [1, 3]
|
39
|
+
# d.days = 7; d
|
40
|
+
# => #<Duration: 2 weeks, 2 minutes and 30 seconds>
|
41
|
+
# d.strftime('%w w, %d d, %h h, %m m, %s s')
|
42
|
+
# => "2 w, 0 d, 0 h, 2 m, 30 s"
|
43
|
+
|
44
|
+
class Duration
|
45
|
+
include Comparable
|
46
|
+
include Enumerable
|
47
|
+
|
48
|
+
attr_reader :total, :weeks, :days, :hours, :minutes
|
49
|
+
|
50
|
+
WEEK = 60 * 60 * 24 * 7
|
51
|
+
DAY = 60 * 60 * 24
|
52
|
+
HOUR = 60 * 60
|
53
|
+
MINUTE = 60
|
54
|
+
SECOND = 1
|
55
|
+
|
56
|
+
# Initialize Duration class.
|
57
|
+
#
|
58
|
+
# *Example*
|
59
|
+
#
|
60
|
+
# d = Duration.new(60 * 60 * 24 * 10 + 120 + 30)
|
61
|
+
# => #<Duration: 1 week, 3 days, 2 minutes and 30 seconds>
|
62
|
+
# d = Duration.new(:weeks => 1, :days => 3, :minutes => 2, :seconds => 30)
|
63
|
+
# => #<Duration: 1 week, 3 days, 2 minutes and 30 seconds>
|
64
|
+
#
|
65
|
+
def initialize(seconds_or_attr = 0)
|
66
|
+
if seconds_or_attr.kind_of? Hash
|
67
|
+
# Part->time map table.
|
68
|
+
h = {:weeks => WEEK, :days => DAY, :hours => HOUR, :minutes => MINUTE, :seconds => SECOND}
|
69
|
+
|
70
|
+
# Loop through each valid part, ignore all others.
|
71
|
+
seconds = seconds_or_attr.inject(0) do |sec, args|
|
72
|
+
# Grab the part of the duration (week, day, whatever) and the number of seconds for it.
|
73
|
+
part, time = args
|
74
|
+
|
75
|
+
# Map each part to their number of seconds and the given value.
|
76
|
+
# {:weeks => 2} maps to h[:weeks] -- so... weeks = WEEK * 2
|
77
|
+
if h.key?(prt = part.to_s.to_sym) then sec + time * h[prt] else 0 end
|
78
|
+
end
|
79
|
+
else
|
80
|
+
seconds = seconds_or_attr
|
81
|
+
end
|
82
|
+
|
83
|
+
@total, array = seconds.to_f.round, []
|
84
|
+
@seconds = [WEEK, DAY, HOUR, MINUTE].inject(@total) do |left, part|
|
85
|
+
array << left / part; left % part
|
86
|
+
end
|
87
|
+
|
88
|
+
@weeks, @days, @hours, @minutes = array
|
89
|
+
end
|
90
|
+
|
91
|
+
# Format duration.
|
92
|
+
#
|
93
|
+
# *Identifiers*
|
94
|
+
#
|
95
|
+
# %w -- Number of weeks
|
96
|
+
# %d -- Number of days
|
97
|
+
# %h -- Number of hours
|
98
|
+
# %m -- Number of minutes
|
99
|
+
# %s -- Number of seconds
|
100
|
+
# %t -- Total number of seconds
|
101
|
+
# %x -- Duration#to_s
|
102
|
+
# %% -- Literal `%' character
|
103
|
+
#
|
104
|
+
# *Example*
|
105
|
+
#
|
106
|
+
# d = Duration.new(:weeks => 10, :days => 7)
|
107
|
+
# => #<Duration: 11 weeks>
|
108
|
+
# d.strftime("It's been %w weeks!")
|
109
|
+
# => "It's been 11 weeks!"
|
110
|
+
#
|
111
|
+
def strftime(fmt)
|
112
|
+
h =\
|
113
|
+
{'w' => @weeks ,
|
114
|
+
'd' => @days ,
|
115
|
+
'h' => @hours ,
|
116
|
+
'm' => @minutes,
|
117
|
+
's' => @seconds,
|
118
|
+
't' => @total ,
|
119
|
+
'x' => to_s}
|
120
|
+
|
121
|
+
fmt.gsub(/%?%(w|d|h|m|s|t|x)/) do |match|
|
122
|
+
match.size == 3 ? match : h[match[1..1]]
|
123
|
+
end.gsub('%%', '%')
|
124
|
+
end
|
125
|
+
|
126
|
+
# Get the number of seconds of a given part, or simply just get the number of
|
127
|
+
# seconds.
|
128
|
+
#
|
129
|
+
# *Example*
|
130
|
+
#
|
131
|
+
# d = Duration.new(:weeks => 1, :days => 1, :hours => 1, :seconds => 30)
|
132
|
+
# => #<Duration: 1 week, 1 day, 1 hour and 30 seconds>
|
133
|
+
# d.seconds(:weeks)
|
134
|
+
# => 604800
|
135
|
+
# d.seconds(:days)
|
136
|
+
# => 86400
|
137
|
+
# d.seconds(:hours)
|
138
|
+
# => 3600
|
139
|
+
# d.seconds
|
140
|
+
# => 30
|
141
|
+
#
|
142
|
+
def seconds(part = nil)
|
143
|
+
# Table mapping
|
144
|
+
h = {:weeks => WEEK, :days => DAY, :hours => HOUR, :minutes => MINUTE}
|
145
|
+
|
146
|
+
if [:weeks, :days, :hours, :minutes].include? part
|
147
|
+
__send__(part) * h[part]
|
148
|
+
else
|
149
|
+
@seconds
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# For iterating through the duration set of weeks, days, hours, minutes, and
|
154
|
+
# seconds.
|
155
|
+
#
|
156
|
+
# *Example*
|
157
|
+
#
|
158
|
+
# Duration.new(:weeks => 1, :seconds => 30).each do |part, time|
|
159
|
+
# puts "part: #{part}, time: #{time}"
|
160
|
+
# end
|
161
|
+
#
|
162
|
+
# _Output_
|
163
|
+
#
|
164
|
+
# part: weeks, time: 1
|
165
|
+
# part: days, time: 0
|
166
|
+
# part: hours, time: 0
|
167
|
+
# part: minutes, time: 0
|
168
|
+
# part: seconds, time: 30
|
169
|
+
#
|
170
|
+
def each
|
171
|
+
[['weeks' , @weeks ],
|
172
|
+
['days' , @days ],
|
173
|
+
['hours' , @hours ],
|
174
|
+
['minutes' , @minutes],
|
175
|
+
['seconds' , @seconds]].each do |part, time|
|
176
|
+
# Yield to block
|
177
|
+
yield part, time
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# Calls `<=>' on Duration#total.
|
182
|
+
#
|
183
|
+
# *Example*
|
184
|
+
#
|
185
|
+
# 5.days == 24.hours * 5
|
186
|
+
# => true
|
187
|
+
#
|
188
|
+
def <=>(other)
|
189
|
+
@total <=> other.to_i
|
190
|
+
end
|
191
|
+
|
192
|
+
# Set the number of weeks.
|
193
|
+
#
|
194
|
+
# *Example*
|
195
|
+
#
|
196
|
+
# d = Duration.new(0)
|
197
|
+
# => #<Duration: ...>
|
198
|
+
# d.weeks = 2; d
|
199
|
+
# => #<Duration: 2 weeks>
|
200
|
+
#
|
201
|
+
def weeks=(n)
|
202
|
+
initialize(:weeks => n, :seconds => @total - seconds(:weeks))
|
203
|
+
end
|
204
|
+
|
205
|
+
# Set the number of days.
|
206
|
+
#
|
207
|
+
# *Example*
|
208
|
+
#
|
209
|
+
# d = Duration.new(0)
|
210
|
+
# => #<Duration: ...>
|
211
|
+
# d.days = 5; d
|
212
|
+
# => #<Duration: 5 days>
|
213
|
+
#
|
214
|
+
def days=(n)
|
215
|
+
initialize(:days => n, :seconds => @total - seconds(:days))
|
216
|
+
end
|
217
|
+
|
218
|
+
# Set the number of hours.
|
219
|
+
#
|
220
|
+
# *Example*
|
221
|
+
#
|
222
|
+
# d = Duration.new(0)
|
223
|
+
# => #<Duration: ...>
|
224
|
+
# d.hours = 5; d
|
225
|
+
# => #<Duration: 5 hours>
|
226
|
+
#
|
227
|
+
def hours=(n)
|
228
|
+
initialize(:hours => n, :seconds => @total - seconds(:hours))
|
229
|
+
end
|
230
|
+
|
231
|
+
# Set the number of minutes.
|
232
|
+
#
|
233
|
+
# *Example*
|
234
|
+
#
|
235
|
+
# d = Duration.new(0)
|
236
|
+
# => #<Duration: ...>
|
237
|
+
# d.minutes = 30; d
|
238
|
+
# => #<Duration: 30 minutes>
|
239
|
+
#
|
240
|
+
def minutes=(n)
|
241
|
+
initialize(:minutes => n, :seconds => @total - seconds(:minutes))
|
242
|
+
end
|
243
|
+
|
244
|
+
# Set the number of minutes.
|
245
|
+
#
|
246
|
+
# *Example*
|
247
|
+
#
|
248
|
+
# d = Duration.new(0)
|
249
|
+
# => #<Duration: ...>
|
250
|
+
# d.seconds = 30; d
|
251
|
+
# => #<Duration: 30 seconds>
|
252
|
+
#
|
253
|
+
def seconds=(n)
|
254
|
+
initialize(:seconds => (@total + n) - @seconds)
|
255
|
+
end
|
256
|
+
|
257
|
+
# Friendly, human-readable string representation of the duration.
|
258
|
+
#
|
259
|
+
# *Example*
|
260
|
+
#
|
261
|
+
# d = Duration.new(:seconds => 140)
|
262
|
+
# => #<Duration: 2 minutes and 20 seconds>
|
263
|
+
# d.to_s
|
264
|
+
# => "2 minutes and 20 seconds"
|
265
|
+
#
|
266
|
+
def to_s
|
267
|
+
str = ''
|
268
|
+
|
269
|
+
each do |part, time|
|
270
|
+
# Skip any zero times.
|
271
|
+
next if time.zero?
|
272
|
+
|
273
|
+
# Concatenate the part of the time and the time itself.
|
274
|
+
str << "#{time} #{time == 1 ? part[0..-2] : part}, "
|
275
|
+
end
|
276
|
+
|
277
|
+
str.chomp(', ').sub(/(.+), (.+)/, '\1 and \2')
|
278
|
+
end
|
279
|
+
|
280
|
+
# Inspection string--Similar to #to_s except that it has the class name.
|
281
|
+
#
|
282
|
+
# *Example*
|
283
|
+
#
|
284
|
+
# Duration.new(:seconds => 140)
|
285
|
+
# => #<Duration: 2 minutes and 20 seconds>
|
286
|
+
#
|
287
|
+
def inspect
|
288
|
+
"#<#{self.class}: #{(s = to_s).empty? ? '...' : s}>"
|
289
|
+
end
|
290
|
+
|
291
|
+
# Add to Duration.
|
292
|
+
#
|
293
|
+
# *Example*
|
294
|
+
#
|
295
|
+
# d = Duration.new(30)
|
296
|
+
# => #<Duration: 30 seconds>
|
297
|
+
# d + 30
|
298
|
+
# => #<Duration: 1 minute>
|
299
|
+
#
|
300
|
+
def +(other)
|
301
|
+
self.class.new(@total + other.to_i)
|
302
|
+
end
|
303
|
+
|
304
|
+
# Subtract from Duration.
|
305
|
+
#
|
306
|
+
# *Example*
|
307
|
+
#
|
308
|
+
# d = Duration.new(30)
|
309
|
+
# => #<Duration: 30 seconds>
|
310
|
+
# d - 15
|
311
|
+
# => #<Duration: 15 seconds>
|
312
|
+
#
|
313
|
+
def -(other)
|
314
|
+
self.class.new(@total - other.to_i)
|
315
|
+
end
|
316
|
+
|
317
|
+
# Multiply two Durations.
|
318
|
+
#
|
319
|
+
# *Example*
|
320
|
+
#
|
321
|
+
# d = Duration.new(30)
|
322
|
+
# => #<Duration: 30 seconds>
|
323
|
+
# d * 2
|
324
|
+
# => #<Duration: 1 minute>
|
325
|
+
#
|
326
|
+
def *(other)
|
327
|
+
self.class.new(@total * other.to_i)
|
328
|
+
end
|
329
|
+
|
330
|
+
# Divide two Durations.
|
331
|
+
#
|
332
|
+
# *Example*
|
333
|
+
#
|
334
|
+
# d = Duration.new(30)
|
335
|
+
# => #<Duration: 30 seconds>
|
336
|
+
# d / 2
|
337
|
+
# => #<Duration: 15 seconds>
|
338
|
+
#
|
339
|
+
def /(other)
|
340
|
+
self.class.new(@total / other.to_i)
|
341
|
+
end
|
342
|
+
|
343
|
+
alias to_i total
|
344
|
+
end
|
345
|
+
|
346
|
+
# BigDuration is a variant of Duration that supports years and months. Support
|
347
|
+
# for months is not accurate, as a month is assumed to be 30 days so use at your
|
348
|
+
# own risk.
|
349
|
+
#
|
350
|
+
class BigDuration < Duration
|
351
|
+
attr_reader :years, :months
|
352
|
+
|
353
|
+
YEAR = 60 * 60 * 24 * 30 * 12
|
354
|
+
MONTH = 60 * 60 * 24 * 30
|
355
|
+
|
356
|
+
# Similar to Duration.new except that BigDuration.new supports `:years' and
|
357
|
+
# `:months' and will also handle years and months correctly when breaking down
|
358
|
+
# the seconds.
|
359
|
+
#
|
360
|
+
def initialize(seconds_or_attr = 0)
|
361
|
+
if seconds_or_attr.kind_of? Hash
|
362
|
+
# Part->time map table.
|
363
|
+
h =\
|
364
|
+
{:years => YEAR ,
|
365
|
+
:months => MONTH ,
|
366
|
+
:weeks => WEEK ,
|
367
|
+
:days => DAY ,
|
368
|
+
:hours => HOUR ,
|
369
|
+
:minutes => MINUTE,
|
370
|
+
:seconds => SECOND}
|
371
|
+
|
372
|
+
# Loop through each valid part, ignore all others.
|
373
|
+
seconds = seconds_or_attr.inject(0) do |sec, args|
|
374
|
+
# Grab the part of the duration (week, day, whatever) and the number of seconds for it.
|
375
|
+
part, time = args
|
376
|
+
|
377
|
+
# Map each part to their number of seconds and the given value.
|
378
|
+
# {:weeks => 2} maps to h[:weeks] -- so... weeks = WEEK * 2
|
379
|
+
if h.key?(prt = part.to_s.to_sym) then sec + time * h[prt] else 0 end
|
380
|
+
end
|
381
|
+
else
|
382
|
+
seconds = seconds_or_attr
|
383
|
+
end
|
384
|
+
|
385
|
+
@total, array = seconds.to_f.round, []
|
386
|
+
@seconds = [YEAR, MONTH, WEEK, DAY, HOUR, MINUTE].inject(@total) do |left, part|
|
387
|
+
array << left / part; left % part
|
388
|
+
end
|
389
|
+
|
390
|
+
@years, @months, @weeks, @days, @hours, @minutes = array
|
391
|
+
end
|
392
|
+
|
393
|
+
# BigDuration variant of Duration#strftime.
|
394
|
+
#
|
395
|
+
# *Identifiers: BigDuration*
|
396
|
+
#
|
397
|
+
# %y -- Number of years
|
398
|
+
# %m -- Number of months
|
399
|
+
#
|
400
|
+
def strftime(fmt)
|
401
|
+
h = {'y' => @years, 'M' => @months}
|
402
|
+
super(fmt.gsub(/%?%(y|M)/) { |match| match.size == 3 ? match : h[match[1..1]] })
|
403
|
+
end
|
404
|
+
|
405
|
+
# Similar to Duration#each except includes years and months in the interation.
|
406
|
+
#
|
407
|
+
def each
|
408
|
+
[['years' , @years ],
|
409
|
+
['months' , @months ],
|
410
|
+
['weeks' , @weeks ],
|
411
|
+
['days' , @days ],
|
412
|
+
['hours' , @hours ],
|
413
|
+
['minutes' , @minutes],
|
414
|
+
['seconds' , @seconds]].each do |part, time|
|
415
|
+
# Yield to block
|
416
|
+
yield part, time
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
# Derived from Duration#seconds, but supports `:years' and `:months' as well.
|
421
|
+
#
|
422
|
+
def seconds(part = nil)
|
423
|
+
h = {:years => YEAR, :months => MONTH}
|
424
|
+
if [:years, :months].include? part
|
425
|
+
__send__(part) * h[part]
|
426
|
+
else
|
427
|
+
super(part)
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
# Set the number of years in the BigDuration.
|
432
|
+
#
|
433
|
+
def years=(n)
|
434
|
+
initialize(:years => n, :seconds => @total - seconds(:years))
|
435
|
+
end
|
436
|
+
|
437
|
+
# Set the number of months in the BigDuration.
|
438
|
+
#
|
439
|
+
def months=(n)
|
440
|
+
initialize(:months => n, :seconds => @total - seconds(:months))
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
# The following important additions are made to Numeric:
|
445
|
+
#
|
446
|
+
# Numeric#weeks -- Create a Duration object with given weeks
|
447
|
+
# Numeric#days -- Create a Duration object with given days
|
448
|
+
# Numeric#hours -- Create a Duration object with given hours
|
449
|
+
# Numeric#minutes -- Create a Duration object with given minutes
|
450
|
+
# Numeric#seconds -- Create a Duration object with given seconds
|
451
|
+
#
|
452
|
+
# BigDuration support:
|
453
|
+
#
|
454
|
+
# Numeric#years -- Create a BigDuration object with given years
|
455
|
+
# Numeric#months -- Create a BigDuration object with given months
|
456
|
+
#
|
457
|
+
# BigDuration objects can be created from regular weeks, days, hours, etc by
|
458
|
+
# providing `:big' as an argument to the above Numeric methods.
|
459
|
+
|
460
|
+
#
|
461
|
+
class Numeric
|
462
|
+
# Create a Duration object using self where self could represent weeks, days,
|
463
|
+
# hours, minutes, and seconds.
|
464
|
+
#
|
465
|
+
# *Example*
|
466
|
+
#
|
467
|
+
# 10.duration(:weeks)
|
468
|
+
# => #<Duration: 10 weeks>
|
469
|
+
# 10.duration
|
470
|
+
# => #<Duration: 10 seconds>
|
471
|
+
#
|
472
|
+
def duration(part = nil, klass = Duration)
|
473
|
+
if [:years, :months, :weeks, :days, :hours, :minutes, :seconds].include? part
|
474
|
+
klass.new(part => self)
|
475
|
+
else
|
476
|
+
klass.new(self)
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
# TODO: IF WE WANT TO DO THIS IT NEEDS TO BE ADDED TO times.rb ???
|
481
|
+
#
|
482
|
+
# alias __numeric_old_method_missing method_missing
|
483
|
+
#
|
484
|
+
# # Intercept calls to .weeks, .days, .hours, .minutes and .seconds because
|
485
|
+
# # Rails defines its own methods, so I'd like to prevent any redefining of
|
486
|
+
# # Rails' methods. If these methods don't get captured, then alternatively
|
487
|
+
# # Numeric#duration can be used.
|
488
|
+
# #
|
489
|
+
# # BigDuration methods include .years and .months, also BigDuration objects
|
490
|
+
# # can be created from any time such as weeks or minutes and even seconds.
|
491
|
+
# #
|
492
|
+
# # *Example: BigDuration*
|
493
|
+
# #
|
494
|
+
# # 5.years
|
495
|
+
# # => #<BigDuration: 5 years>
|
496
|
+
# # 10.minutes(:big)
|
497
|
+
# # => #<BigDuration: 10 minutes>
|
498
|
+
# #
|
499
|
+
# # *Example*
|
500
|
+
# #
|
501
|
+
# # 140.seconds
|
502
|
+
# # => #<Duration: 2 minutes and 20 seconds>
|
503
|
+
# #
|
504
|
+
# def method_missing(method, *args)
|
505
|
+
# if [:weeks, :days, :hours, :minutes, :seconds].include? method
|
506
|
+
# if args.size > 0 && args[0] == :big
|
507
|
+
# duration(method, BigDuration)
|
508
|
+
# else
|
509
|
+
# duration(method)
|
510
|
+
# end
|
511
|
+
# elsif [:years, :months].include? method
|
512
|
+
# duration(method, BigDuration)
|
513
|
+
# else
|
514
|
+
# __numeric_old_method_missing(method, *args)
|
515
|
+
# end
|
516
|
+
# end
|
517
|
+
|
518
|
+
end
|
519
|
+
|
520
|
+
# Time#duration has been added to convert the UNIX timestamp into a Duration.
|
521
|
+
# See Time#duration for an example.
|
522
|
+
#
|
523
|
+
class Time
|
524
|
+
# Create a Duration object from the UNIX timestamp.
|
525
|
+
#
|
526
|
+
# *Example*
|
527
|
+
#
|
528
|
+
# Time.now.duration
|
529
|
+
# => #<Duration: 1898 weeks, 6 days, 1 hour, 12 minutes and 1 second>
|
530
|
+
#
|
531
|
+
def duration(type = nil)
|
532
|
+
if type == :big then BigDuration.new(to_i) else Duration.new(to_i) end
|
533
|
+
end
|
534
|
+
end
|