deep_clonable 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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