init_copy 0.1.2 → 0.3.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: f2ea381fdf2b5c0bec710f2b219f87e2f897e8bba17246591982617e02a5024c
4
+ data.tar.gz: c33f202bb2301400918c86fc49a8acf0a43be8f82f5e7e2df1dc6ca9935fc4c4
5
5
  SHA512:
6
- metadata.gz: e78215e491c98eb64d1e3d8b8920559151ce92ba2fe23e858832f82f90da7b40d71fc2b41ee2968c35ab88835c47ac9263fd1e6cc149ed6974a3787d7d985a5d
7
- data.tar.gz: f2cafe04cd905f0f31083e30343e73029cf5ae5fc8f1b5d28c141e1caeea4fb4575d3f77dde841da21d76f4aa667a767513e9bd93fe0f04a33b928ff53994c37
6
+ metadata.gz: 36b93091f59641bf0ea2fc2a7c520815f285e24aa5136d7e03c1e837811084f2b62e6040f82e98a1facd9e6b0930834558f7df7783cfe01a60a17b20d99152c9
7
+ data.tar.gz: fb2e3f6d74272af1061f73794814874bdb7d76f16c7998fdd9cfd41d1c5d17a7eda9985a0e0724be9fa16e1a55ba64f557ae431d93eff9a2637fc6bffab1312f
data/.rdoc_options ADDED
@@ -0,0 +1,29 @@
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
+ markup: markdown
15
+ show_hash: true
16
+ skip_tests: true
17
+
18
+ exclude:
19
+ - /.git/
20
+ - /.github/
21
+ - /.idea/
22
+ - /doc/
23
+ - /pkg/
24
+ - /spec/
25
+ - /stock/
26
+ - /test/
27
+ - Gemfile
28
+ - Gemfile.lock
29
+ - 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,171 @@
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
+ [![Source Code](https://img.shields.io/badge/source-github-%23211F1F.svg)](https://github.com/esotericpig/init_copy)
6
+ [![Changelog](https://img.shields.io/badge/changelog-md-%23A0522D.svg)](CHANGELOG.md)
7
+ [![License](https://img.shields.io/github/license/esotericpig/init_copy.svg)](LICENSE.txt)
8
+
9
+ 🧬 Easily use the correct `clone` or `dup` method in `initialize_copy`.
10
+
11
+ 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:
12
+
13
+ ```ruby
14
+ module SecretExt
15
+ def secret
16
+ 'password'
17
+ end
18
+ end
19
+
20
+ # Init vars.
21
+ bob = 'Bob'
22
+ bob.extend(SecretExt)
23
+ bob.freeze
24
+
25
+ clone = bob.clone
26
+ dup = bob.dup
27
+
28
+ # Check vars.
29
+ puts clone.frozen? #=> true
30
+ puts dup.frozen? #=> false
31
+
32
+ puts clone.secret #=> password
33
+ puts dup.secret #=> NoMethodError
34
+ ```
35
+
36
+ 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. 😞
37
+
38
+ 🚀 Instead, *InitCopy* was created:
39
+
40
+ 1. Install the gem `init_copy` ([on RubyGems.org](https://rubygems.org/gems/init_copy)).
41
+ 2. Include `InitCopy::Able` in your class/module.
42
+ 3. Override the `init_copy(original)` method.
43
+ 4. Use `ic_copy(var)`, instead of clone/dup.
44
+
45
+ Example usage:
46
+
47
+ ```ruby
48
+ require 'init_copy'
49
+
50
+ class JangoFett
51
+ include InitCopy::Able
52
+
53
+ attr_reader :gear,:bounties,:order66
54
+
55
+ def initialize
56
+ super
57
+
58
+ @gear = ['blaster','jetpack']
59
+ @bounties = ['Padmé','Vosa']
60
+
61
+ @order66 = Class.new do
62
+ undef_method :clone
63
+ undef_method :dup
64
+ end.new
65
+ end
66
+
67
+ protected
68
+
69
+ def init_copy(_orig)
70
+ super
71
+
72
+ @gear = ic_copy(@gear)
73
+ @bounties = ic_copy(@bounties)
74
+
75
+ @order66 = ic_copy?(@order66) # Safe copy if no dup/clone.
76
+ end
77
+ end
78
+
79
+ # Init vars.
80
+ jango = JangoFett.new
81
+ jango.bounties.freeze
82
+
83
+ boba1 = jango.clone
84
+ boba2 = jango.dup
85
+
86
+ jango.gear << 'vibroblade'
87
+ boba1.gear << 'implant'
88
+
89
+ # Check vars.
90
+ puts jango.gear.inspect #=> ["blaster", "jetpack", "vibroblade"]
91
+
92
+ puts boba1.gear.inspect #=> ["blaster", "jetpack", "implant"]
93
+ puts boba2.gear.inspect #=> ["blaster", "jetpack"]
94
+
95
+ puts boba1.bounties.inspect #=> ["Padmé", "Vosa"]
96
+ puts boba2.bounties.inspect #=> ["Padmé", "Vosa"]
97
+
98
+ puts boba1.bounties.frozen? #=> true (clone)
99
+ puts boba2.bounties.frozen? #=> false (dup)
100
+ ```
101
+
102
+ ## // Contents
103
+
104
+ - [Setup](#-setup)
105
+ - [Hacking](#-hacking)
106
+ - [License](#-license)
107
+
108
+ ## [//](#-contents) Setup
109
+
110
+ Pick your poison...
111
+
112
+ With the *RubyGems* CLI package manager:
113
+
114
+ ```bash
115
+ gem install init_copy
116
+ ```
117
+
118
+ In your *Gemspec*:
119
+
120
+ ```ruby
121
+ spec.add_dependency 'init_copy', '~> X.X'
122
+ ```
123
+
124
+ In your *Gemfile*:
125
+
126
+ ```ruby
127
+ # Pick your poison...
128
+ gem 'init_copy', '~> X.X'
129
+ gem 'init_copy', git: 'https://github.com/esotericpig/init_copy.git', branch: 'main'
130
+ ```
131
+
132
+ From source:
133
+
134
+ ```bash
135
+ git clone --depth 1 'https://github.com/esotericpig/init_copy.git'
136
+ cd init_copy
137
+ bundle install
138
+ bundle exec rake install:local
139
+ ```
140
+
141
+ ## [//](#-contents) Hacking
142
+
143
+ ```bash
144
+ git clone 'https://github.com/esotericpig/init_copy.git'
145
+ cd init_copy
146
+ bundle install
147
+ bundle exec rake -T
148
+ ```
149
+
150
+ Testing:
151
+
152
+ ```bash
153
+ bundle exec rake test
154
+ ```
155
+
156
+ Generating doc:
157
+
158
+ ```bash
159
+ bundle exec rake clobber_doc doc
160
+ ```
161
+
162
+ Installing:
163
+
164
+ ```bash
165
+ bundle exec rake install:local
166
+ ```
167
+
168
+ ## [//](#-contents) License
169
+
170
+ Copyright (c) 2020-2025 Bradley Whited
171
+ [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
- require 'init_copy'
6
+ require 'init_copy/version'
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,44 @@
1
1
  # encoding: UTF-8
2
2
  # frozen_string_literal: true
3
3
 
4
-
5
- require_relative 'lib/init_copy'
6
-
4
+ require_relative 'lib/init_copy/version'
7
5
 
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
- # Lowest version that isn't eol (end-of-life).
32
24
  # - 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
25
+ spec.required_ruby_version = '>= 3.1'
26
+ spec.require_paths = ['lib']
27
+ spec.bindir = 'bin'
28
+ spec.executables = []
29
+
30
+ spec.extra_rdoc_files = %w[LICENSE.txt README.md]
31
+ spec.rdoc_options = [
32
+ %w[--embed-mixins --hyperlink-all --line-numbers --show-hash],
33
+ '--main','README.md',
34
+ '--title',"InitCopy v#{InitCopy::VERSION}",
35
+ ].flatten
36
+
37
+ spec.files = [
38
+ Dir.glob("{#{spec.require_paths.join(',')}}/**/*.{erb,rb}"),
39
+ Dir.glob("#{spec.bindir}/*"),
40
+ Dir.glob('{spec,test}/**/*.{erb,rb}'),
41
+ %W[Gemfile #{spec.name}.gemspec Rakefile .rdoc_options],
42
+ spec.extra_rdoc_files,
43
+ ].flatten
39
44
  end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ #--
5
+ # This file is part of InitCopy.
6
+ # Copyright (c) 2025 Bradley Whited
7
+ #
8
+ # SPDX-License-Identifier: MIT
9
+ #++
10
+
11
+ module InitCopy
12
+ VERSION = '0.3.0'
13
+ end
data/lib/init_copy.rb CHANGED
@@ -3,120 +3,57 @@
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
+ require 'init_copy/version'
11
12
 
12
- ###
13
- # @author Jonathan Bradley Whited
14
- # @since 0.1.0
15
- ###
13
+ # Example usage:
14
+ # require 'init_copy'
15
+ #
16
+ # class JangoFett
17
+ # include InitCopy::Able
18
+ #
19
+ # protected
20
+ #
21
+ # def init_copy(_orig)
22
+ # super
23
+ #
24
+ # @gear = ic_copy(@gear)
25
+ # @order66 = ic_copy?(@order66) # Safe copy if no dup/clone.
26
+ # end
27
+ # end
16
28
  module InitCopy
17
- VERSION = '0.1.2'
18
-
19
- DEFAULT_COPY_NAME = :dup
20
-
21
- def self.new(default_name=DEFAULT_COPY_NAME)
22
- return Copier.new(default_name)
23
- end
24
-
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
39
-
40
- return copy_name
41
- end
42
-
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
62
-
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
70
- end
71
-
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
- module Copyable
81
- # @since 0.1.1
82
- def initialize(*)
29
+ module Able
30
+ def initialize_clone(orig)
83
31
  super
84
- @init_copy_method_name = DEFAULT_COPY_NAME
85
- end
86
32
 
87
- def initialize_clone(*)
88
- @init_copy_method_name = :clone
89
- super
33
+ # The instance var name is long & obnoxious to reduce conflicts.
34
+ @__init_copy_method_name = :clone
35
+ init_copy(orig)
90
36
  end
91
37
 
92
- def initialize_dup(*)
93
- @init_copy_method_name = :dup
38
+ def initialize_dup(orig)
94
39
  super
95
- end
96
40
 
97
- def clone(*)
98
- @init_copy_method_name = :clone
99
- super
41
+ @__init_copy_method_name = :dup
42
+ init_copy(orig)
100
43
  end
101
44
 
102
- def dup(*)
103
- @init_copy_method_name = :dup
104
- super
105
- end
106
-
107
- private
45
+ protected
108
46
 
109
- def copy(var)
110
- return var.__send__(@init_copy_method_name)
47
+ def init_copy(_orig)
111
48
  end
112
49
 
113
- def safe_copy(var)
114
- @init_copy_method_name = DEFAULT_COPY_NAME if @init_copy_method_name.nil?
50
+ def ic_copy(var)
51
+ return var.__send__(@__init_copy_method_name)
52
+ end
115
53
 
116
- return var.respond_to?(@init_copy_method_name) ?
117
- var.__send__(@init_copy_method_name) : var
54
+ def ic_copy?(var)
55
+ return var.__send__(@__init_copy_method_name) if var.respond_to?(@__init_copy_method_name)
56
+ return var
118
57
  end
119
58
  end
120
-
121
- Copiable = Copyable # Alias
122
59
  end
@@ -0,0 +1,237 @@
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
+ describe InitCopy do
16
+ it 'has a correct version' do
17
+ _(InitCopy::VERSION).must_match(/\d+\.\d+\.\d+(-[0-9A-Za-z\-.]+)?(\+[0-9A-Za-z\-.]+)?/)
18
+ end
19
+
20
+ def self.add_basic_copy_tests
21
+ it 'is not the same as the copies' do
22
+ _(@sut).wont_be_same_as(@sut_clone)
23
+ _(@sut).wont_be_same_as(@sut_dup)
24
+ end
25
+
26
+ it 'has the correct copy method name' do
27
+ _(@sut.init_copy_method_name).must_be_nil
28
+ _(@sut_clone.init_copy_method_name).must_equal(:clone)
29
+ _(@sut_dup.init_copy_method_name).must_equal(:dup)
30
+ end
31
+ end
32
+
33
+ def self.add_deep_copy_tests(is_frozen: false)
34
+ it 'has the correct original' do
35
+ _(@sut.orig).must_be_nil
36
+ _(@sut_clone.orig).must_be_same_as(@sut)
37
+ _(@sut_dup.orig).must_be_same_as(@sut)
38
+ end
39
+
40
+ it 'does a deep copy' do
41
+ _(@sut.nums).wont_be_same_as(@sut_clone.nums)
42
+ _(@sut.nums).wont_be_same_as(@sut_dup.nums)
43
+
44
+ expected = [1,2,3]
45
+
46
+ _(@sut.nums).must_equal(expected)
47
+ _(@sut_clone.nums).must_equal(expected)
48
+ _(@sut_dup.nums).must_equal(expected)
49
+
50
+ if !is_frozen
51
+ @sut.nums << 4
52
+ @sut_clone.nums << 5
53
+ @sut_dup.nums << 6
54
+
55
+ _(@sut.nums).must_equal([1,2,3,4])
56
+ _(@sut_clone.nums).must_equal([1,2,3,5])
57
+ _(@sut_dup.nums).must_equal([1,2,3,6])
58
+ end
59
+ end
60
+ end
61
+
62
+ describe 'without copy' do
63
+ before do
64
+ @sut = TestBag.new
65
+ @sut_clone = @sut.clone
66
+ @sut_dup = @sut.dup
67
+ end
68
+
69
+ add_basic_copy_tests
70
+
71
+ it 'has no original' do
72
+ _(@sut.orig).must_be_nil
73
+ _(@sut_clone.orig).must_be_nil
74
+ _(@sut_dup.orig).must_be_nil
75
+ end
76
+
77
+ it 'does not do a deep copy' do
78
+ _(@sut.nums).must_be_same_as(@sut_clone.nums)
79
+ _(@sut.nums).must_be_same_as(@sut_dup.nums)
80
+
81
+ expected = [1,2,3]
82
+
83
+ _(@sut.nums).must_equal(expected)
84
+ _(@sut_clone.nums).must_equal(expected)
85
+ _(@sut_dup.nums).must_equal(expected)
86
+
87
+ @sut.nums << 4
88
+ @sut_clone.nums << 5
89
+ @sut_dup.nums << 6
90
+
91
+ expected = [1,2,3,4,5,6]
92
+
93
+ _(@sut.nums).must_equal(expected)
94
+ _(@sut_clone.nums).must_equal(expected)
95
+ _(@sut_dup.nums).must_equal(expected)
96
+ end
97
+ end
98
+
99
+ describe 'with copy' do
100
+ before do
101
+ @sut = TestBagWithCopy.new
102
+ @sut_clone = @sut.clone
103
+ @sut_dup = @sut.dup
104
+ end
105
+
106
+ add_basic_copy_tests
107
+ add_deep_copy_tests
108
+ end
109
+
110
+ describe 'with copy and internal state' do
111
+ before do
112
+ @sut = TestBagWithCopy.new
113
+
114
+ @sut.nums.extend(
115
+ Module.new do
116
+ def bonus
117
+ return 110
118
+ end
119
+ end
120
+ )
121
+ @sut.nums.freeze
122
+
123
+ @sut_clone = @sut.clone
124
+ @sut_dup = @sut.dup
125
+ end
126
+
127
+ add_basic_copy_tests
128
+ add_deep_copy_tests(is_frozen: true)
129
+
130
+ it 'has the correct bonus extension' do
131
+ _(@sut.nums).must_respond_to(:bonus,'SUT should have the nums bonus extension')
132
+ _(@sut.nums.bonus).must_equal(110)
133
+
134
+ _(@sut_clone.nums).must_respond_to(:bonus,'clone should keep the nums bonus extension')
135
+ _(@sut_clone.nums.bonus).must_equal(110)
136
+
137
+ _(@sut_dup.nums).wont_respond_to(:bonus,'dup should remove the nums bonus extension')
138
+ _ { @sut_dup.bonus }.must_raise(NoMethodError)
139
+ end
140
+
141
+ it 'has the correct frozen state' do
142
+ _(@sut.nums.frozen?).must_equal(true,'SUT should have the nums as frozen')
143
+ _(@sut_clone.nums.frozen?).must_equal(true,'clone should keep the nums as frozen')
144
+ _(@sut_dup.nums.frozen?).must_equal(false,'dup should remove the nums as frozen')
145
+ end
146
+ end
147
+
148
+ describe 'child with copy and unsafe var' do
149
+ before do
150
+ @sut = TestBagChildWithCopyAndUnsafe.new
151
+ @sut_clone = @sut.clone
152
+ @sut_dup = @sut.dup
153
+ end
154
+
155
+ add_basic_copy_tests
156
+ add_deep_copy_tests
157
+
158
+ it 'does a deep copy of the strs' do
159
+ _(@sut.strs).wont_be_same_as(@sut_clone.strs)
160
+ _(@sut.strs).wont_be_same_as(@sut_dup.strs)
161
+
162
+ expected = %w[a b c]
163
+
164
+ _(@sut.strs).must_equal(expected)
165
+ _(@sut_clone.strs).must_equal(expected)
166
+ _(@sut_dup.strs).must_equal(expected)
167
+
168
+ @sut.strs << 'd'
169
+ @sut_clone.strs << 'e'
170
+ @sut_dup.strs << 'f'
171
+
172
+ _(@sut.strs).must_equal(%w[a b c d])
173
+ _(@sut_clone.strs).must_equal(%w[a b c e])
174
+ _(@sut_dup.strs).must_equal(%w[a b c f])
175
+ end
176
+
177
+ it 'does not do a deep copy of the unsafe var' do
178
+ _(@sut.unsafe).wont_respond_to(:clone)
179
+ _(@sut.unsafe).wont_respond_to(:dup)
180
+
181
+ _(@sut.unsafe).must_be_same_as(@sut_clone.unsafe)
182
+ _(@sut.unsafe).must_be_same_as(@sut_dup.unsafe)
183
+ end
184
+ end
185
+ end
186
+
187
+ class TestBag
188
+ include InitCopy::Able
189
+
190
+ attr_reader :orig
191
+ attr_reader :nums
192
+
193
+ def initialize
194
+ super
195
+
196
+ @__init_copy_method_name = nil
197
+ @orig = nil
198
+ @nums = [1,2,3]
199
+ end
200
+
201
+ def init_copy_method_name
202
+ return @__init_copy_method_name
203
+ end
204
+ end
205
+
206
+ class TestBagWithCopy < TestBag
207
+ protected
208
+
209
+ def init_copy(orig)
210
+ super
211
+
212
+ @orig = orig
213
+ @nums = ic_copy(@nums)
214
+ end
215
+ end
216
+
217
+ class TestBagChildWithCopyAndUnsafe < TestBagWithCopy
218
+ attr_reader :strs
219
+ attr_reader :unsafe
220
+
221
+ def initialize
222
+ super
223
+
224
+ @strs = %w[a b c]
225
+ @unsafe = Class.new do
226
+ undef_method :clone
227
+ undef_method :dup
228
+ end.new
229
+ end
230
+
231
+ def init_copy(*)
232
+ super
233
+
234
+ @strs = ic_copy(@strs)
235
+ @unsafe = ic_copy?(@unsafe)
236
+ end
237
+ end
metadata CHANGED
@@ -1,108 +1,67 @@
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.3.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-09 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
+ - lib/init_copy/version.rb
30
+ - test/init_copy_test.rb
81
31
  homepage: https://github.com/esotericpig/init_copy
82
32
  licenses:
83
33
  - MIT
84
34
  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
35
+ rubygems_mfa_required: 'true'
87
36
  homepage_uri: https://github.com/esotericpig/init_copy
88
37
  source_code_uri: https://github.com/esotericpig/init_copy
89
- post_install_message:
90
- rdoc_options: []
38
+ bug_tracker_uri: https://github.com/esotericpig/init_copy/issues
39
+ changelog_uri: https://github.com/esotericpig/init_copy/blob/main/CHANGELOG.md
40
+ post_install_message:
41
+ rdoc_options:
42
+ - "--embed-mixins"
43
+ - "--hyperlink-all"
44
+ - "--line-numbers"
45
+ - "--show-hash"
46
+ - "--main"
47
+ - README.md
48
+ - "--title"
49
+ - InitCopy v0.3.0
91
50
  require_paths:
92
51
  - lib
93
52
  required_ruby_version: !ruby/object:Gem::Requirement
94
53
  requirements:
95
54
  - - ">="
96
55
  - !ruby/object:Gem::Version
97
- version: '2.4'
56
+ version: '3.1'
98
57
  required_rubygems_version: !ruby/object:Gem::Requirement
99
58
  requirements:
100
59
  - - ">="
101
60
  - !ruby/object:Gem::Version
102
61
  version: '0'
103
62
  requirements: []
104
- rubygems_version: 3.2.15
105
- signing_key:
63
+ rubygems_version: 3.5.21
64
+ signing_key:
106
65
  specification_version: 4
107
- summary: Easily use the appropriate clone/dup method in initialize_copy.
66
+ summary: Easily use the correct clone or dup method in initialize_copy.
108
67
  test_files: []