deep_clonable 1.0.2 → 1.1.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/VERSION +1 -0
- data/deep_clonable.gemspec +13 -18
- data/lib/deep_clonable.rb +32 -23
- data/test/deep_clonable_test.rb +78 -19
- metadata +22 -11
- data/VERSION.yml +0 -5
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.1.0
|
data/deep_clonable.gemspec
CHANGED
@@ -1,46 +1,41 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{deep_clonable}
|
8
|
-
s.version = "1.0
|
8
|
+
s.version = "1.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Justin Balthrop"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2011-06-02}
|
13
13
|
s.description = %q{ Add support for deep cloning to objects}
|
14
14
|
s.email = %q{code@justinbalthrop.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
17
|
-
|
17
|
+
"README.rdoc"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
"LICENSE",
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
"README.rdoc",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION",
|
24
|
+
"deep_clonable.gemspec",
|
25
|
+
"lib/deep_clonable.rb",
|
26
|
+
"test/deep_clonable_test.rb",
|
27
|
+
"test/test_helper.rb"
|
28
28
|
]
|
29
29
|
s.homepage = %q{http://github.com/ninjudd/deep_clonable}
|
30
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
31
30
|
s.require_paths = ["lib"]
|
32
|
-
s.rubygems_version = %q{1.3.
|
31
|
+
s.rubygems_version = %q{1.3.7}
|
33
32
|
s.summary = %q{Add support for deep cloning to objects}
|
34
|
-
s.test_files = [
|
35
|
-
"test/deep_clonable_test.rb",
|
36
|
-
"test/test_helper.rb"
|
37
|
-
]
|
38
33
|
|
39
34
|
if s.respond_to? :specification_version then
|
40
35
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
41
36
|
s.specification_version = 3
|
42
37
|
|
43
|
-
if Gem::Version.new(Gem::
|
38
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
44
39
|
else
|
45
40
|
end
|
46
41
|
else
|
data/lib/deep_clonable.rb
CHANGED
@@ -8,25 +8,37 @@ end
|
|
8
8
|
module DeepClonable
|
9
9
|
module InstanceMethods
|
10
10
|
def clone
|
11
|
-
|
12
|
-
cloned_object.
|
13
|
-
cloned_object
|
11
|
+
was_frozen = frozen?
|
12
|
+
cloned_object = super.dup
|
13
|
+
cloned_object = yield(cloned_object) if block_given?
|
14
|
+
was_frozen ? cloned_object.freeze : cloned_object
|
14
15
|
end
|
15
|
-
|
16
|
-
def dup
|
17
|
-
cloned_object = super
|
18
|
-
cloned_object.
|
16
|
+
|
17
|
+
def dup(method = :dup)
|
18
|
+
cloned_object = super()
|
19
|
+
cloned_object.update_vars(deep_vars, method)
|
19
20
|
cloned_object
|
20
21
|
end
|
21
22
|
|
22
|
-
|
23
|
+
alias old_freeze freeze
|
24
|
+
|
25
|
+
def freeze
|
26
|
+
dup(:freeze).old_freeze
|
27
|
+
end
|
28
|
+
|
29
|
+
# You can override deep_vars in your class to specify which instance_variables should be deep cloned.
|
23
30
|
# As it is, all Arrays and Hashes are deep cloned.
|
24
|
-
def
|
25
|
-
instance_variables.
|
26
|
-
value = instance_variable_get(
|
27
|
-
|
28
|
-
|
29
|
-
|
31
|
+
def deep_vars
|
32
|
+
instance_variables.select do |var|
|
33
|
+
value = instance_variable_get(var)
|
34
|
+
value.kind_of?(Array) or value.kind_of?(Hash) or value.kind_of?(DeepClonable::InstanceMethods)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def update_vars(vars, method)
|
39
|
+
vars.each do |var|
|
40
|
+
value = instance_variable_get(var)
|
41
|
+
instance_variable_set(var, value.send(method))
|
30
42
|
end
|
31
43
|
end
|
32
44
|
end
|
@@ -34,8 +46,8 @@ module DeepClonable
|
|
34
46
|
module ClassMethods
|
35
47
|
# Use this to define cloning version of the given in-place methods.
|
36
48
|
#
|
37
|
-
# This method supports a common idiom where you create in-place and
|
38
|
-
# cloning versions of most operations. This method allows you to
|
49
|
+
# This method supports a common idiom where you create in-place and
|
50
|
+
# cloning versions of most operations. This method allows you to
|
39
51
|
# define only the in-place version (with the trailing bang (!),
|
40
52
|
# that part is important) and specify the cloning versions by name
|
41
53
|
# using this method.
|
@@ -43,13 +55,10 @@ module DeepClonable
|
|
43
55
|
clone_method_name = clone_method_name.to_s.gsub(/\!$/,'')
|
44
56
|
method_name ||= "#{clone_method_name}!"
|
45
57
|
class_eval %{
|
46
|
-
def #{clone_method_name}(*args)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
yield object
|
51
|
-
else
|
52
|
-
object
|
58
|
+
def #{clone_method_name}(*args, &block)
|
59
|
+
self.clone do |object|
|
60
|
+
object.#{method_name}(*args)
|
61
|
+
block ? block.call(object) : object
|
53
62
|
end
|
54
63
|
end
|
55
64
|
}
|
data/test/deep_clonable_test.rb
CHANGED
@@ -1,41 +1,100 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/test_helper'
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
2
|
|
3
3
|
class TestClass
|
4
4
|
deep_clonable
|
5
|
-
|
6
|
-
attr_reader :num
|
7
|
-
|
8
|
-
def initialize(
|
9
|
-
@num
|
5
|
+
|
6
|
+
attr_reader :num, :hash, :array
|
7
|
+
|
8
|
+
def initialize(num, hash, array)
|
9
|
+
@num = num
|
10
|
+
@hash = hash
|
11
|
+
@array = array
|
10
12
|
end
|
11
|
-
|
13
|
+
|
12
14
|
clone_method :+, :add!
|
13
15
|
def add!(other)
|
14
16
|
@num += other.num
|
17
|
+
@hash.merge!(other.hash)
|
18
|
+
@array.concat(other.array)
|
15
19
|
end
|
16
20
|
|
17
21
|
clone_method :invert
|
18
22
|
def invert!
|
19
|
-
@num
|
23
|
+
@num = -(@num)
|
24
|
+
@hash = @hash.invert
|
25
|
+
@array.reverse!
|
20
26
|
end
|
21
27
|
end
|
22
28
|
|
23
29
|
class DeepClonableTest < Test::Unit::TestCase
|
24
|
-
should
|
25
|
-
a = TestClass.new(10)
|
30
|
+
should "clone method" do
|
31
|
+
a = TestClass.new(10, {:a => 1}, [1,2,3])
|
26
32
|
b = a.invert
|
27
|
-
|
28
|
-
assert_equal
|
29
|
-
assert_equal
|
33
|
+
|
34
|
+
assert_equal(10, a.num)
|
35
|
+
assert_equal({:a => 1}, a.hash)
|
36
|
+
assert_equal([1,2,3], a.array)
|
37
|
+
|
38
|
+
assert_equal(-10, b.num)
|
39
|
+
assert_equal({1 => :a}, b.hash)
|
40
|
+
assert_equal([3,2,1], b.array)
|
30
41
|
end
|
31
42
|
|
32
43
|
should 'clone method with rename' do
|
33
|
-
a = TestClass.new(10)
|
34
|
-
b = TestClass.new(20)
|
44
|
+
a = TestClass.new(10, {:a => 1}, [1])
|
45
|
+
b = TestClass.new(20, {:b => 2}, [2,3])
|
35
46
|
c = a + b
|
36
|
-
|
37
|
-
assert_equal
|
38
|
-
assert_equal
|
39
|
-
assert_equal
|
47
|
+
|
48
|
+
assert_equal(10, a.num)
|
49
|
+
assert_equal({:a => 1}, a.hash)
|
50
|
+
assert_equal([1], a.array)
|
51
|
+
|
52
|
+
assert_equal(20, b.num)
|
53
|
+
assert_equal({:b => 2}, b.hash)
|
54
|
+
assert_equal([2,3], b.array)
|
55
|
+
|
56
|
+
assert_equal(30, c.num)
|
57
|
+
assert_equal({:a => 1, :b => 2}, c.hash)
|
58
|
+
assert_equal([1,2,3], c.array)
|
59
|
+
end
|
60
|
+
|
61
|
+
should "return a frozen object when cloning a frozen object" do
|
62
|
+
a = TestClass.new(10, {:a => 1}, [1,2,3]).freeze
|
63
|
+
|
64
|
+
assert_raises(TypeError) do
|
65
|
+
a.invert!
|
66
|
+
end
|
67
|
+
|
68
|
+
b = a.invert
|
69
|
+
|
70
|
+
assert_equal(10, a.num)
|
71
|
+
assert_equal({:a => 1}, a.hash)
|
72
|
+
assert_equal([1,2,3], a.array)
|
73
|
+
|
74
|
+
assert_equal(-10, b.num)
|
75
|
+
assert_equal({1 => :a}, b.hash)
|
76
|
+
assert_equal([3,2,1], b.array)
|
77
|
+
|
78
|
+
assert a.frozen?
|
79
|
+
assert b.frozen?
|
80
|
+
assert a.clone.frozen?
|
81
|
+
end
|
82
|
+
|
83
|
+
should "unfreeze an object when duping" do
|
84
|
+
a = TestClass.new(10, {:a => 1}, [1,2,3]).freeze
|
85
|
+
b = a.dup
|
86
|
+
|
87
|
+
assert a.frozen?
|
88
|
+
assert !b.frozen?
|
89
|
+
|
90
|
+
b.invert!
|
91
|
+
|
92
|
+
assert_equal(10, a.num)
|
93
|
+
assert_equal({:a => 1}, a.hash)
|
94
|
+
assert_equal([1,2,3], a.array)
|
95
|
+
|
96
|
+
assert_equal(-10, b.num)
|
97
|
+
assert_equal({1 => :a}, b.hash)
|
98
|
+
assert_equal([3,2,1], b.array)
|
40
99
|
end
|
41
100
|
end
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deep_clonable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 19
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 1.1.0
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Justin Balthrop
|
@@ -9,7 +15,7 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2011-06-02 00:00:00 -07:00
|
13
19
|
default_executable:
|
14
20
|
dependencies: []
|
15
21
|
|
@@ -26,7 +32,7 @@ files:
|
|
26
32
|
- LICENSE
|
27
33
|
- README.rdoc
|
28
34
|
- Rakefile
|
29
|
-
- VERSION
|
35
|
+
- VERSION
|
30
36
|
- deep_clonable.gemspec
|
31
37
|
- lib/deep_clonable.rb
|
32
38
|
- test/deep_clonable_test.rb
|
@@ -36,29 +42,34 @@ homepage: http://github.com/ninjudd/deep_clonable
|
|
36
42
|
licenses: []
|
37
43
|
|
38
44
|
post_install_message:
|
39
|
-
rdoc_options:
|
40
|
-
|
45
|
+
rdoc_options: []
|
46
|
+
|
41
47
|
require_paths:
|
42
48
|
- lib
|
43
49
|
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
44
51
|
requirements:
|
45
52
|
- - ">="
|
46
53
|
- !ruby/object:Gem::Version
|
54
|
+
hash: 3
|
55
|
+
segments:
|
56
|
+
- 0
|
47
57
|
version: "0"
|
48
|
-
version:
|
49
58
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
50
60
|
requirements:
|
51
61
|
- - ">="
|
52
62
|
- !ruby/object:Gem::Version
|
63
|
+
hash: 3
|
64
|
+
segments:
|
65
|
+
- 0
|
53
66
|
version: "0"
|
54
|
-
version:
|
55
67
|
requirements: []
|
56
68
|
|
57
69
|
rubyforge_project:
|
58
|
-
rubygems_version: 1.3.
|
70
|
+
rubygems_version: 1.3.7
|
59
71
|
signing_key:
|
60
72
|
specification_version: 3
|
61
73
|
summary: Add support for deep cloning to objects
|
62
|
-
test_files:
|
63
|
-
|
64
|
-
- test/test_helper.rb
|
74
|
+
test_files: []
|
75
|
+
|