Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better enum symbol casting documentation #706

Merged
merged 5 commits into from
Aug 29, 2023
Merged
Changes from 2 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
35 changes: 11 additions & 24 deletions docs/syntax_and_semantics/enum.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Enums

This page is for [Crystal enums](https://crystal-lang.org/api/Enum.html). For C enums, see [C bindings enum](c_bindings/enum.md).
nobodywasishere marked this conversation as resolved.
Show resolved Hide resolved

An enum is a set of integer values, where each value has an associated name. For example:

```crystal
Expand Down Expand Up @@ -117,37 +119,22 @@ Class variables are allowed, but instance variables are not.

## Usage

Enums are a type-safe alternative to [Symbol](https://crystal-lang.org/api/Symbol.html). For example, an API's method can specify a [type restriction](type_restrictions.md) using an enum type:
When a method parameter has an enum [type restriction](type_restrictions.md), it accepts either an enum constant or a Symbol. The Symbol will be automatically cast to an enum constant, raising a compile-time error if casting fails.
nobodywasishere marked this conversation as resolved.
Show resolved Hide resolved

```crystal
def paint(color : Color)
case color
when Color::Red
# ...
else
# Unusual, but still can happen
raise "unknown color: #{color}"
end
puts "Painting using the color #{color}"
end

paint Color::Red
```

The above could also be implemented with a Symbol:

```crystal
def paint(color : Symbol)
case color
when :red
# ...
else
raise "unknown color: #{color}"
end
end
paint :red # automatically casts to `Color::Red`

paint :red
# compile-time error:
# expected argument #1 to 'paint' to match a member of enum Color
#
# Options are: :red, :green and :blue
paint :yellow
nobodywasishere marked this conversation as resolved.
Show resolved Hide resolved
```

However, if the programmer makes a typo, say `:reed`, the error will only be caught at runtime, while attempting to use `Color::Reed` will result in a compile-time error.

The recommended thing to do is to use enums whenever possible, only use symbols for the internal implementation of an API, and avoid symbols for public APIs. But you are free to do what you want.
The same automatic casting does not apply to case statements. To use enums with case statements, see [case enum values](case.md#enum-values).
Loading