1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Ruby] Rangeクラスの先頭をとる時はfirstじゃなくてbeginを使おう

Last updated at Posted at 2025-10-02

どうも、最近は勤怠プロダクトの開発に勤しんでいる @Joharu です。

ごく基礎的な内容になりますが、
業務でRubyの範囲型 (Range)を取り扱う際に躓いたので、記事にしてみます。

(自論に近いので、怪しい点などあれば是非コメント頂けると嬉しいです🙇‍♀️)

TL;DR

  • RubyのRangeから先頭要素を取得する時はfirstよりbeginがおすすめ
  • first..Date.todayみたいな無限範囲で RangeErrorになる
  • beginならnilが返ってきてもエラーにならない

環境

  • Ruby 3.0以降(無限範囲記法 .. が使用可能)

躓いたこと:firstだとエラーになることがあった

Rangeの先頭を取りたい時、firstを使っている箇所があったのですが、
実はこれが起因のエラーを踏むことがありました。

# 普通の範囲なら問題なし
(1..10).first  # => 1
(1..10).begin  # => 1

# でも無限範囲だと...
(..Date.today).first  # => RangeError - cannot get the first element of beginless range
(..Date.today).begin  # => nil(エラーにならない)

..Date.todayみたいな書き方、日付の範囲処理でよく使いますよね。
でもfirstだとRangeErrorになっちゃうんですね。

実際にありがちなケース

こんなコードを書いたことありませんか?

# 期間を指定して何かを処理する関数
def process_data_in_period(date_range)
  start_date = date_range.first  # ここでエラーになる可能性
  # ...
end

# 「今日まで」の範囲を渡すとエラー
process_data_in_period(..Date.today)  # RangeError!

これをbeginに変えるだけで安全になります:

def process_data_in_period(date_range)
  start_date = date_range.begin  # nilが返ってもエラーにならない
  return if start_date.nil?      # nilチェックも簡単
  # ...
end

process_data_in_period(..Date.today)  # 正常に動作

なぜbeginの方がいいのか

beginを使うメリットは単純です:

  • RangeErrorにならない: 無限範囲でもnilが返るだけ
  • nilチェックしやすい: nilかどうかで無限範囲を判定できる

以上!

まとめ

Range型から先頭を取る時はbeginを使うのがおすすめ、という話でした。

理由は簡単で、nilがあってもRangeErrorにならないから。
特に..Date.todayのように無限範囲になる可能性がある箇所は、beginを使っておけば安心ですね。


参考記事

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?