Skip to content

Instantly share code, notes, and snippets.

@havenwood
Last active October 7, 2022 15:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save havenwood/015713e2e00c54280af16e11c2d09091 to your computer and use it in GitHub Desktop.
Save havenwood/015713e2e00c54280af16e11c2d09091 to your computer and use it in GitHub Desktop.
An example of a Rust-like `Option` enum in Ruby, see https://doc.rust-lang.org/rust-by-example/std/option.html
# frozen_string_literal: true
# An example of a Rust-like `Option` enum in Ruby
module Option
class NoneError < StandardError
def message = "called #unwrap on a `None' value"
end
Some = Data.define(:unwrap) do
def initialize(value) = super
end
None = Data.define do
def unwrap = raise NoneError
end
end
include Option
# An integer division that doesn't `raise ZeroDivisionError`
def checked_division(dividend, divisor)
if divisor.zero?
# Failure is represented as the `None` variant
None.new
else
# Result is wrapped in a `Some` variant
Some.new(dividend / divisor)
end
end
# This function handles a division that may not succeed
def try_division(dividend, divisor)
# `Option` values can be pattern matched, just like other enums
case checked_division(dividend, divisor)
in None
puts "#{dividend} / #{divisor} failed!"
in Some(quotient)
puts "#{dividend} / #{divisor} = #{quotient}"
end
end
try_division(4, 2)
#>> 4 / 2 = 2
try_division(1, 0)
#>> 1 / 0 failed!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment