0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Ruby】Range#include?とRange#cover?について調べたら、CRubyのコードに辿り着いた

Last updated at Posted at 2023-04-25

Range#include? と Range#cover?の違いと内部のC言語に関して

前提

本記事の内容は'MRI'いわゆる'CRuby'を対象としています。
また、Rubyのバージョンは3.2です。

概要

Range#include? と Range#cover? は以下のように、どちらも引数が指定した範囲に含まれるかどうかを判定する時に使われています。

(1.1..2.3).include?(1.1)    # => true
(1.1..2.3).cover?(1.1)      # => true

しかし、その違いがよく分からなかったため、本記事ではその違いについて説明します。
本記事では、公式ドキュメントへの理解を深め、最終的にはCRubyのコードについても考察していきたいと思います。

結論

公式ドキュメントでは書かれていなかったことで、自分で調べたことを補足していきます。

Range#include?

公式ドキュメント

Range#include? (Ruby 3.2 リファレンスマニュアル)

obj が範囲内に含まれている時に true を返します。そうでない場合は、false を返します。
<=> メソッドによる演算により範囲内かどうかを判定するには Range#cover? を使用してください。
始端・終端・引数が数値であれば、 Range#cover? と同様の動きをします。

上記に対しての補足は、以下のとおりです。

2文字以上の文字範囲を比較する時、Range#include?はRange#eachを使用して、引数とRangeの各要素を==で比較することで、範囲内に要素が存在するかどうか判定します。
範囲の始点と終点が1文字の時で、引数が1文字なら始点および終点と引数を比較します。引数が1文字でないなら、問答無用でfalseになります。
また、始端・終端・引数が数値であれば、C言語では、cover?の処理の関数r_cover_pを呼び出しています。

ruby/range.c at v3_2_1 · ruby/ruby

Range#cover?

公式ドキュメント

Range#cover? (Ruby 3.2 リファレンスマニュアル)

obj が範囲内に含まれている時に true を返します。
Range#include? と異なり <=> メソッドによる演算により範囲内かどうかを判定します。 Range#include? は原則として離散値を扱い、 Range#cover? は連続値を扱います。(数値については、例外として Range#include? も連続的に扱います。)

上記に対しての補足は、以下のとおりです。

引数とRangeの始点および終点を<=>で比較して、範囲内にあるかを判定します。そのため、Range#include?よりも処理が早いです。

詳細

詳細は以下のZennのリンク先にあげています。

【Ruby】Range#include?とRange#cover?の違い

メソッドの違いが分からず、同じように困っている方に届きやすいように、Qiitaでも掲載しました。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?