Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
### 1.2.0 (Next)
### 2.0.0 (Next)

* [#55](https://github.com/dblock/ruby-enum/issues/55): Renamed `Ruby::Enum` to `RubyEnum::Enum` since Ruby 4.0 reserves the top-level `Ruby` module - [@dblock](https://github.com/dblock).
* Your contribution here.

### 1.1.0 (2026/6/20)
Expand Down
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Ruby::Enum
RubyEnum::Enum
==========

[![Gem Version](http://img.shields.io/gem/v/ruby-enum.svg)](http://badge.fury.io/rb/ruby-enum)
Expand Down Expand Up @@ -41,7 +41,7 @@ Define enums, and reference them as constants.

``` ruby
class OrderState
include Ruby::Enum
include RubyEnum::Enum

define :CREATED, 'created'
define :PAID, 'paid'
Expand All @@ -51,7 +51,7 @@ end
``` ruby
OrderState::CREATED # 'created'
OrderState::PAID # 'paid'
OrderState::UNKNOWN # raises Ruby::Enum::Errors::UninitializedConstantError
OrderState::UNKNOWN # raises RubyEnum::Enum::Errors::UninitializedConstantError
OrderState.keys # [ :CREATED, :PAID ]
OrderState.values # [ 'created', 'paid' ]
OrderState.to_h # { :CREATED => 'created', :PAID => 'paid' }
Expand All @@ -63,7 +63,7 @@ Define enums, and reference them as class methods.

``` ruby
class OrderState
include Ruby::Enum
include RubyEnum::Enum

define :created, 'created'
define :paid, 'paid'
Expand All @@ -85,7 +85,7 @@ The value is optional. If unspecified, the value will default to the key.

``` ruby
class OrderState
include Ruby::Enum
include RubyEnum::Enum

define :UNSPECIFIED
define :unspecified
Expand Down Expand Up @@ -206,22 +206,22 @@ OrderState.key('failed')

### Duplicate enumerator keys or duplicate values

Defining duplicate enums raises `Ruby::Enum::Errors::DuplicateKeyError`.
Defining duplicate enums raises `RubyEnum::Enum::Errors::DuplicateKeyError`.

```ruby
class OrderState
include Ruby::Enum
include RubyEnum::Enum

define :CREATED, 'created'
define :CREATED, 'recreated' # raises DuplicateKeyError
end
```

Defining a duplicate value raises `Ruby::Enum::Errors::DuplicateValueError`.
Defining a duplicate value raises `RubyEnum::Enum::Errors::DuplicateValueError`.

```ruby
class OrderState
include Ruby::Enum
include RubyEnum::Enum

define :CREATED, 'created'
define :RECREATED, 'created' # raises DuplicateValueError
Expand All @@ -232,11 +232,11 @@ The `DuplicateValueError` exception is raised to be consistent with the unique k

### Inheritance

When inheriting from a `Ruby::Enum` class, all defined enums in the parent class will be accessible in sub classes as well. Sub classes can also provide extra enums, as usual.
When inheriting from a `RubyEnum::Enum` class, all defined enums in the parent class will be accessible in sub classes as well. Sub classes can also provide extra enums, as usual.

``` ruby
class OrderState
include Ruby::Enum
include RubyEnum::Enum

define :CREATED, 'CREATED'
define :PAID, 'PAID'
Expand Down Expand Up @@ -264,16 +264,16 @@ ShippedOrderState.values # ['CREATED', 'PAID', 'PREPARED', SHIPPED']

### Exhaustive case matcher

If you want to make sure that you cover all cases in a case stament, you can use the exhaustive case matcher: `Ruby::Enum::Case`. It will raise an error if a case/enum value is not handled, or if a value is specified that's not part of the enum. This is inspired by the [Rust Pattern Syntax](https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html). If multiple cases match, all matches are being executed. The return value is the value from the matched case, or an array of return values if multiple cases matched.
If you want to make sure that you cover all cases in a case stament, you can use the exhaustive case matcher: `RubyEnum::Enum::Case`. It will raise an error if a case/enum value is not handled, or if a value is specified that's not part of the enum. This is inspired by the [Rust Pattern Syntax](https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html). If multiple cases match, all matches are being executed. The return value is the value from the matched case, or an array of return values if multiple cases matched.

> NOTE: This will add checks at runtime which might lead to worse performance. See [benchmarks](#benchmarks).

> NOTE: `:else` is a reserved keyword if you want to use `Ruby::Enum::Case`.
> NOTE: `:else` is a reserved keyword if you want to use `RubyEnum::Enum::Case`.

```ruby
class Color < OrderState
include Ruby::Enum
include Ruby::Enum::Case
include RubyEnum::Enum
include RubyEnum::Enum::Case

define :RED, :red
define :GREEN, :green
Expand Down
38 changes: 34 additions & 4 deletions UPGRADING.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,40 @@
# Upgrading Ruby::Enum
# Upgrading RubyEnum::Enum

## Upgrading to >= 2.0.0

### Module renamed from `Ruby::Enum` to `RubyEnum::Enum`

Ruby 4.0 [reserves](https://bugs.ruby-lang.org/issues/20884) the top-level `Ruby` module for the language itself, so this gem's `Ruby::Enum` namespace is no longer safe to use. As of `2.0.0`, the gem uses `RubyEnum::Enum` instead.

`gem 'ruby-enum', '< 2.0.0'`

``` ruby
class Color
include Ruby::Enum

define :RED, 'red'
end
```

`gem 'ruby-enum', '>= 2.0.0'`

``` ruby
class Color
include RubyEnum::Enum

define :RED, 'red'
end
```

For backward compatibility, `Ruby::Enum` is still available as a deprecated alias for `RubyEnum::Enum` and will emit a deprecation warning when included. It will be removed in a future major version. Update your code to use `RubyEnum::Enum` and `RubyEnum::Enum::Case` directly.

See [#55](https://github.com/dblock/ruby-enum/issues/55) for more information.

## Upgrading to >= 0.9.0

### Inheritance & `Ruby::Enum.values`
### Inheritance & `RubyEnum::Enum.values`

This only applies to classes that inherit from another which is a `Ruby::Enum`.
This only applies to classes that inherit from another which is a `RubyEnum::Enum`.

Prior to version `0.9.0`, the `values` class method would enumerate only the
values defined in the class.
Expand All @@ -14,7 +44,7 @@ the entire class heirarchy, ancestors first.

``` ruby
class PrimaryColors
include Ruby::Enum
include RubyEnum::Enum

define :RED, 'RED'
define :GREEN, 'GREEN'
Expand Down
4 changes: 2 additions & 2 deletions benchmarks/case.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
##
# Test enum
class Color
include Ruby::Enum
include Ruby::Enum::Case
include RubyEnum::Enum
include RubyEnum::Enum::Case

define :RED, :red
define :GREEN, :green
Expand Down
2 changes: 1 addition & 1 deletion lib/config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ en:
resolution: "The enumerated value could not be found in class %{name}. Use 'define' to declare it.\n
\_Example:\n
\_\_module %{name}\n
\_\_\_include Ruby::Enum\n
\_\_\_include RubyEnum::Enum\n
\_\_\_define %{key}, 'value'\n
\_\_end"
duplicate_key:
Expand Down
7 changes: 4 additions & 3 deletions lib/ruby-enum.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,19 @@
# Try to load the I18n gem and provide a mock if it is not available.
begin
require 'i18n'
Ruby::Enum.i18n = I18n
RubyEnum::Enum.i18n = I18n
rescue LoadError
# I18n is not available
# :nocov:
# Tests for this loading are in the spec_i18n folder
Ruby::Enum.i18n = Ruby::Enum::I18nMock
RubyEnum::Enum.i18n = RubyEnum::Enum::I18nMock
# :nocov:
end

Ruby::Enum.i18n.load_path << File.join(File.dirname(__FILE__), 'config', 'locales', 'en.yml')
RubyEnum::Enum.i18n.load_path << File.join(File.dirname(__FILE__), 'config', 'locales', 'en.yml')

require 'ruby-enum/errors/base'
require 'ruby-enum/errors/uninitialized_constant_error'
require 'ruby-enum/errors/duplicate_key_error'
require 'ruby-enum/errors/duplicate_value_error'
require 'ruby-enum/deprecated'
28 changes: 28 additions & 0 deletions lib/ruby-enum/deprecated.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true

# Deprecated backward-compatible alias for RubyEnum::Enum.
#
# Ruby 4.0 reserves the top-level `Ruby` module for the language itself, so
# this namespace is deprecated and will be removed in a future major version.
# Use RubyEnum::Enum instead.
module Ruby
module Enum
def self.included(base)
warn '[DEPRECATION] `Ruby::Enum` is deprecated and will be removed in a future version. ' \
'Use `RubyEnum::Enum` instead.'

base.include RubyEnum::Enum
end

module Case
def self.included(base)
warn '[DEPRECATION] `Ruby::Enum::Case` is deprecated and will be removed in a future version. ' \
'Use `RubyEnum::Enum::Case` instead.'

base.include RubyEnum::Enum::Case
end
end

Errors = RubyEnum::Enum::Errors
end
end
10 changes: 5 additions & 5 deletions lib/ruby-enum/enum.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

module Ruby
module RubyEnum
module Enum
class << self
# Needed for I18n mock
Expand Down Expand Up @@ -53,7 +53,7 @@ def store_new_instance(key, value)
end

def const_missing(key)
raise Ruby::Enum::Errors::UninitializedConstantError, name: name, key: key
raise RubyEnum::Enum::Errors::UninitializedConstantError, name: name, key: key
end

# Iterate over all enumerated values.
Expand Down Expand Up @@ -128,7 +128,7 @@ def keys
def values
result = @_enum_hash.values.map(&:value)

if superclass < Ruby::Enum
if superclass < RubyEnum::Enum
superclass.values + result
else
result
Expand Down Expand Up @@ -164,13 +164,13 @@ def upper?(s)
def validate_key!(key)
return unless @_enum_hash.key?(key)

raise Ruby::Enum::Errors::DuplicateKeyError, name: name, key: key
raise RubyEnum::Enum::Errors::DuplicateKeyError, name: name, key: key
end

def validate_value!(value)
return unless @_enums_by_value.key?(value)

raise Ruby::Enum::Errors::DuplicateValueError, name: name, value: value
raise RubyEnum::Enum::Errors::DuplicateValueError, name: name, value: value
end
end
end
Expand Down
8 changes: 4 additions & 4 deletions lib/ruby-enum/enum/case.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# frozen_string_literal: true

module Ruby
module RubyEnum
module Enum
##
# Adds a method to an enum class that allows for exhaustive matching on a value.
#
# @example
# class Color
# include Ruby::Enum
# include Ruby::Enum::Case
# include RubyEnum::Enum
# include RubyEnum::Enum::Case
#
# define :RED, :red
# define :GREEN, :green
Expand All @@ -33,7 +33,7 @@ def self.included(klass)
end

##
# @see Ruby::Enum::Case
# @see RubyEnum::Enum::Case
module ClassMethods
class ValuesNotDefinedError < StandardError
end
Expand Down
2 changes: 1 addition & 1 deletion lib/ruby-enum/enum/i18n_mock.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

# :nocov:
module Ruby
module RubyEnum
module Enum
##
# Mock I18n module in case the i18n gem is not available.
Expand Down
4 changes: 2 additions & 2 deletions lib/ruby-enum/errors/base.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

module Ruby
module RubyEnum
module Enum
module Errors
class Base < StandardError
Expand Down Expand Up @@ -39,7 +39,7 @@ def compose_message(key, attributes = {})
#
# Returns a localized error message string.
def translate(key, options)
Ruby::Enum.i18n.translate("#{BASE_KEY}.#{key}", locale: :en, **options).strip
RubyEnum::Enum.i18n.translate("#{BASE_KEY}.#{key}", locale: :en, **options).strip
end

# Create the problem.
Expand Down
2 changes: 1 addition & 1 deletion lib/ruby-enum/errors/duplicate_key_error.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

module Ruby
module RubyEnum
module Enum
module Errors
# Error raised when a duplicate enum key is found
Expand Down
2 changes: 1 addition & 1 deletion lib/ruby-enum/errors/duplicate_value_error.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

module Ruby
module RubyEnum
module Enum
module Errors
# Error raised when a duplicate enum value is found
Expand Down
2 changes: 1 addition & 1 deletion lib/ruby-enum/errors/uninitialized_constant_error.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

module Ruby
module RubyEnum
module Enum
module Errors
class UninitializedConstantError < Base
Expand Down
4 changes: 2 additions & 2 deletions lib/ruby-enum/version.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

module Ruby
module RubyEnum
module Enum
VERSION = '1.2.0'
VERSION = '2.0.0'
end
end
2 changes: 1 addition & 1 deletion ruby-enum.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ require 'ruby-enum/version'

Gem::Specification.new do |s|
s.name = 'ruby-enum'
s.version = Ruby::Enum::VERSION
s.version = RubyEnum::Enum::VERSION
s.authors = ['Daniel Doubrovkine']
s.email = '[email protected]'
s.platform = Gem::Platform::RUBY
Expand Down
Loading
Loading