1. ホーム
  2. ruby

[解決済み] イコール、エクル、==、==の違いは何ですか?

2022-03-17 22:35:56

質問

この4つのメソッドの違いを理解しようとしています。私は、デフォルトで == はメソッドを呼び出します。 equal? これは、両方のオペランドがまったく同じオブジェクトを参照しているときに真を返します。

=== もデフォルトで呼び出されます。 == を呼び出すと equal? ...なるほど、この3つのメソッドがすべてオーバーライドされていないのなら === , ==equal? は、まったく同じことをするのですか?

次に eql? . これは(デフォルトで)何をするのでしょうか?オペランドのハッシュ/IDを呼び出すのでしょうか?

なぜRubyにはたくさんの等号があるのですか?セマンティクスが違うのでしょうか?

どうすれば解決するの?

大きく引用する オブジェクトのドキュメント というのも、ここには素晴らしい説明があるからです。また、これらのメソッドが他のクラスでオーバーライドされている場合は、次のようなドキュメントを読むことをお勧めします。 文字列 .

余談ですが、これらを自分でいろいろなオブジェクトで試したい場合は、次のようなものを使ってください。

class Object
  def all_equals(o)
    ops = [:==, :===, :eql?, :equal?]
    Hash[ops.map(&:to_s).zip(ops.map {|s| send(s, o) })]
  end
end

"a".all_equals "a" # => {"=="=>true, "==="=>true, "eql?"=>true, "equal?"=>false}


== - ジェネリック "イコール"。

<ブロッククオート

オブジェクトレベルで == は、以下の場合にのみ真を返します。 objother が同じオブジェクトであることを示します。一般に、このメソッドはクラス固有の意味を持たせるために子孫クラスでオーバーライドされます。

これは最も一般的な比較であり、したがって、あなた(クラスの作成者)が2つのオブジェクトが "等しい" かどうかを決定する最も基本的な場所となります。

=== - ケースイコール

Objectクラスの場合、実質的には #== しかし、通常、caseステートメントで意味のあるセマンティクスを提供するために子孫によってオーバーライドされます。

これ、すごい便利なんですよ。面白いものの例 === を実装しています。

  • 範囲
  • Regex
  • Proc (Ruby 1.9 に収録)

というようなことができるわけです。

case some_object
when /a regex/
  # The regex matches
when 2..4
  # some_object is in the range 2..4
when lambda {|x| some_crazy_custom_predicate }
  # the lambda returned true
end

参照 回答はこちら を使用した例です。 case + Regex は、コードをよりきれいにすることができます。そしてもちろん、自分で === 実装を使用すると、カスタム case のセマンティクスを提供します。

eql? - Hash イコール

eql? メソッドは、以下の場合に真を返します。 objother は同じハッシュキーを参照します。これは Hash を使用して、メンバが等しいかどうかをテストします。 クラスのオブジェクトの場合 Object , eql? とは同義です。 == . サブクラスは通常、この伝統を継承し、エイリアスとして eql? をオーバーライドした == メソッドを使用することができますが、例外もあります。 Numeric 型は、例えば == を超えることはできませんが eql? ということです。

1 == 1.0     #=> true
1.eql? 1.0   #=> false

だから、自分の用途に合わせて自由にオーバーライドしてもいいし、あるいは == を使用し alias :eql? :== ということで、2つのメソッドは同じように動作します。

equal? - 同一性比較

とは異なり == は、その equal? メソッドはサブクラスで決してオーバーライドしてはいけません。このメソッドはオブジェクトのアイデンティティを決定するために使われます(つまり。 a.equal?(b) もし a とは同じオブジェクトです。 b ).

これは事実上のポインタ比較です。