Techioz Blog

入れ子になった配列の宣言は Ruby でどのように解釈されるのでしょうか?

概要

配列で作業しているときに、Ruby のネストされた配列の宣言でカンマを見逃しましたが、言語はこれを別の方法で解釈していました。この動作について詳しい人がいたら、考えてみてください。

arr = [1,2[1,8]]
[1, 1] 
arr = [1,5[6,4]]
[1, 0] 
arr = [1,3[1,6]]
[1, 1] 
arr = [1,6[1,6]]
[1, 3] 
arr = [1,7[1,6]]
[1, 3] 
arr = [1,0[1,6]]
[1, 0] 
arr = [1,8[1,6]]
[1, 4]

虚偽の申告に基づいて例外を発生させる必要があります

解決策

[1,8[1,6]] は、配列リテラルのコンテキストでは構文エラーのように見えるかもしれませんが、実際には完全に有効な Ruby 式です。 1 と 8[1,6] の結果である 4 の 2 つの要素を持つ配列を作成します。

8[1,6] は、整数 8 の一部を抽出します。これは、8 をビットのシーケンス (2 進数 00001000₂) として扱うことによって行われます。これらのビットから、ビット 1 から始まる 6 ビットが抽出されます: (ビット 0 が右端のビット)

0b00001000[1,6]  #=> 8
   ↓↓↓↓↓↓
 0b000100        #=> 4

詳細については、Integer#[] のドキュメントを参照してください。

これは、文字列の一部を文字のシーケンスとして処理して抽出する “hello Ruby”[1,6] に非常に似ています (文字 0 が左端の文字です)。

"hello ruby"[1,6]
  ↓↓↓↓↓↓
 "ello r"