Project

General

Profile

Feature #12350

Introduce Array#find! that raises an error if element not found

Added by ka8725 (Andrey Koleshko) over 3 years ago. Updated about 3 years ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:75365]

Description

It would be great to have some function (like Hash#fetch) for Array that raises an exception if element not found by passed block in find.

For example:

[].find! { |el| el == 1 }
=> ElementError: element not found

I just noticed that there are many cases when it's needed to raise an exception (because this is exceptional situation) if an element not found.

Currently I just define methods like this one:

def find_price!(size)
  found_price = prices.find { |p| p.key == size }
  fail "Price for #{size} not found" unless found_price
  found_price
end

History

Updated by ka8725 (Andrey Koleshko) over 3 years ago

  • Description updated (diff)

Updated by zverok (Victor Shepelev) over 3 years ago

I'm pretty unhappy that community/style guidelines are banning the straightforward and readable solution:

prices.find { |p| p.key == size } or fail "Price for #{size} not found"

Updated by ka8725 (Andrey Koleshko) over 3 years ago

Victor Shepelev wrote:

I'm pretty unhappy that community/style guidelines are banning the straightforward and readable solution:

prices.find { |p| p.key == size } or fail "Price for #{size} not found"

I'm not aware about the banning. Could you elaborate what is bad in your example? Basically I don't see anything bad in your code except a little bit verbose like in mine solution.

Updated by zverok (Victor Shepelev) over 3 years ago

Could you elaborate what is bad in your example? Basically I don't see anything bad in your code except a little bit verbose like in mine solution.

I don't know! The most popular and widely accepted Ruby Style Guide just bans them: https://github.com/bbatsov/ruby-style-guide#no-and-or-or

And when I've tried to rant about how and/or are useful, it all went sideways: https://www.reddit.com/r/ruby/comments/478a17/rant_on_good_ruby_idiom_andor_operators/

Updated by nobu (Nobuyoshi Nakada) over 3 years ago

Victor Shepelev wrote:

Could you elaborate what is bad in your example? Basically I don't see anything bad in your code except a little bit verbose like in mine solution.

I don't know! The most popular and widely accepted Ruby Style Guide just bans them: https://github.com/bbatsov/ruby-style-guide#no-and-or-or

I don't think it makes a sense, however, you can use || instead if you don't like or of course.

prices.find { |p| p.key == size } || raise "Price for #{size} not found"

And it feels better to me because of the error message.

Updated by cremno (cremno phobia) over 3 years ago

You can pass a callable object to Enumerable#find:

def find_price!(size)
  prices.find(->{ fail "Price for #{size} not found" }){ |p| p.key == size }
end

Updated by dsferreira (Daniel Ferreira) about 3 years ago

Documentation can be improved to use example of callable object don't you think?
I'm happy to create a PR with it.

Updated by matz (Yukihiro Matsumoto) about 3 years ago

I am not against adding a method that raises an exception, but find! is not a proper name for it.
Besides that, we can raise an exception for non-existing values by the current behavior.
So let us start improving documentation. Daniel, could you create an PR?

Matz.

Also available in: Atom PDF