💡

Grow.rbのmy_find問題を解いてみる

に公開

Grow.rbとは:

Ruby力を高めたいRubyistたちが、コードを書いたりちょっとマニアックな内容を学んだりするコミュニティです。

オリジナルのfindメソッドを作ってみようというテーマです。

テストコードはこちら。

https://github.com/grow-rb/enumerable-exercises/blob/d08568e5319c9d24a74c9cb635ed1115ad43adc3/find/find_test.rb#L1-L22

書いた回答がこちら。

module Enumerable
  def my_find(error_message = nil, &block)
    return unless block_given?

    each do |element|
      return element if block.call(element)
    end

    error_message&.call || nil
  end
end

ChatGPT o1を使ってリファクタしてもらったのがこちら。コメントもo1が書いたものです。

module Enumerable
  def my_find(error_message = nil)
    # ブロックがなければ Enumerator を返すことで、
    # Ruby標準の find と似た挙動にし、柔軟性と一貫性を確保
    return to_enum(:my_find, error_message) unless block_given?

    # ブロック条件を満たす最初の要素を返す
    each do |element|
      return element if yield(element)
    end

    # 条件に合う要素が見つからなかった場合の処理
    # error_message が Proc ならば call する。なければ nil を返す
    error_message&.call
  end
end

私のコードでerror_message&.call || nilとしていたところを、|| nilを削除したのは納得できる修正。たしかに冗長だった。
ただ、やはりProcを受け取るメソッドなら引数に明示的に渡しておきたいんだけどなぁ🤔

Discussion