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

result and option #2

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open

result and option #2

wants to merge 6 commits into from

Conversation

nz
Copy link
Member

@nz nz commented Mar 4, 2025

Okay fine, let's do this. Add yard-doctest and go to town making a take on Result and Option that feels like Ruby.

The first take was a lot smaller and more opinionated. The kind of thing I could easily and uncontroversially drop into a Rails project. This next take is… unapologetic in bringing my Rust reflexes into Ruby. But may not be something I want to use in Rails.

More thought will be required about how I want to use this, but it sure was fun to write, especially after finding yard-doctest.

@nz nz force-pushed the result-and-option branch from 53555cf to b3fa9e7 Compare March 4, 2025 23:31
# Err("foo").match do
# ok { :foo }
# err { :bar }
# end # => :bar
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Love the doc tests
  2. I see Rust's match as requiring that all cases are handled (exhaustive pattern matching) and also to expose inner values.

Based on this example, it's unclear if it yields or gives the original value somehow. It's not quite and_then but that is what this reminds me of. Actually maybe it's closer to https://doc.rust-lang.org/std/result/enum.Result.html#method.map_or_else.

  1. Random unsolicited advice, this cheatsheet is really helpful https://upsuper.github.io/rust-cheatsheet/?dark,large

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I borrowed this from another random gem that had taken a stab at Rust style Results, and I don't love it. I'm going to work up a proper example with case and probably ditch this unless I can come up with a better reason to have it.

#
# @example
# Ok("foo").expect!("foo") # => "foo"
# Err("foo").expect!("foo") # => raise Errgonomic::ExpectError, "foo"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unclear from this example that the original "foo" or the later "foo" is raised. Picking different values would help.

Also, rust has a lint against using foo and bar in examples for variables. One way around this is with theming. Like planet names or characters from a show you like etc.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, good one. Now I want a linter for that in Ruby! (Yo @h3h!)

@@ -97,6 +150,10 @@ def expect!(msg)
end

# Return the inner value of an Err, else raise an exception when Ok.
#
# @example
# Ok("foo").unwrap_err! # => raise Errgonomic::UnwrapError, "value is an Ok"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From interface design perspective with errors: I think that beyond knowing the value was "ok" in this scenario they would also want to know what it held. I.e. if it's surprising that it's Ok, the contents might yield some clues.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. I haven't used this in Rust yet so was a bit on autopilot in the implementation. That makes a lot of sense.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% sure what methods hide the original error message in Rust, I think some do. In general though, I consider exceptions a time when I want maximum context as by definition: something I didn't expect is happening.

# Ok("foo").match do
# ok { :ok }
# err { :err }
# end # => :ok
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you support pattern matching? https://docs.ruby-lang.org/en/3.0/syntax/pattern_matching_rdoc.html Could you?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants