init_copy 0.1.2 → 0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 334205ab1c79efe1d230625d0c8f6790624b1ad6fc7b0c4d53c398659d8accc6
4
- data.tar.gz: 2251d54cef9fd610da58f62bfeb550f8bec0019f3f2d06811028648c7575c94b
3
+ metadata.gz: 1620d2aa498e981be870fd3e0d671595b0407e557b54e40cf7e32b38b95158a8
4
+ data.tar.gz: 1b08062be47d208e59ed5a70e548f726d55936ccc000a84bbda5b2ed47119360
5
5
  SHA512:
6
- metadata.gz: e78215e491c98eb64d1e3d8b8920559151ce92ba2fe23e858832f82f90da7b40d71fc2b41ee2968c35ab88835c47ac9263fd1e6cc149ed6974a3787d7d985a5d
7
- data.tar.gz: f2cafe04cd905f0f31083e30343e73029cf5ae5fc8f1b5d28c141e1caeea4fb4575d3f77dde841da21d76f4aa667a767513e9bd93fe0f04a33b928ff53994c37
6
+ metadata.gz: 17b1bc267564f9f49c5b699581f522690bc13a63addbab7708bbb6af227970f3701c0f259d00d0d42b4c898e5b349324672b416395d5d0d34be151cf48994db0
7
+ data.tar.gz: e2973b90f3bd28a061904a1db08435b2f2a5af11c2a7bc4d14ce1a40bfbc7837099b0c8c786ea39b064714b041d87994420890ff6f6ae30afb621dac6f31d89b
data/.rdoc_options ADDED
@@ -0,0 +1,28 @@
1
+ ---
2
+ charset: UTF-8
3
+ encoding: UTF-8
4
+
5
+ op_dir: doc
6
+ title: InitCopy
7
+ main_page: README.md
8
+
9
+ apply_default_exclude: true
10
+ embed_mixins: true
11
+ force_update: true
12
+ hyperlink_all: true
13
+ line_numbers: true
14
+ show_hash: true
15
+ skip_tests: true
16
+
17
+ exclude:
18
+ - /.git/
19
+ - /.github/
20
+ - /.idea/
21
+ - /doc/
22
+ - /pkg/
23
+ - /spec/
24
+ - /stock/
25
+ - /test/
26
+ - Gemfile
27
+ - Gemfile.lock
28
+ - Rakefile
data/Gemfile CHANGED
@@ -1,7 +1,16 @@
1
1
  # encoding: UTF-8
2
2
  # frozen_string_literal: true
3
3
 
4
-
5
4
  source 'https://rubygems.org'
6
5
 
7
6
  gemspec
7
+
8
+ group :development,:test do
9
+ gem 'bundler' ,'~> 2.6'
10
+ gem 'rake' ,'~> 13.3'
11
+ gem 'rdoc' ,'~> 6.14'
12
+ end
13
+
14
+ group :test do
15
+ gem 'minitest' ,'~> 5.25'
16
+ end
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2020-2021 Jonathan Bradley Whited
3
+ Copyright (c) 2020-2025 Bradley Whited
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md ADDED
@@ -0,0 +1,162 @@
1
+ # InitCopy
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/init_copy.svg)](https://badge.fury.io/rb/init_copy)
4
+ [![CI Status](https://github.com/esotericpig/init_copy/actions/workflows/ci.yml/badge.svg)](https://github.com/esotericpig/init_copy/actions/workflows/ci.yml)
5
+
6
+ [![Source Code](https://img.shields.io/badge/source-github-%23211F1F.svg)](https://github.com/esotericpig/init_copy)
7
+ [![Changelog](https://img.shields.io/badge/changelog-md-%23A0522D.svg)](CHANGELOG.md)
8
+ [![License](https://img.shields.io/github/license/esotericpig/init_copy.svg)](LICENSE.txt)
9
+
10
+ 🧬 Easily use the correct `clone` or `dup` method in `initialize_copy`.
11
+
12
+ If we only use either `clone` or `dup` or we use `Marshal`, then that does not produce the correct behavior according to the [standard documentation](https://docs.ruby-lang.org/en/master/Object.html#method-i-dup-label-on+dup+vs+clone). This is because `clone` should preserve the internal state (e.g., the frozen state and extended modules), while `dup` should not. For example:
13
+
14
+ ```ruby
15
+ module SecretExt
16
+ def secret
17
+ 'password'
18
+ end
19
+ end
20
+
21
+ bob = 'Bob'
22
+ bob.extend(SecretExt)
23
+ bob.freeze
24
+
25
+ clone = bob.clone
26
+ dup = bob.dup
27
+
28
+ puts clone.frozen? #=> true
29
+ puts dup.frozen? #=> false
30
+
31
+ puts clone.secret #=> password
32
+ puts dup.secret #=> NoMethodError
33
+ ```
34
+
35
+ To solve this issue in the past, we had to define both `initialize_clone` & `initialize_dup` and maintain two copies of all our deep-copy code. That sucks. 😞
36
+
37
+ 🚀 Instead, *InitCopy* was created:
38
+ 1. Install the gem `init_copy` ([RubyGems.org page](https://rubygems.org/gems/init_copy)).
39
+ 2. Include `InitCopy` in your class/module.
40
+ 3. Override the `init_copy(original)` method.
41
+ 4. Use `ic_copy(var)`, instead of clone/dup.
42
+
43
+ Example usage:
44
+
45
+ ```ruby
46
+ require 'init_copy'
47
+
48
+ class JangoFett
49
+ include InitCopy
50
+
51
+ attr_reader :gear,:order66
52
+
53
+ def initialize
54
+ super
55
+
56
+ @gear = ['blaster','jetpack']
57
+
58
+ @order66 = Class.new do
59
+ undef_method :clone
60
+ undef_method :dup
61
+ end.new
62
+ end
63
+
64
+ protected
65
+
66
+ def init_copy(_orig)
67
+ super
68
+
69
+ @gear = ic_copy(@gear)
70
+ @order66 = ic_copy?(@order66) # Safe copy if no dup/clone.
71
+ end
72
+ end
73
+
74
+ jango = JangoFett.new
75
+ jango.freeze
76
+
77
+ boba1 = jango.clone
78
+ boba2 = jango.dup
79
+
80
+ jango.gear << 'vibroblade'
81
+ boba1.gear << 'implant'
82
+
83
+ puts jango.gear.inspect #=> ["blaster", "jetpack", "vibroblade"]
84
+
85
+ puts boba1.gear.inspect #=> ["blaster", "jetpack", "implant"]
86
+ puts boba2.gear.inspect #=> ["blaster", "jetpack"]
87
+
88
+ puts boba1.frozen? #=> true (clone)
89
+ puts boba2.frozen? #=> false (dup)
90
+ ```
91
+
92
+ ## // Contents
93
+
94
+ - [Setup](#-setup)
95
+ - [Hacking](#-hacking)
96
+ - [License](#-license)
97
+
98
+ ## [//](#-contents) Setup
99
+
100
+ Pick your poison...
101
+
102
+ With the *RubyGems* CLI package manager:
103
+
104
+ ```bash
105
+ gem install init_copy
106
+ ```
107
+
108
+ In your *Gemspec*:
109
+
110
+ ```ruby
111
+ spec.add_dependency 'init_copy', '~> X.X'
112
+ ```
113
+
114
+ In your *Gemfile*:
115
+
116
+ ```ruby
117
+ # Pick one...
118
+ gem 'init_copy', '~> X.X'
119
+
120
+ gem 'init_copy', git: 'https://github.com/esotericpig/init_copy.git', branch: 'main'
121
+ ```
122
+
123
+ From source:
124
+
125
+ ```bash
126
+ git clone 'https://github.com/esotericpig/init_copy.git'
127
+ cd init_copy
128
+ bundle install
129
+ bundle exec rake install:local
130
+ ```
131
+
132
+ ## [//](#-contents) Hacking
133
+
134
+ ```bash
135
+ git clone 'https://github.com/esotericpig/init_copy.git'
136
+ cd init_copy
137
+ bundle install
138
+ bundle exec rake -T
139
+ ```
140
+
141
+ Testing:
142
+
143
+ ```bash
144
+ bundle exec rake test
145
+ ```
146
+
147
+ Generating doc:
148
+
149
+ ```bash
150
+ bundle exec rake clobber_doc doc
151
+ ```
152
+
153
+ Installing:
154
+
155
+ ```bash
156
+ bundle exec rake install:local
157
+ ```
158
+
159
+ ## [//](#-contents) License
160
+
161
+ Copyright (c) 2020-2025 Bradley Whited
162
+ [MIT License](LICENSE.txt)
data/Rakefile CHANGED
@@ -1,39 +1,27 @@
1
1
  # encoding: UTF-8
2
2
  # frozen_string_literal: true
3
3
 
4
-
5
4
  require 'bundler/gem_tasks'
6
5
 
7
6
  require 'init_copy'
8
7
  require 'rake/clean'
9
8
  require 'rake/testtask'
10
- require 'yard'
11
-
9
+ require 'rdoc/task'
12
10
 
13
- CLEAN.exclude('.git/','stock/')
11
+ CLEAN.exclude('.git/','.github/','.idea/','stock/')
14
12
  CLOBBER.include('doc/')
15
13
 
16
-
17
- task default: [:test]
18
-
19
- desc 'Generate doc (YARDoc)'
20
- task :doc,%i[] => %i[yard]
14
+ task default: %i[test]
21
15
 
22
16
  Rake::TestTask.new do |task|
23
17
  task.libs = ['lib','test']
24
- task.pattern = File.join('test','**','*_test.rb')
25
- task.description += ": '#{task.pattern}'"
18
+ task.pattern = 'test/**/*_test.rb'
19
+ task.options = '--pride'
26
20
  task.verbose = false
27
21
  task.warning = true
28
22
  end
29
23
 
30
- YARD::Rake::YardocTask.new do |task|
31
- task.files = [File.join('lib','**','*.{rb}')]
32
-
33
- task.options += ['--files','CHANGELOG.md,LICENSE.txt']
34
- task.options += ['--readme','README.md']
35
-
36
- task.options << '--protected' # Show protected methods
37
- #task.options += ['--template-path',File.join('yard','templates')]
38
- task.options += ['--title',"InitCopy v#{InitCopy::VERSION} Doc"]
24
+ RDoc::Task.new(:doc) do |task|
25
+ task.rdoc_dir = 'doc'
26
+ task.title = "InitCopy v#{InitCopy::VERSION}"
39
27
  end
data/init_copy.gemspec CHANGED
@@ -1,39 +1,45 @@
1
1
  # encoding: UTF-8
2
2
  # frozen_string_literal: true
3
3
 
4
-
5
4
  require_relative 'lib/init_copy'
6
5
 
7
-
8
6
  Gem::Specification.new do |spec|
9
7
  spec.name = 'init_copy'
10
8
  spec.version = InitCopy::VERSION
11
- spec.authors = ['Jonathan Bradley Whited']
9
+ spec.authors = ['Bradley Whited']
12
10
  spec.email = ['code@esotericpig.com']
13
11
  spec.licenses = ['MIT']
14
12
  spec.homepage = 'https://github.com/esotericpig/init_copy'
15
- spec.summary = 'Easily use the appropriate clone/dup method in initialize_copy.'
13
+ spec.summary = 'Easily use the correct clone or dup method in initialize_copy.'
16
14
  spec.description = spec.summary
17
15
 
18
16
  spec.metadata = {
19
- 'bug_tracker_uri' => 'https://github.com/esotericpig/init_copy/issues',
20
- 'changelog_uri' => 'https://github.com/esotericpig/init_copy/blob/master/CHANGELOG.md',
21
- 'homepage_uri' => 'https://github.com/esotericpig/init_copy',
22
- 'source_code_uri' => 'https://github.com/esotericpig/init_copy'
17
+ 'rubygems_mfa_required' => 'true',
18
+ 'homepage_uri' => 'https://github.com/esotericpig/init_copy',
19
+ 'source_code_uri' => 'https://github.com/esotericpig/init_copy',
20
+ 'bug_tracker_uri' => 'https://github.com/esotericpig/init_copy/issues',
21
+ 'changelog_uri' => 'https://github.com/esotericpig/init_copy/blob/main/CHANGELOG.md',
23
22
  }
24
23
 
25
- spec.require_paths = ['lib']
26
-
27
- spec.files = Dir.glob(File.join("{#{spec.require_paths.join(',')}}",'**','*.{rb}')) +
28
- %W[ Gemfile #{spec.name}.gemspec Rakefile ] +
29
- %w[ LICENSE.txt ]
30
-
31
24
  # Lowest version that isn't eol (end-of-life).
32
25
  # - https://www.ruby-lang.org/en/downloads/branches/
33
- spec.required_ruby_version = '>= 2.4'
34
-
35
- spec.add_development_dependency 'bundler' ,'~> 2.2'
36
- spec.add_development_dependency 'minitest','~> 5.14'
37
- spec.add_development_dependency 'rake' ,'~> 13.0'
38
- spec.add_development_dependency 'yard' ,'~> 0.9' # For doc
26
+ spec.required_ruby_version = '>= 3.2'
27
+ spec.require_paths = ['lib']
28
+ spec.bindir = 'bin'
29
+ spec.executables = []
30
+
31
+ spec.extra_rdoc_files = %w[LICENSE.txt README.md]
32
+ spec.rdoc_options = [
33
+ %w[--embed-mixins --hyperlink-all --line-numbers --show-hash],
34
+ '--main','README.md',
35
+ '--title',"InitCopy v#{InitCopy::VERSION}",
36
+ ].flatten
37
+
38
+ spec.files = [
39
+ Dir.glob("{#{spec.require_paths.join(',')}}/**/*.{erb,rb}"),
40
+ Dir.glob("#{spec.bindir}/*"),
41
+ Dir.glob('{spec,test}/**/*.{erb,rb}'),
42
+ %W[Gemfile #{spec.name}.gemspec Rakefile .rdoc_options],
43
+ spec.extra_rdoc_files,
44
+ ].flatten
39
45
  end
data/lib/init_copy.rb CHANGED
@@ -3,120 +3,77 @@
3
3
 
4
4
  #--
5
5
  # This file is part of InitCopy.
6
- # Copyright (c) 2020-2021 Jonathan Bradley Whited
6
+ # Copyright (c) 2020 Bradley Whited
7
7
  #
8
8
  # SPDX-License-Identifier: MIT
9
9
  #++
10
10
 
11
-
12
- ###
13
- # @author Jonathan Bradley Whited
14
- # @since 0.1.0
15
- ###
11
+ # Example usage:
12
+ # require 'init_copy'
13
+ #
14
+ # class JangoFett
15
+ # include InitCopy
16
+ #
17
+ # protected
18
+ #
19
+ # def init_copy(_orig)
20
+ # super
21
+ #
22
+ # @gear = ic_copy(@gear)
23
+ # @order66 = ic_copy?(@order66) # Safe copy if no dup/clone.
24
+ # end
25
+ # end
16
26
  module InitCopy
17
- VERSION = '0.1.2'
27
+ VERSION = '0.2.0'
18
28
 
19
- DEFAULT_COPY_NAME = :dup
29
+ def self.included(mod)
30
+ super
20
31
 
21
- def self.new(default_name=DEFAULT_COPY_NAME)
22
- return Copier.new(default_name)
32
+ # NOTE: Can't use prepend(), else children's init_copy() won't call their parents', even with super().
33
+ mod.include(Copyable)
23
34
  end
24
35
 
25
- def self.find_copy_name(default_name=DEFAULT_COPY_NAME)
26
- copy_name = default_name
27
-
28
- caller.each do |name|
29
- if name.end_with?("clone'")
30
- copy_name = :clone
31
- break
32
- end
33
-
34
- if name.end_with?("dup'")
35
- copy_name = :dup
36
- break
37
- end
38
- end
36
+ def self.extended(mod)
37
+ super
39
38
 
40
- return copy_name
39
+ mod.include(Copyable)
41
40
  end
42
41
 
43
- ###
44
- # @author Jonathan Bradley Whited
45
- # @since 0.1.0
46
- ###
47
- class Copier
48
- attr_accessor :default_name
49
- attr_accessor :name
50
-
51
- def initialize(default_name=DEFAULT_COPY_NAME)
52
- super()
53
-
54
- @default_name = default_name
55
-
56
- update_name
57
- end
58
-
59
- def copy(var)
60
- return var.__send__(@name)
61
- end
42
+ def self.prepended(mod)
43
+ super
62
44
 
63
- def safe_copy(var)
64
- return var.respond_to?(@name) ? var.__send__(@name) : var
65
- end
66
-
67
- def update_name
68
- @name = InitCopy.find_copy_name(@default_name)
69
- end
45
+ # User specifically requested to prepend.
46
+ mod.prepend(Copyable)
70
47
  end
71
48
 
72
- Copyer = Copier # Alias
73
-
74
- ###
75
- # The instance variable name is long and obnoxious to reduce conflicts.
76
- #
77
- # @author Jonathan Bradley Whited
78
- # @since 0.1.0
79
- ###
80
49
  module Copyable
81
- # @since 0.1.1
82
- def initialize(*)
50
+ def initialize_clone(orig)
83
51
  super
84
- @init_copy_method_name = DEFAULT_COPY_NAME
85
- end
86
52
 
87
- def initialize_clone(*)
88
- @init_copy_method_name = :clone
89
- super
53
+ # The instance variable name is long & obnoxious to reduce conflicts.
54
+ @__init_copy_method_name = :clone
55
+ init_copy(orig)
90
56
  end
91
57
 
92
- def initialize_dup(*)
93
- @init_copy_method_name = :dup
58
+ def initialize_dup(orig)
94
59
  super
95
- end
96
60
 
97
- def clone(*)
98
- @init_copy_method_name = :clone
99
- super
100
- end
101
-
102
- def dup(*)
103
- @init_copy_method_name = :dup
104
- super
61
+ @__init_copy_method_name = :dup
62
+ init_copy(orig)
105
63
  end
106
64
 
107
- private
65
+ protected
108
66
 
109
- def copy(var)
110
- return var.__send__(@init_copy_method_name)
67
+ def init_copy(_orig)
111
68
  end
112
69
 
113
- def safe_copy(var)
114
- @init_copy_method_name = DEFAULT_COPY_NAME if @init_copy_method_name.nil?
70
+ def ic_copy(var)
71
+ return var.__send__(@__init_copy_method_name)
72
+ end
115
73
 
116
- return var.respond_to?(@init_copy_method_name) ?
117
- var.__send__(@init_copy_method_name) : var
74
+ def ic_copy?(var)
75
+ return var.__send__(@__init_copy_method_name) if var.respond_to?(@__init_copy_method_name)
76
+ return var
118
77
  end
119
78
  end
120
-
121
- Copiable = Copyable # Alias
122
79
  end
@@ -0,0 +1,242 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ #--
5
+ # This file is part of InitCopy.
6
+ # Copyright (c) 2020 Bradley Whited
7
+ #
8
+ # SPDX-License-Identifier: MIT
9
+ #++
10
+
11
+ require 'minitest/autorun'
12
+
13
+ require 'init_copy'
14
+
15
+ class InitCopyTest < Minitest::Test
16
+ # def setup
17
+ # end
18
+
19
+ def test_include
20
+ %i[include extend prepend].each do |method|
21
+ sut_class = Class.new
22
+ sut_class.__send__(method,InitCopy)
23
+
24
+ assert_includes(sut_class.included_modules,InitCopy::Copyable,
25
+ "`#{method}` of InitCopy should include InitCopy::Copyable")
26
+ end
27
+ end
28
+
29
+ def test_no_copy
30
+ sut = TestBag.new
31
+
32
+ refute_deep_copy(sut,sut.clone,:clone)
33
+ refute_deep_copy(sut,sut.dup,:dup)
34
+ end
35
+
36
+ def test_clone
37
+ sut = TestBagWithCopy.new
38
+
39
+ assert_deep_copy(sut,sut.clone,:clone)
40
+ end
41
+
42
+ def test_dup
43
+ sut = TestBagWithCopy.new
44
+
45
+ assert_deep_copy(sut,sut.dup,:dup)
46
+ end
47
+
48
+ def test_correct_clone_and_dup_behavior
49
+ sut_ext = Module.new do
50
+ def bonus
51
+ return 100
52
+ end
53
+ end
54
+
55
+ sut = TestBagWithCopy.new
56
+ sut.extend(sut_ext)
57
+
58
+ assert_deep_copy(sut,sut.clone,:clone)
59
+ assert_deep_copy(sut,sut.dup,:dup)
60
+
61
+ sut.nums.freeze
62
+ sut_clone = sut.clone
63
+ sut_dup = sut.dup
64
+
65
+ assert_predicate(sut.nums,:frozen?,'SUT nums should be frozen')
66
+ assert_respond_to(sut,:bonus,'SUT should have the bonus extension')
67
+ assert_equal(100,sut.bonus)
68
+
69
+ assert_predicate(sut_clone.nums,:frozen?,'clone should keep the nums as frozen')
70
+ assert_respond_to(sut_clone,:bonus,'clone should keep the bonus extension')
71
+ assert_equal(100,sut_clone.bonus)
72
+
73
+ refute_predicate(sut_dup.nums,:frozen?,'dup should remove the internal frozen state of nums')
74
+ refute_respond_to(sut_dup,:bonus,'dup should remove the bonus extension')
75
+ assert_raises(NoMethodError) { sut_dup.bonus }
76
+ end
77
+
78
+ def test_safe_copy
79
+ sut = TestBagWithSafeCopy.new
80
+
81
+ assert_respond_to(sut.nums,:clone)
82
+ assert_respond_to(sut.nums,:dup)
83
+
84
+ assert_deep_copy(sut,sut.clone,:clone)
85
+ assert_deep_copy(sut,sut.dup,:dup)
86
+
87
+ class << sut.nums
88
+ undef_method :clone
89
+ undef_method :dup
90
+ end
91
+
92
+ refute_respond_to(sut.nums,:clone)
93
+ refute_respond_to(sut.nums,:dup)
94
+
95
+ refute_deep_copy(sut,sut.clone,:clone,is_safe_copy: true)
96
+ refute_deep_copy(sut,sut.dup,:dup,is_safe_copy: true)
97
+
98
+ # Make sure we didn't remove clone()/dup() for all arrays.
99
+ assert_respond_to([1,2,3],:clone)
100
+ assert_respond_to([1,2,3],:dup)
101
+ end
102
+
103
+ def test_child_copy
104
+ sut_class = Class.new(TestBagWithCopy) do
105
+ attr_reader :strs
106
+
107
+ def initialize
108
+ super
109
+
110
+ @strs = %w[a b c]
111
+ end
112
+
113
+ def init_copy(*)
114
+ super
115
+
116
+ @strs = ic_copy(@strs)
117
+ end
118
+ end
119
+
120
+ sut = sut_class.new
121
+ sut_clone = sut.clone
122
+ sut_dup = sut.dup
123
+
124
+ assert_deep_copy(sut,sut_clone,:clone)
125
+ assert_deep_copy(sut,sut_dup,:dup)
126
+
127
+ expected = %w[a b c]
128
+
129
+ refute_same(sut.strs,sut_clone.strs)
130
+ refute_same(sut.strs,sut_dup.strs)
131
+ assert_equal(expected,sut.strs)
132
+ assert_equal(expected,sut_clone.strs)
133
+ assert_equal(expected,sut_dup.strs)
134
+
135
+ sut.strs << 'd'
136
+ sut_clone.strs << 'e'
137
+ sut_dup.strs << 'f'
138
+
139
+ assert_equal(%w[a b c d],sut.strs)
140
+ assert_equal(%w[a b c e],sut_clone.strs)
141
+ assert_equal(%w[a b c f],sut_dup.strs)
142
+ end
143
+
144
+ def assert_deep_copy(sut,sut_copy,copy_method_name)
145
+ refute_same(sut,sut_copy)
146
+
147
+ assert_nil(sut.init_copy_method_name)
148
+ assert_equal(copy_method_name,sut_copy.init_copy_method_name)
149
+
150
+ assert_nil(sut.orig)
151
+ assert_same(sut,sut_copy.orig)
152
+
153
+ expected = [1,2,3]
154
+
155
+ refute_same(sut.nums,sut_copy.nums)
156
+ assert_equal(expected,sut.nums)
157
+ assert_equal(expected,sut_copy.nums)
158
+
159
+ sut.nums << 4
160
+ sut_copy.nums << 5
161
+
162
+ assert_equal([1,2,3,4],sut.nums)
163
+ assert_equal([1,2,3,5],sut_copy.nums)
164
+
165
+ # Reset.
166
+ sut.nums.pop
167
+ sut_copy.nums.pop
168
+ end
169
+
170
+ def refute_deep_copy(sut,sut_copy,copy_method_name,is_safe_copy: false)
171
+ refute_same(sut,sut_copy)
172
+
173
+ assert_nil(sut.init_copy_method_name)
174
+ assert_equal(copy_method_name,sut_copy.init_copy_method_name)
175
+
176
+ assert_nil(sut.orig)
177
+
178
+ if is_safe_copy
179
+ assert_same(sut,sut_copy.orig)
180
+ else
181
+ assert_nil(sut_copy.orig)
182
+ end
183
+
184
+ expected = [1,2,3]
185
+
186
+ assert_same(sut.nums,sut_copy.nums)
187
+ assert_equal(expected,sut.nums)
188
+ assert_equal(expected,sut_copy.nums)
189
+
190
+ sut.nums << 4
191
+ sut_copy.nums << 5
192
+
193
+ expected = [1,2,3,4,5]
194
+
195
+ assert_equal(expected,sut.nums)
196
+ assert_equal(expected,sut_copy.nums)
197
+
198
+ # Reset.
199
+ sut.nums.pop(2)
200
+ end
201
+ end
202
+
203
+ class TestBag
204
+ include InitCopy
205
+
206
+ attr_reader :orig
207
+ attr_reader :nums
208
+
209
+ def initialize
210
+ super
211
+
212
+ @__init_copy_method_name = nil
213
+ @orig = nil
214
+ @nums = [1,2,3]
215
+ end
216
+
217
+ def init_copy_method_name
218
+ return @__init_copy_method_name
219
+ end
220
+ end
221
+
222
+ class TestBagWithCopy < TestBag
223
+ protected
224
+
225
+ def init_copy(orig)
226
+ super
227
+
228
+ @orig = orig
229
+ @nums = ic_copy(@nums)
230
+ end
231
+ end
232
+
233
+ class TestBagWithSafeCopy < TestBag
234
+ protected
235
+
236
+ def init_copy(orig)
237
+ super
238
+
239
+ @orig = orig
240
+ @nums = ic_copy?(@nums)
241
+ end
242
+ end
metadata CHANGED
@@ -1,108 +1,66 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: init_copy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
- - Jonathan Bradley Whited
8
- autorequire:
7
+ - Bradley Whited
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-18 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: bundler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '2.2'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '2.2'
27
- - !ruby/object:Gem::Dependency
28
- name: minitest
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '5.14'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '5.14'
41
- - !ruby/object:Gem::Dependency
42
- name: rake
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '13.0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '13.0'
55
- - !ruby/object:Gem::Dependency
56
- name: yard
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '0.9'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '0.9'
69
- description: Easily use the appropriate clone/dup method in initialize_copy.
11
+ date: 2025-06-06 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Easily use the correct clone or dup method in initialize_copy.
70
14
  email:
71
15
  - code@esotericpig.com
72
16
  executables: []
73
17
  extensions: []
74
- extra_rdoc_files: []
18
+ extra_rdoc_files:
19
+ - LICENSE.txt
20
+ - README.md
75
21
  files:
22
+ - ".rdoc_options"
76
23
  - Gemfile
77
24
  - LICENSE.txt
25
+ - README.md
78
26
  - Rakefile
79
27
  - init_copy.gemspec
80
28
  - lib/init_copy.rb
29
+ - test/init_copy_test.rb
81
30
  homepage: https://github.com/esotericpig/init_copy
82
31
  licenses:
83
32
  - MIT
84
33
  metadata:
85
- bug_tracker_uri: https://github.com/esotericpig/init_copy/issues
86
- changelog_uri: https://github.com/esotericpig/init_copy/blob/master/CHANGELOG.md
34
+ rubygems_mfa_required: 'true'
87
35
  homepage_uri: https://github.com/esotericpig/init_copy
88
36
  source_code_uri: https://github.com/esotericpig/init_copy
89
- post_install_message:
90
- rdoc_options: []
37
+ bug_tracker_uri: https://github.com/esotericpig/init_copy/issues
38
+ changelog_uri: https://github.com/esotericpig/init_copy/blob/main/CHANGELOG.md
39
+ post_install_message:
40
+ rdoc_options:
41
+ - "--embed-mixins"
42
+ - "--hyperlink-all"
43
+ - "--line-numbers"
44
+ - "--show-hash"
45
+ - "--main"
46
+ - README.md
47
+ - "--title"
48
+ - InitCopy v0.2.0
91
49
  require_paths:
92
50
  - lib
93
51
  required_ruby_version: !ruby/object:Gem::Requirement
94
52
  requirements:
95
53
  - - ">="
96
54
  - !ruby/object:Gem::Version
97
- version: '2.4'
55
+ version: '3.2'
98
56
  required_rubygems_version: !ruby/object:Gem::Requirement
99
57
  requirements:
100
58
  - - ">="
101
59
  - !ruby/object:Gem::Version
102
60
  version: '0'
103
61
  requirements: []
104
- rubygems_version: 3.2.15
105
- signing_key:
62
+ rubygems_version: 3.5.21
63
+ signing_key:
106
64
  specification_version: 4
107
- summary: Easily use the appropriate clone/dup method in initialize_copy.
65
+ summary: Easily use the correct clone or dup method in initialize_copy.
108
66
  test_files: []