私は Ruby の深い部分を数か月しか学んでいないので、これが少しばかげた質問だったら申し訳ありません。ネストされた配列を含む可能性のある配列を再帰的に反復しようとしているため、現在の要素の型を確認する必要があります。小さなテストとして次のコードがあります。
arr = [ 1..2, [3..4, [5..6]], [7..8, [9..10]] ]
arr.each do |node|
p node.class
p node.instance_of? Array
end
実行すると、次の出力が得られます。
Range
false
Array
false
Array
false
Range と 2 つのネストされた Array を含む Array があるので、最後の 2 つは True を返すと予想していました。
さらに奇妙なのは、次のように書く場合です。
node.class.name == "Array"
当然のことながら、True を返します。
ここで何が起こっているのですか?
Ruby バージョン: MRI 1.9.3-p194
注:最終的に、コードの衝突を回避するためにモジュールを使用してコードに名前を付ける方法が原因で、これが発生していることに気付きました。
module MyProg
class MyClass
attr_reader :my_array
def initialize(size)
@my_array = Array.new(size)
end
end
end
MyProg::MyClass.new
これを行うと、コードが分離されますが、名前空間の下から始まるすべてのクラス ルックアップが解決されるという欠点があります。これは、上記の例でmy_array.class
は、実際MyProg::Array
にはグローバル Array クラスの代わりに解決されることを意味します。
このような名前空間を使用していて、それでもこのメソッドを使用したい場合は、クラスの前にダブルコロンのグローバル識別子を使用して、Ruby にグローバル名前空間からのルックアップを強制的に開始させることで、問題を解決できます。
arr.is_a? ::Array
arr.is_a? ::String
ただし、Ruby の Duck Typing 機能を考えると (そして、後でコードをより適切に保守するために)、以下の Peter の提案に従って、実際にオブジェクトの動作をテストする必要があります。そのため、学習者に与えられたいくつかの優れたヘルプに対して、彼の答えを正しいものとしてマークしています!