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でも掲載しました。