オブジェクトがRubyで反復可能かどうかを確認するにはどうすればよいですか?
つまり、次のように、オブジェクトが反復可能かどうかをきれいにチェックするメソッドが必要です。
def is_iterable(my_object)
..
end
メソッド内からクラスに明示的に名前を付ける以外に、どこから始めればよいのかよくわかりません。
編集: 私の目的のために、反復可能はあなたが.eachすることができる何かであるとしましょう。
オブジェクトがRubyで反復可能かどうかを確認するにはどうすればよいですか?
つまり、次のように、オブジェクトが反復可能かどうかをきれいにチェックするメソッドが必要です。
def is_iterable(my_object)
..
end
メソッド内からクラスに明示的に名前を付ける以外に、どこから始めればよいのかよくわかりません。
編集: 私の目的のために、反復可能はあなたが.eachすることができる何かであるとしましょう。
私の目的のために、反復可能はあなたができることだとしましょう
.each
。
このオブジェクトにこのメソッドがあるかどうかを尋ねることができます
def iterable?(object)
object.respond_to?(:each)
end
すでにいくつかの答えがありますが、 Object#is_a?/ Object#kind_of?の2つの方法があります。およびModule#===:
[].is_a? Enumerable #=> true
"".is_a? Enumerable #=> false
Enumerable === [] #=> true
Enumerable === "" #=> false
あなたのより大きな目標とあなたが結果で何をする必要があるかに応じて、これを行うためのいくつかの方法があります。
ダックタイピングを使用して、オブジェクトが#eachに応答するかどうかを確認したい場合は、そのようなメソッドがあるかどうかをオブジェクトに尋ねることができます。
my_object.respond_to? :each
オブジェクトがEnumerableクラスに混在しているかどうかを確認したい場合は、クラスが含まれているかどうかを確認できます。
my_object.class.include? Enumerable
すべての祖先とミックスインのリストが必要な場合は、#ancestorsメソッドが必要です。たとえば、my_objectがEnumerableクラスを継承しているかどうかを確認するには、次のコマンドを呼び出します。
my_object = []
my_object.class.ancestors
=> [Array, Enumerable, Object, PP::ObjectMixin, Kernel, BasicObject]
my_object.class.ancestors.include? Enumerable
=> true
反復可能でない場合でもRange
応答するため、範囲の要素が応答することを具体的に確認する必要がありますeach
succ
def iterable?(object)
return object.begin.respond_to? :succ if object.kind_of? Range
object.respond_to? :each
end
一般的に、each
メソッドが定義されているかどうか、またはEnumerable
モジュールがオブジェクトのクラスに含まれているかどうかを確認できます。
my_object.class.include? Enumerable
Minitest
ActiveRecord
コンポジションオブジェクトのスタイルテストケース:
def test_iterates_over_invoice_items
invoice = Invoice.new(items: [InvoiceItem.new(description: 'test')])
iteration_count = 0
invoice.each do |invoice_item|
assert_equal 'test', invoice_item.description
iteration_count += 1
end
assert_equal 1, iteration_count
end