alassek / activerecord-pg_enum

Integrate PostgreSQL's enumerated types with the Rails enum feature
MIT License
168 stars 10 forks source link

Ensure we don't modify `Gem::Version` internals when installing #17

Closed agrobbin closed 3 years ago

agrobbin commented 3 years ago

Gem::Version#canonical_segments memoizes the array, which is different than segments, which returns a dup.

Since we are manipulating the array to do this calculation, we should not modify canonical_segments itself.

I ran into this since Gem::Version objects are essentially value objects, cached across the system based on the string:

Gem::Version.new('6.0.3.4') === Gem::Version.new('6.0.3.4')
# => true

Because of that, when doing my own inspection of Rails.gem_version.canonical_segments after activerecord-pg_enum had been installed, the canonical_segments array had been modified.

Consider this scenario:

Rails.gem_version
# => #<Gem::Version "6.0.3.4">
Rails.gem_version.canonical_segments
# => [6, 0, 3, 4]
Rails.gem_version > Gem::Version.new('6.0')
# => true
# activerecord-pg_enum is installed
Rails.gem_version.canonical_segments
# => [6, 0]
Rails.gem_version > Gem::Version.new('6.0')
# => false
agrobbin commented 3 years ago

@alassek I've also issued a PR to RubyGems itself (rubygems/rubygems#4247) to prevent this from happening in the future.

alassek commented 3 years ago

Woah! Good catch. I definitely did not intend this.