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 ADDED
@@ -0,0 +1 @@
1
+ 1.1.0
@@ -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 the gemspec command
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.2"
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{2010-04-13}
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
- "README.rdoc"
17
+ "README.rdoc"
18
18
  ]
19
19
  s.files = [
20
20
  "LICENSE",
21
- "README.rdoc",
22
- "Rakefile",
23
- "VERSION.yml",
24
- "deep_clonable.gemspec",
25
- "lib/deep_clonable.rb",
26
- "test/deep_clonable_test.rb",
27
- "test/test_helper.rb"
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.5}
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::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
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
- cloned_object = super
12
- cloned_object.clone_fields
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.clone_fields
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
- # You can override clone_fields in your class to do deep clone in place.
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 clone_fields
25
- instance_variables.each do |variable|
26
- value = instance_variable_get(variable)
27
- if value.kind_of?(Array) or value.kind_of?(Hash) or value.kind_of?(DeepClonable::InstanceMethods)
28
- instance_variable_set(variable, value.clone)
29
- end
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
- object = self.clone
48
- object.#{method_name}(*args)
49
- if block_given?
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
  }
@@ -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(n)
9
- @num = n
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 = -(@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 'clone method' do
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 10, a.num
29
- assert_equal 10, -b.num
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 30, c.num
38
- assert_equal 20, b.num
39
- assert_equal 10, a.num
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
- version: 1.0.2
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: 2010-04-13 00:00:00 -07:00
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.yml
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
- - --charset=UTF-8
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.5
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
- - test/deep_clonable_test.rb
64
- - test/test_helper.rb
74
+ test_files: []
75
+
data/VERSION.yml DELETED
@@ -1,5 +0,0 @@
1
- ---
2
- :build:
3
- :patch: 2
4
- :major: 1
5
- :minor: 0