0

Ruby は型の実行スタイルに===演算子を使用します。Ruby は、句にcase/when存在するものの型に応じて、それぞれのメソッドを呼び出すことも知られています。when.===

ステートメントwhenに名前が含まれているとしclassます。ルールは次のit will use Module#===, which will return true if the right side is an instance of, or subclass of, the left side.とおりです。このコンテキストの例は次のとおりです。

ここでinstance ofテストが発生します

obj = 'hello'
#=> "hello"
case obj
when String
print 'It is a string'
when Fixnum
print 'It is a number'
else
print 'It is not a string'
end
#It is a string
#=> nil

ここでsubclass ofテストが発生します

num = 10
#=> 10
case num
when Numeric
puts "Right class"
else
puts "Wrong class"
end
#Right class
#=> nil

リテラルwhenが含まStringれるようになり、次に String#=== が呼び出され、左右のリテラルが同じ (同じシーケンスで同じ文字) かどうかがチェックされます。

a = "abc"
#=> "abc"
case a
when "def" then p "Hi"
when "abc" then p "found"
else "not found"
end
#"found"
#=> "found"

オールロジックがかっこよすぎる。今私のクエリはcase/when構造です -

  • 、またはリテラル、または実行時に有効なものをwhen保持しているかどうかをRubyはどのように認識しますか?classString

また

  • 現在保持.=== しているモノに対してそれぞれのオペレーターを呼び出す前に、どのようなテストを実行しますか。when

編集

動作中のプリンシパルを理解する前にCase/when、次のことを明確にしておきましょうwhen

String.===("abc") #=> true

「abc」はStringクラスのインスタンスだからです。- そうですか?

今、誰が誰のスーパークラスであるかを確認するために、以下を試しました。

10.class #=> Fixnum
Fixnum.superclass #=> Integer
Integer.superclass #=> Numeric
Numeric.superclass #=> Object

うーん。trueこれは、 Fixnum が の間接サブクラスでもあるため、以下が返されることを意味しますNumeric。- そうですか?

Numeric.===(10) #=> true

しかし、なぜ以下の出力が上記と矛盾するのでしょうか?

Numeric.===(Fixnum) #=> false

以下のように私のクエリをより具体的にしようとしています:

と を呼び出しているNumeric.===(10)ときString.===("abc")。私たちは、ではなく"abc"10むしろ"abc".class、およびを送信していると思います10.class

10.===(10) #=> true
Numeric.===(10) #=> true

次に、上記を見てください。どちらも戻りtrueます。trueそれらは同じロジックで出力されますか? と思いますNO。比較10.===(10)のようなもの です。10 ==(10)しかし、 のクラスは のサブクラスとしてNumeric.===(10)出力されます。true10Numeric

"abc".===("abc") #=> true
String.===("abc") #=> true

次に、上記を見てください。どちらも戻りtrueます。trueそれらは同じロジックで出力されますか? と思いますNO"abc".===("abc")単純な文字列リテラル比較"abc" ==("abc")比較と同じです。しかし、のインスタンスであるとしてString.===("abc")出力します。true"abc"String

今私の質問は、ルビーが左側のオペランド型をどのように検出し、適切な比較規則を適用するかです。

100%間違っているかもしれませんが、その場合は訂正してください。

4

2 に答える 2

2

@Lee Jarvisも説明していることを説明しようと思います。

class Someclass
end

s = Someclass.new
p s.methods.sort
#[:!, :!=, :!~, :<=>, :==, :===, :=~, :__id__, :__send__, :class, :clone,(...)

5番目の方法を見てください。私の Someclass インスタンスには、===どこからともなくメソッドがあります。

実際には、56 個のメソッドがあり、そのうちの 1 つも定義していません。これらは Object から継承されます。Ruby のすべてのクラスは Object を継承しています。クラス Object (および私の Someclass) の場合、 #=== は #== の呼び出しと事実上同じですが、(ドキュメントにあるように) #=== は通常、case ステートメントで意味のあるセマンティクスを提供するために子孫によって上書きされます。

つまり、Ruby は賢いことは何もせず、問題のオブジェクトに===メッセージを送信する (または、必要に===応じてメソッドを呼び出す) だけです。

于 2013-03-03T21:33:30.707 に答える
1

今私の質問は、ルビーが左側のオペランド型をどのように検出し、適切な比較規則を適用するかです。

そうではありません。===メソッドを呼び出すだけです。それでおしまい。これがオブジェクト指向のしくみであり、Ruby に固有のものではありません。すべての OO 言語は同じように機能します。つまり、オブジェクトに対してメソッドを呼び出すと、オブジェクトがどのように反応するかを決定します。(または、Ruby、PHP、Java、C#、C++、Python などのクラスベースの言語では、オブジェクトのクラスが決定します。)

異なるオブジェクトは、異なる方法で反応する場合があります。クラスは引数がそれ自体のインスタンスであるかどうかをチェックし、正規表現は引数がそれらによって一致するかどうかをチェックし、範囲は引数がそれらによってカバーされているかどうかをチェックします。

基本的な発送方法のみです。

于 2013-03-04T01:59:44.650 に答える