From cd5cea4e8d162dffd4227624464b376dcd7b6660 Mon Sep 17 00:00:00 2001 From: Nazar Matus Date: Sun, 21 Jun 2026 02:00:15 +0300 Subject: [PATCH 1/4] Class reloading (#56) * Fix DuplicateKeyError when the whole class is reloaded * Add test for redundant module inclusion in a subclass * rubocop: disable RSpec/DescribedClass rule + nits * Add test for subclass lazy reloading * Update CHANGELOG.md --- .rubocop.yml | 5 +++- CHANGELOG.md | 1 + lib/ruby-enum/enum.rb | 3 +++ spec/ruby-enum/enum_spec.rb | 54 +++++++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/.rubocop.yml b/.rubocop.yml index a71c181..558e59a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -11,7 +11,7 @@ Metrics/BlockLength: RSpec/SpecFilePathFormat: Enabled: false -Style/LineLength: +Layout/LineLength: Enabled: false Style/HashEachMethods: @@ -38,6 +38,9 @@ RSpec/NestedGroups: RSpec/ExampleLength: Enabled: false +RSpec/DescribedClass: + Enabled: false + RSpec/MultipleExpectations: Enabled: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a3190e..9d2c4fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### 1.1.0 (Next) +* [#56](https://github.com/dblock/ruby-enum/pull/56): Fix `DuplicateKeyError` when the enum class is reloaded - [@flvrone](https://github.com/flvrone). * [#54](https://github.com/dblock/ruby-enum/pull/54): Add support for Ruby 4.0 - [@dblock](https://github.com/dblock). * [#53](https://github.com/dblock/ruby-enum/pull/53): Replace code climate with coveralls - [@dblock](https://github.com/dblock). * Your contribution here. diff --git a/lib/ruby-enum/enum.rb b/lib/ruby-enum/enum.rb index 0930e86..6693b66 100644 --- a/lib/ruby-enum/enum.rb +++ b/lib/ruby-enum/enum.rb @@ -19,6 +19,9 @@ def self.included(base) base.extend ClassMethods base.private_class_method(:new) + + base.instance_variable_set(:@_enum_hash, {}) + base.instance_variable_set(:@_enums_by_value, {}) end module ClassMethods diff --git a/spec/ruby-enum/enum_spec.rb b/spec/ruby-enum/enum_spec.rb index a3d811e..0003700 100644 --- a/spec/ruby-enum/enum_spec.rb +++ b/spec/ruby-enum/enum_spec.rb @@ -17,6 +17,13 @@ class FirstSubclass < Colors class SecondSubclass < FirstSubclass define :PINK, 'pink' end + + class OtherSecondSubclass < FirstSubclass + include Ruby::Enum + + define :MAGENTA, 'magenta' + end + it 'returns an enum value' do expect(Colors::RED).to eq 'red' expect(Colors::GREEN).to eq 'green' @@ -169,6 +176,12 @@ class SecondSubclass < FirstSubclass expect(SecondSubclass.values).to eq(%w[red green orange pink]) end end + + context 'when a subclass of a subclass is defined with redundant module inclusion' do + it 'returns all values' do + expect(OtherSecondSubclass.values).to eq(%w[red green orange magenta]) + end + end end describe '#to_h' do @@ -229,6 +242,47 @@ class SecondSubclass < FirstSubclass end end + describe 'Reloading enum definition' do + it 'can be lazy reloaded' do + class_body = proc do + include Ruby::Enum + + define :BUZZ_CUT, 'buzz_cut' + end + + hair_styles = Class.new(&class_body) + + expect { hair_styles.class_eval(&class_body) }.not_to raise_error + end + + context 'when a subclass is defined' do + it 'NEEDS to include Ruby::Enum explicitly to be lazy reloaded' do + hair_styles = Class.new do + include Ruby::Enum + + define :BUZZ_CUT, 'buzz_cut' + end + + broken_subclass_body = proc do + define :PONYTAIL, 'ponytail' + end + broken_subclass = Class.new(hair_styles, &broken_subclass_body) + expect { broken_subclass.class_eval(&broken_subclass_body) } + .to raise_error Ruby::Enum::Errors::DuplicateKeyError, /PONYTAIL/ + + subclass_body = proc do + include Ruby::Enum + + define :PONYTAIL, 'ponytail' + end + more_hair_styles = Class.new(hair_styles, &subclass_body) + + expect { more_hair_styles.class_eval(&subclass_body) }.not_to raise_error + expect(more_hair_styles.values).to eq(%w[buzz_cut ponytail]) + end + end + end + describe 'Given a class that has not defined any enums' do class EmptyEnums include Ruby::Enum From 90bb8a17bdf83783da4f9aa905bd5c78f6824e34 Mon Sep 17 00:00:00 2001 From: "Daniel (dB.) Doubrovkine" Date: Sat, 20 Jun 2026 19:02:58 -0400 Subject: [PATCH 2/4] Preparing for release, 1.1.0. --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d2c4fd..edbab5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,8 @@ -### 1.1.0 (Next) +### 1.1.0 (2026/6/20) * [#56](https://github.com/dblock/ruby-enum/pull/56): Fix `DuplicateKeyError` when the enum class is reloaded - [@flvrone](https://github.com/flvrone). * [#54](https://github.com/dblock/ruby-enum/pull/54): Add support for Ruby 4.0 - [@dblock](https://github.com/dblock). * [#53](https://github.com/dblock/ruby-enum/pull/53): Replace code climate with coveralls - [@dblock](https://github.com/dblock). -* Your contribution here. ### 1.0.0 (2023/01/10) From ec3a353d0f604701000e74f384632acbfaac1bc9 Mon Sep 17 00:00:00 2001 From: "Daniel (dB.) Doubrovkine" Date: Sat, 20 Jun 2026 19:04:21 -0400 Subject: [PATCH 3/4] Preparing for next development iteration, 1.2.0. --- CHANGELOG.md | 4 ++++ lib/ruby-enum/version.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index edbab5f..dce9d55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +### 1.2.0 (Next) + +* Your contribution here. + ### 1.1.0 (2026/6/20) * [#56](https://github.com/dblock/ruby-enum/pull/56): Fix `DuplicateKeyError` when the enum class is reloaded - [@flvrone](https://github.com/flvrone). diff --git a/lib/ruby-enum/version.rb b/lib/ruby-enum/version.rb index ce01fd3..3003715 100644 --- a/lib/ruby-enum/version.rb +++ b/lib/ruby-enum/version.rb @@ -2,6 +2,6 @@ module Ruby module Enum - VERSION = '1.1.0' + VERSION = '1.2.0' end end From 91bfc0e35a63a853285875965195118f5cdb3c4a Mon Sep 17 00:00:00 2001 From: "Daniel (dB.) Doubrovkine" Date: Sat, 20 Jun 2026 19:04:43 -0400 Subject: [PATCH 4/4] Update RELEASING.md: GitHub Actions, MFA/OTP instructions. --- RELEASING.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/RELEASING.md b/RELEASING.md index 756915c..9e37e9b 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -11,7 +11,7 @@ bundle install rake ``` -Check that the last build succeeded in [Travis CI](https://travis-ci.org/dblock/ruby-enum) for all supported platforms. +Check that the last build succeeded in [GitHub Actions](https://github.com/dblock/ruby-enum/actions) for all supported platforms. Add a date to this release in [CHANGELOG.md](CHANGELOG.md). @@ -28,15 +28,24 @@ git add README.md CHANGELOG.md lib/ruby-enum/version.rb git commit -m "Preparing for release, 0.2.2." ``` -Release. +Release. If you have MFA enabled on RubyGems (you should), `rake release` will build the gem, tag it, and push commits/tags to GitHub, but fail at the RubyGems push. Push the gem manually with your OTP. ``` $ rake release -ruby-enum 0.2.2 built to pkg/ruby-enum-0.2.2.gem. -Tagged v0.2.2. +ruby-enum 1.1.0 built to pkg/ruby-enum-1.1.0.gem. +Tagged v1.1.0. Pushed git commits and tags. -Pushed ruby-enum 0.2.2 to rubygems.org. +... +You have enabled multi-factor authentication. Please enter OTP code. +``` + +Then push to RubyGems manually: + +``` +$ gem push pkg/ruby-enum-1.1.0.gem --otp +Pushing gem to https://rubygems.org... +Successfully registered gem: ruby-enum (1.1.0) ``` ### Prepare for the Next Version