Rubyでのオブジェクトのタイプの判別


365

私が探しているものの例としてpythonを使用します(Pythonがわからない場合は、疑似コードと考えることができます)。

>>> a = 1
>>> type(a)
<type 'int'>

私はルビーで私ができることを知っています:

1.9.3p194 :002 > 1.class
 => Fixnum 

しかし、これはオブジェクトのタイプを判別する適切な方法ですか?


5
@JörgWMittagまだAFAICRはPythonで `type`が行うことですが、私の記憶はあいまいです。isinstance 応答を必要とするか、確認します。しかし、単に「NOES !!!」と言うだけです。本当に役に立ちませんか?代わりに、教育的であることを検討してください。
デイブニュートン

4
@JörgWMittag私が同情している間、OPはRubyで模倣するコードを提供しました。NOが役に立たないと言ってOP を実際に教育しない限り、IMO。そして、たとえあなたがそうしたとしても、OPがコードを通して何を望んでいるかをOPが定義したので、それはおそらく情報提供のみであるでしょう。
デイブニュートン

5
@JörgWMittag-Rubyではすべてがオブジェクトであるため、Pythonのようにプリミティブ型(int、long、booleanなど)はありません。その結果、Ruby内のクラスは型定義です。これはRubyに限定されず、単語クラスとタイプは他のいくつかの言語では同義語であり、OOP理論ではより広義です。
ocodo 2014年

6
ここでは本当にRubyについて話しているので、型とクラスは同義であり、これについては議論がありません。すべての値はオブジェクトです。したがって、Rubyについて単に話す人にとって、クラスタイプです。-参照:ruby-lang.org/en/about
ocodo

2
@JörgWMittagそのエッセイはこれまで非常に有益であり、機会があれば残りを読みます。特に、クックは、Python、Ruby、および他の動的に型付けされた言語が「実際には反対ではない」と主張することが(私の教授の1人がしたように)正しくない理由をかなり明確に(そして私が持っているよりもはるかに多くの背景知識を)持っているようです-指向」(彼がおそらくそれを実現せずに意味したのは、それらがADT指向ではないということでした)。しかし、Rubyは静的に型付けされていないため、Cookが説明している意味でのADTはありません。そのため、その違いに基づく異議は役に立ちません。
カイルストランド14年

回答:


608

オブジェクトの「タイプ」を判別する適切な方法は、Rubyの世界では不安定な用語であり、を呼び出すことobject.classです。

クラスは他のクラスから継承できるため、オブジェクトが「特定のタイプ」であるかどうかobject.is_a?(ClassName)を確認したい場合objectは、がタイプであるClassNameか、それから派生したものであるかを確認するために呼び出すことができます。

通常、型のチェックはRubyでは行われませんが、オブジェクトは特定のメソッドに応答する能力に基づいて評価されます。これは、一般的に「ダックタイピング」と呼ばれます。つまり、必要なメソッドに応答する場合は、型にこだわる必要はありません。

たとえばobject.is_a?(String)、別のクラスが文字列に変換するメソッドを実装したり、文字列の動作と同じように動作させたりする可能性があるため、厳格すぎます。object.respond_to?(:to_s)問題のオブジェクトがあなたが望むことをすることをテストするより良い方法でしょう。


13
-1。#classではない、それはその返し、オブジェクトの型を返すクラスを。名前は死んだプレゼントであるべきです。クラスとタイプは、OOの完全に異なる2つの概念です。
イェルクWミッターク

78
@JörgW Mittag:そう思いません。「クラス」と「プロセッサー速度」(例を示すと)は2つのまったく異なる概念ですが、「クラス」と「タイプ」は密接に関連した概念です。たとえば、クラスに関するWikipediaの記事の内容次のとおりです。「オブジェクト指向プログラミングでは、クラスは特殊なタイプを定義するために使用される構造です。」tadmanは質問者に役に立ちました。
Teemu Leisti 2013

18
@JörgWMittagRubyではtypeof、C、JavaScriptなどから最も近いものはclassです。Rubyには、他の言語のような正式なプロトコルシステムはありません。Objective-Cは、それに最も近いSmalltalkです。「タイプ」を「特定の一連のメソッドに応答して許容可能な結果を​​返すオブジェクト」として定義している場合、それを表明する方法は実際にはありません。緩すぎます。Rubyでオブジェクトのタイプを参照する場合、ほとんどの場合、クラスについて話していることがわかります。そのため、引用符で用語の種類を使用しました。
tadman 2013

14
@JörgW Mittag:「クラス」と「タイプ」は確かにOOの完全に異なる概念ではないことを断言します。(また、Javaで変数をどのように宣言しますか?変数のタイプまたはクラスのいずれかを指定し、その後にその名前を続けます: " "または " "。)tadmanは、両方の質問者を満足させるように質問に回答しましたRubyが使用する用語を明確にしながら、一般の読者。オブジェクト指向の専門用語の細かい点について、学問の細分化に興味があるわけではないので、最後に一言お願いします。int iInteger j
Teemu Leisti 2013

11
@TeemuLeistiここでの問題のほとんどは、Rubyのすべてがオブジェクトであり、したがってクラスを持っているという事実から生じます。一方、他のほとんどすべての言語では、オブジェクトではなくクラスを持たないプリミティブ型があり、それを行うオブジェクトとは対照的です。純粋なタイプなどがなく、正式にタイプを定義する方法がない場合、Rubyの世界では特に意味が曖昧になります。マッツは、自分以外のここでの特定の思想学校に厳密に固執していません。
tadman 2013


44

Rubyではしばしば、実際にはオブジェクトのクラスが何であるかを気にせず、特定のメソッドに応答することだけを気にします。これはダックタイピングと呼ばれ、あらゆる種類のRubyコードベースで確認できます。

したがって、多くの(ほとんどではないにしても)ケースでは、以下を使用してダックタイピングを使用するのが最善#respond_to?(method)です。

object.respond_to?(:to_i)

1
有効なポイント。質問には答えませんが、質問の精神にぶつかります。
user566245

@ user566245それはresponds_to?(:the_question)ですが、あなたが言ったように、質問には答えず、関連情報を提供します。かなり確実な答えが質問に答える必要があります。
R.リンコン

17

「はい」と言います。"マッツ"が彼の講演の1つでこのようなことを言っていたように、 "Rubyオブジェクトには型がありません。" すべてではなく、彼が私たちに伝えようとしている部分です。では、なぜ誰もが「すべてがオブジェクトである」と言ったのでしょうか。さらに、「データにはオブジェクトではなくタイプがある」と述べた。

だからこれを楽しむかもしれません。

https://www.youtube.com/watch?v=1l3U1X3z0CE

しかし、Rubyはクラスだけではオブジェクトのタイプをあまり気にしません。型ではなくクラスを使用します。すべてのデータにはクラスがあります。

12345.class

'my string'.class

彼らには祖先もいる

Object.ancestors

それらにはメタクラスもありますが、その詳細を保存します。

クラスがわかったら、クラスに使用できるメソッドを検索できます。ここで「データ型」が必要になります。詳細を調べたい場合は、ルックアップ...

「Rubyオブジェクトモデル」

Rubyがオブジェクトを処理する方法に使用される用語です。これはすべて内部にあるため、実際にはあまり表示されませんが、知っておくと便利です。しかし、それは別のトピックです。

はい!クラスはデータ型です。オブジェクトにはクラスがあり、データにはタイプがあります。したがって、データベースについて知っていれば、有限の型のセットしかないことがわかります。

テキストブロック番号


たとえば、Object.ancestors # => [Object, Kernel, BasicObject]
ドリアン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.