facets 2.9.0.pre.1 → 2.9.0.pre.2
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 +1 -0
- data/COPYING +1 -2
- data/HISTORY.rdoc +16 -8
- data/lib/core/facets/hash/subset.rb +24 -0
- data/lib/core/facets/hash/zip.rb +18 -0
- data/lib/core/facets/kernel/try.rb +3 -3
- data/lib/core/facets/module/home.rb +90 -0
- data/lib/core/facets/module/homename.rb +1 -0
- data/lib/core/facets/module/housing.rb +1 -0
- data/lib/core/facets/module/modname.rb +1 -22
- data/lib/core/facets/na.rb +11 -5
- data/lib/core/facets/object/clone.rb +1 -0
- data/lib/core/facets/{kernel/try_dup.rb → object/dup.rb} +41 -35
- data/lib/core/facets/{kernel → object}/object_state.rb +15 -18
- data/lib/core/facets/object/replace.rb +43 -0
- data/lib/core/facets/object/try_dup.rb +1 -0
- data/lib/core/facets/string/cleanlines.rb +2 -0
- data/lib/core/facets/time/ago.rb +1 -1
- data/lib/core/facets/time/in.rb +1 -93
- data/lib/core/facets/time/less.rb +1 -0
- data/lib/core/facets/time/shift.rb +95 -0
- data/lib/more/facets/interval.rb +284 -0
- data/lib/more/facets/math.rb +6 -0
- data/lib/more/facets/math/abs.rb +8 -0
- data/lib/more/facets/math/acot.rb +8 -0
- data/lib/more/facets/math/acoth.rb +8 -0
- data/lib/more/facets/math/acsc.rb +8 -0
- data/lib/more/facets/math/acsch.rb +8 -0
- data/lib/more/facets/math/amd.rb +17 -0
- data/lib/more/facets/math/approx_equal.rb +15 -0
- data/lib/more/facets/math/asec.rb +8 -0
- data/lib/more/facets/math/asech.rb +8 -0
- data/lib/more/facets/math/atkinson_index.rb +16 -0
- data/lib/more/facets/math/beta.rb +9 -0
- data/lib/more/facets/math/cdf.rb +10 -0
- data/lib/more/facets/math/ceil.rb +8 -0
- data/lib/more/facets/math/cot.rb +8 -0
- data/lib/more/facets/math/coth.rb +8 -0
- data/lib/more/facets/math/csc.rb +8 -0
- data/lib/more/facets/math/csch.rb +8 -0
- data/lib/more/facets/math/delta.rb +8 -0
- data/lib/more/facets/math/epsilon.rb +21 -0
- data/lib/more/facets/math/exp10.rb +8 -0
- data/lib/more/facets/math/exp2.rb +8 -0
- data/lib/more/facets/math/factorial.rb +37 -0
- data/lib/more/facets/math/floor.rb +8 -0
- data/lib/more/facets/math/gamma.rb +12 -0
- data/lib/more/facets/math/gcd.rb +23 -0
- data/lib/more/facets/math/gini_coefficient.rb +33 -0
- data/lib/more/facets/math/kldivergence.rb +19 -0
- data/lib/more/facets/math/lcm.rb +15 -0
- data/lib/more/facets/math/lgamma.rb +21 -0
- data/lib/more/facets/math/linsolve.rb +10 -0
- data/lib/more/facets/math/log2.rb +14 -0
- data/lib/more/facets/math/max.rb +1 -0
- data/lib/more/facets/math/mean.rb +16 -0
- data/lib/more/facets/math/median.rb +15 -0
- data/lib/more/facets/math/min.rb +35 -0
- data/lib/more/facets/math/pow.rb +8 -0
- data/lib/more/facets/math/pstd.rb +1 -0
- data/lib/more/facets/math/pvariance.rb +1 -0
- data/lib/more/facets/math/rmd.rb +16 -0
- data/lib/more/facets/math/root.rb +8 -0
- data/lib/more/facets/math/sec.rb +8 -0
- data/lib/more/facets/math/sech.rb +8 -0
- data/lib/more/facets/math/sign.rb +9 -0
- data/lib/more/facets/math/sinc.rb +8 -0
- data/lib/more/facets/math/sqr.rb +8 -0
- data/lib/more/facets/math/sqsolve.rb +53 -0
- data/lib/more/facets/math/std.rb +27 -0
- data/lib/more/facets/math/stderr.rb +1 -0
- data/lib/more/facets/math/sum.rb +16 -0
- data/lib/more/facets/math/summed_sqdevs.rb +14 -0
- data/lib/more/facets/math/theil_index.rb +24 -0
- data/lib/more/facets/math/variance.rb +31 -0
- data/lib/more/facets/thread.rb +24 -0
- data/lib/tour/facets/array/op_pow.rb +5 -0
- data/lib/tour/facets/module/enclosure.rb +15 -1
- data/lib/tour/facets/module/preextend.rb +26 -0
- data/lib/tour/facets/module/prepend.rb +39 -13
- data/meta/gemfile +1 -1
- data/qed/core/binding/caller.rdoc +1 -3
- data/test/core/array/test_after.rb +1 -1
- data/test/core/array/test_before.rb +1 -1
- data/test/core/array/test_conjoin.rb +1 -1
- data/test/core/array/test_store.rb +1 -1
- data/test/core/hash/test_argumentize.rb +1 -1
- data/test/core/hash/test_join.rb +1 -1
- data/test/core/kernel/test_dup.rb +1 -1
- data/test/core/kernel/test_get.rb +1 -1
- data/test/core/kernel/test_qua_class.rb +1 -1
- data/test/core/time/test_ago.rb +5 -117
- data/test/core/time/test_hence.rb +2 -2
- data/test/core/time/test_in.rb +4 -115
- data/test/core/time/test_less.rb +137 -0
- data/test/core/time/test_set.rb +1 -1
- data/test/core/time/test_shift.rb +126 -0
- data/test/more/test_date.rb +1 -1
- data/test/tour/module/test_cattr.rb +1 -1
- data/test/tour/module/test_class_extend.rb +1 -1
- data/test/tour/module/test_instance_function.rb +1 -1
- data/test/tour/module/test_method_space.rb +1 -1
- metadata +76 -10
- data/lib/core/facets/hash/zipnew.rb +0 -18
- data/lib/core/facets/kernel/clone.rb +0 -1
- data/lib/core/facets/kernel/dup.rb +0 -34
- data/lib/core/facets/kernel/replace.rb +0 -1
data/AUTHORS
CHANGED
@@ -9,6 +9,7 @@
|
|
9
9
|
The following developers have recently contributed to the development of Facets.
|
10
10
|
They are held in the highest regard for their efforts.
|
11
11
|
|
12
|
+
* Alexey Petrushin Some methods from `ruby-ext` project.
|
12
13
|
* Michael Harmer Documentation Improvements
|
13
14
|
* Lavir the Whiolet Improved Range#at_rand and added File#ext.
|
14
15
|
* Jean-Denis Vauguet Added Pathname#visit.
|
data/COPYING
CHANGED
data/HISTORY.rdoc
CHANGED
@@ -27,6 +27,10 @@ extensions you want, thus avoiding any conflicts. There are actually only a
|
|
27
27
|
dozen or so overlaps and all are intended to compatible, but it doesn't hurt
|
28
28
|
to be sure.
|
29
29
|
|
30
|
+
Lastly, it is worth mentioning that this release has been more thuroughly
|
31
|
+
tested than any version of Facets to date. Thanks to RVM this release runs
|
32
|
+
green on Ruby 1.8.6, 1.8.7 and 1.9.2.
|
33
|
+
|
30
34
|
Changes:
|
31
35
|
|
32
36
|
* New Features
|
@@ -44,10 +48,13 @@ Changes:
|
|
44
48
|
* Add Module#anonymous?
|
45
49
|
* Add Module#copy_inheritor
|
46
50
|
* Add Indexable#from and Indexable#upto
|
47
|
-
* Add Array#from and Array#
|
51
|
+
* Add Array#from and Array#thru
|
48
52
|
* Add NA class via na.rb
|
49
53
|
* Add Memoizable in memoizable.rb for a more robust memoization system
|
50
54
|
* Add Module#safe_memo in thread.rb for thread safe memoization
|
55
|
+
* Add Kernel#sandbox in thread.rb for threaded $SAFE=4 evaluation
|
56
|
+
* Add Hash#subset
|
57
|
+
* Add numerous Math extensions
|
51
58
|
|
52
59
|
* Deprecations
|
53
60
|
|
@@ -59,9 +66,8 @@ Changes:
|
|
59
66
|
* Deprecate Kernel#populate and #set_from (use #assign and #assign_from)
|
60
67
|
* Deprecate Kernel#non_nil? since #not_nil? is enough
|
61
68
|
* Deprecate #__HERE__ b/c implementation was unreliable
|
62
|
-
* Deprecate
|
63
|
-
* Deprecate Time#
|
64
|
-
* Deprecate Time#advance, use #in instead TODO
|
69
|
+
* Deprecate Time#since, use #less instead
|
70
|
+
* Deprecate Time#advance, use #shift instead
|
65
71
|
* Deprecate Kernel#super_as (no good way to get callers method name)
|
66
72
|
* Deprecate Integer#clear_bit, use #bit_clear instead
|
67
73
|
* Deprecate Kernel#resc, use String#to_re or #to_rx instead
|
@@ -90,6 +96,8 @@ Changes:
|
|
90
96
|
* Rename String#chars to String#characters
|
91
97
|
* Rename String#outdent to String#unindent
|
92
98
|
* Rename Time#round to Time#round_to
|
99
|
+
* Rename Time#hence to Time#shift (but keep aliases)
|
100
|
+
* Rename Hash#zipnew to Hash#zip
|
93
101
|
|
94
102
|
* Moved Libraries
|
95
103
|
|
@@ -121,15 +129,15 @@ Changes:
|
|
121
129
|
* Improved Features
|
122
130
|
|
123
131
|
* New lib/tour division of libraries
|
124
|
-
* Module#class_extend
|
132
|
+
* Module#class_extend dynamically creates append_features method
|
125
133
|
* Kernel#require_all is only for relative requires
|
126
134
|
* __DIR__ can take subdirectory arguments
|
127
135
|
* Hash#join has more sensible default separator (' ')
|
128
|
-
*
|
136
|
+
* Some OpEsc escapes have been renamed
|
129
137
|
* Kernel#assign does not accept a block
|
130
|
-
* Kernel#try is like ActiveSupport
|
138
|
+
* Kernel#try is now like ActiveSupport's
|
131
139
|
* Improved #respond (which is like old #try)
|
132
|
-
* Remove all `if defined?(ActiveSupport)`
|
140
|
+
* Remove all `if defined?(ActiveSupport)` conditions
|
133
141
|
* Use #random_range to support specialized Range#at_rand functionality
|
134
142
|
* Use Comparable.[] instead of Comparable()
|
135
143
|
* Array#rotate rotates in opposite direction than before (b/c or Ruby 1.9)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
# Take a subset of the hash, based on keys given or a block
|
4
|
+
# that evaluates to true for each hash key.
|
5
|
+
#
|
6
|
+
# {'a'=>1, 'b'=>2}.subset('a') #=> {'a'=>1}
|
7
|
+
# {'a'=>1, 'b'=>2}.subset{|k| k == 'a' } #=> {'a'=>1}
|
8
|
+
#
|
9
|
+
# CREDIT: Alexey Petrushin
|
10
|
+
def subset(keys=nil, &block)
|
11
|
+
h = {}
|
12
|
+
if keys
|
13
|
+
self.each do |k, v|
|
14
|
+
h[k] = v if keys.include?(k)
|
15
|
+
end
|
16
|
+
else
|
17
|
+
self.each do |k, v|
|
18
|
+
h[k] = v if block.call(k)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
h
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
# Creates a new hash from two separate arrays, a +keys+ array and
|
4
|
+
# a +values+ array.
|
5
|
+
#
|
6
|
+
# Hash.zip(["a","b","c"], [1,2,3])
|
7
|
+
# # => { "a"=>1, "b"=>2, "c"=>3 }
|
8
|
+
#
|
9
|
+
# CREDIT: Trans, Ara T. Howard
|
10
|
+
|
11
|
+
def self.zip(keys,values) # or some better name
|
12
|
+
h = {}
|
13
|
+
keys.size.times{ |i| h[ keys[i] ] = values[i] }
|
14
|
+
h
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
@@ -18,7 +18,7 @@ module Kernel
|
|
18
18
|
#
|
19
19
|
# or:
|
20
20
|
#
|
21
|
-
# @example? @example.name : nil
|
21
|
+
# @example ? @example.name : nil
|
22
22
|
#
|
23
23
|
# But with try
|
24
24
|
#
|
@@ -26,9 +26,9 @@ module Kernel
|
|
26
26
|
#
|
27
27
|
# or
|
28
28
|
#
|
29
|
-
# @example.try.name
|
29
|
+
# @example.try.name #=> "bob"
|
30
30
|
#
|
31
|
-
# It also accepts arguments and
|
31
|
+
# It also accepts arguments and a block, for the method it is trying:
|
32
32
|
#
|
33
33
|
# @people.try(:collect){ |p| p.name }
|
34
34
|
#
|
@@ -0,0 +1,90 @@
|
|
1
|
+
class Module
|
2
|
+
|
3
|
+
# Returns the module or class containing the receiver.
|
4
|
+
#
|
5
|
+
# module ::HomeExample
|
6
|
+
# module M
|
7
|
+
# module N
|
8
|
+
# end
|
9
|
+
# end
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# HomeExample::M::N.home #=> HomeExample::M
|
13
|
+
#
|
14
|
+
# The home of a top-level module/class is Object.
|
15
|
+
#
|
16
|
+
# HomeExample.home #=> Object
|
17
|
+
#
|
18
|
+
# This method is called *home* because techinally a module or class
|
19
|
+
# is just a constant reference, and as such can reside with multiple
|
20
|
+
# namespaces, like any variable. For example:
|
21
|
+
#
|
22
|
+
# module OtherPlace
|
23
|
+
# M = ::HomeExample::M
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# In this example, you might think that +OtherPlace::M+'s home would be
|
27
|
+
# +OtherPlace+, but +OtherPlace::M+ is the same object as +HomeExample::M+,
|
28
|
+
# and it can have only one "home" --the original location of it's definition.
|
29
|
+
def home
|
30
|
+
#homename = /::[^:]+\Z/ =~ name ? $` : nil
|
31
|
+
if homename
|
32
|
+
homename.split(/::/).inject(self) do |mod, cref|
|
33
|
+
if /\:(0x.*?)\>$/ =~ cref # TODO: does this ever happen?
|
34
|
+
#p $1.to_i(16)
|
35
|
+
ObjectSpace._idref($1.to_i(16))
|
36
|
+
else
|
37
|
+
mod.const_get(cref)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
else
|
41
|
+
Object
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns the name of module or class containing the receiver.
|
46
|
+
#
|
47
|
+
# module ::HomeExample
|
48
|
+
# module M
|
49
|
+
# module N
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# HomeExample::M::N.homename #=> "HomeExample::M"
|
55
|
+
#
|
56
|
+
# See also Module#basename.
|
57
|
+
def homename
|
58
|
+
/::[^:]+\Z/ =~ name ? $` : nil
|
59
|
+
end
|
60
|
+
|
61
|
+
# Original name for #homename.
|
62
|
+
alias_method :modname, :homename
|
63
|
+
|
64
|
+
# Returns all the namespaces of this module according ordered from
|
65
|
+
# nearest and moving outwards. The receiver is not contained within
|
66
|
+
# the result.
|
67
|
+
#
|
68
|
+
# module ::HouseExample
|
69
|
+
# module M
|
70
|
+
# module N
|
71
|
+
# end
|
72
|
+
# end
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# HouseExample.housing #=> [Object]
|
76
|
+
# HouseExample::M.housing #=> [HouseExample, Object]
|
77
|
+
# HouseExample::M::N.housing #=> [HouseExample::M, HouseExample, Object]
|
78
|
+
#
|
79
|
+
# Compare this to +Module.nesting+.
|
80
|
+
def housing
|
81
|
+
n = []
|
82
|
+
name.split(/::/).inject(self) do |mod, cref|
|
83
|
+
c = mod.const_get(cref) ; n.unshift(c) ; c
|
84
|
+
end
|
85
|
+
n << Object # ?
|
86
|
+
n.shift # we really don't need +self+ too.
|
87
|
+
n
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'facets/module/home'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'facets/module/home'
|
@@ -1,22 +1 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
# Returns the name of the module containing this one.
|
4
|
-
#
|
5
|
-
# module ::NSExample
|
6
|
-
# module M
|
7
|
-
# module N
|
8
|
-
# end
|
9
|
-
# end
|
10
|
-
# end
|
11
|
-
#
|
12
|
-
# NSExample::M::N.modname #=> "NSExample::M"
|
13
|
-
#
|
14
|
-
# See also Module#basename.
|
15
|
-
def modname
|
16
|
-
unless defined? @_modname
|
17
|
-
@_modname = name =~ /::[^:]+\Z/ ? $`.freeze : nil
|
18
|
-
end
|
19
|
-
@_modname
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
1
|
+
require 'facets/module/homename'
|
data/lib/core/facets/na.rb
CHANGED
@@ -6,10 +6,16 @@
|
|
6
6
|
#
|
7
7
|
# NA is also used to represent an argument "slot" for Proc#partial.
|
8
8
|
#
|
9
|
-
# NA is
|
9
|
+
# NA is an instance of ArgumentError.
|
10
10
|
|
11
|
-
class NA
|
12
|
-
|
13
|
-
|
14
|
-
end
|
11
|
+
class << NA = ArgumentError.new
|
12
|
+
def inspect ; 'N/A' ; end
|
13
|
+
def method_missing(*); self; end
|
15
14
|
end
|
15
|
+
|
16
|
+
# NA is a subclass of ArgumentError.
|
17
|
+
#class NA < ArgumentError
|
18
|
+
# class << self
|
19
|
+
# def method_missing(*); self; end
|
20
|
+
# end
|
21
|
+
#end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'facets/object/dup'
|
@@ -1,73 +1,79 @@
|
|
1
|
-
|
1
|
+
class Object
|
2
2
|
# Override this in a child class if it cannot be dup'ed.
|
3
3
|
#
|
4
4
|
# obj1 = Object.new
|
5
|
-
# obj2 = obj1.
|
5
|
+
# obj2 = obj1.dup!
|
6
6
|
# obj2.equal?(obj1) #=> false
|
7
7
|
#
|
8
8
|
# CREDIT: Dan Kubb (extlib)
|
9
|
-
def
|
9
|
+
def dup!
|
10
10
|
dup
|
11
11
|
end
|
12
12
|
|
13
|
-
# Alternative name for #
|
14
|
-
def
|
15
|
-
|
13
|
+
# Alternative name for #dup!
|
14
|
+
def try_dup
|
15
|
+
dup!
|
16
16
|
end
|
17
|
+
|
18
|
+
# Can you safely call #dup on this object?
|
19
|
+
#
|
20
|
+
# Returns +false+ for +nil+, +false+, +true+, symbols, and numbers;
|
21
|
+
# +true+ otherwise.
|
22
|
+
def dup? ; true ; end
|
23
|
+
def clone? ; true ; end
|
17
24
|
end
|
18
25
|
|
19
|
-
class
|
20
|
-
# Since
|
26
|
+
class NilClass
|
27
|
+
# Since NilClass is immutable it cannot be duplicated.
|
21
28
|
# For this reason #try_dup returns +self+.
|
22
29
|
#
|
23
|
-
#
|
30
|
+
# nil.dup! #=> nil
|
24
31
|
#
|
25
|
-
def
|
26
|
-
|
27
|
-
end
|
32
|
+
def dup! ; self ; end
|
33
|
+
def dup? ; false ; end
|
34
|
+
def clone? ; false ; end
|
28
35
|
end
|
29
36
|
|
30
37
|
class FalseClass
|
31
38
|
# Since FalseClass is immutable it cannot be duplicated.
|
32
39
|
# For this reason #try_dup returns +self+.
|
33
40
|
#
|
34
|
-
# false.
|
41
|
+
# false.dup! #=> false
|
35
42
|
#
|
36
|
-
def
|
37
|
-
|
38
|
-
end
|
43
|
+
def dup! ; self ; end
|
44
|
+
def dup? ; false ; end
|
45
|
+
def clone? ; false ; end
|
39
46
|
end
|
40
47
|
|
41
|
-
class
|
42
|
-
# Since
|
48
|
+
class TrueClass
|
49
|
+
# Since TrueClass is immutable it cannot be duplicated.
|
43
50
|
# For this reason #try_dup returns +self+.
|
44
51
|
#
|
45
|
-
#
|
52
|
+
# true.dup! #=> true
|
46
53
|
#
|
47
|
-
def
|
48
|
-
|
49
|
-
end
|
54
|
+
def dup! ; self ; end
|
55
|
+
def dup? ; false ; end
|
56
|
+
def clone? ; false ; end
|
50
57
|
end
|
51
58
|
|
52
|
-
class
|
53
|
-
# Since
|
59
|
+
class Symbol
|
60
|
+
# Since Symbol is immutable it cannot be duplicated.
|
54
61
|
# For this reason #try_dup returns +self+.
|
55
62
|
#
|
56
|
-
#
|
63
|
+
# :a.dup! #=> :a
|
57
64
|
#
|
58
|
-
def
|
59
|
-
|
60
|
-
end
|
65
|
+
def dup! ; self ; end
|
66
|
+
def dup? ; false ; end
|
67
|
+
def clone? ; false ; end
|
61
68
|
end
|
62
69
|
|
63
|
-
class
|
64
|
-
# Since
|
70
|
+
class Numeric
|
71
|
+
# Since Numeric is immutable it cannot be duplicated.
|
65
72
|
# For this reason #try_dup returns +self+.
|
66
73
|
#
|
67
|
-
#
|
74
|
+
# 1.dup! #=> 1
|
68
75
|
#
|
69
|
-
def
|
70
|
-
|
71
|
-
end
|
76
|
+
def dup! ; self ; end
|
77
|
+
def dup? ; false ; end
|
78
|
+
def clone? ; false ; end
|
72
79
|
end
|
73
|
-
|
@@ -1,5 +1,6 @@
|
|
1
|
-
class Object
|
2
|
-
# Get or set state of object.
|
1
|
+
class Object
|
2
|
+
# Get or set state of object. You can think of #object_state as an in-code
|
3
|
+
# form of marshalling.
|
3
4
|
#
|
4
5
|
# class StateExample
|
5
6
|
# attr_reader :a, :b
|
@@ -12,13 +13,18 @@ class Object # module Kernel ?
|
|
12
13
|
# obj.a #=> 1
|
13
14
|
# obj.b #=> 2
|
14
15
|
#
|
16
|
+
# obj.object_state #=> {:a=>1, :b=>2}
|
17
|
+
#
|
15
18
|
# obj.object_state(:a=>3, :b=>4)
|
16
19
|
# obj.a #=> 3
|
17
20
|
# obj.b #=> 4
|
18
21
|
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
+
# For most object's this is essentially the same as <code>instance.to_h</code>.
|
23
|
+
# But for data structures like Array and Hash it returns a snapshot of their
|
24
|
+
# contents, not the state of their instance variables.
|
25
|
+
#--
|
26
|
+
# TODO: Should this be in module Kernel ?
|
27
|
+
#++
|
22
28
|
def object_state(data=nil)
|
23
29
|
if data
|
24
30
|
instance_variables.each do |iv|
|
@@ -34,35 +40,31 @@ class Object # module Kernel ?
|
|
34
40
|
data
|
35
41
|
end
|
36
42
|
end
|
37
|
-
|
38
|
-
# Replace state of object.
|
39
|
-
def replace(data)
|
40
|
-
instance_variables.each do |iv|
|
41
|
-
name = iv.to_s.sub(/^[@]/, '').to_sym
|
42
|
-
instance_variable_set(iv, data[name])
|
43
|
-
end
|
44
|
-
end
|
45
43
|
end
|
46
44
|
|
47
45
|
class Array
|
46
|
+
#
|
48
47
|
def object_state(data=nil)
|
49
48
|
data ? replace(data) : dup
|
50
49
|
end
|
51
50
|
end
|
52
51
|
|
53
52
|
class String
|
53
|
+
#
|
54
54
|
def object_state(data=nil)
|
55
55
|
data ? replace(data) : dup
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
59
|
class Hash
|
60
|
+
#
|
60
61
|
def object_state(data=nil)
|
61
62
|
data ? replace(data) : dup
|
62
63
|
end
|
63
64
|
end
|
64
65
|
|
65
66
|
class Struct
|
67
|
+
#
|
66
68
|
def object_state(data=nil)
|
67
69
|
if data
|
68
70
|
data.each_pair {|k,v| send(k.to_s + "=", v)}
|
@@ -72,9 +74,4 @@ class Struct
|
|
72
74
|
data
|
73
75
|
end
|
74
76
|
end
|
75
|
-
|
76
|
-
def replace(data)
|
77
|
-
data.each_pair {|k,v| send(k.to_s + "=", v)}
|
78
|
-
end
|
79
77
|
end
|
80
|
-
|