こんにちは!エンジニアのタナカゴダイです。
Rubyで配列の内容をバイナリ(パック)に変換するにはpackメソッドを使用します。
「配列の内容をバイナリに変換して文字列として取得したい」
「packメソッドとunpackメソッドの使い方をそれぞれ知りたい」
この記事では、そんな方に向けてpackとunpackメソッドについて、以下の内容で解説していきます。
・packメソッドとは何か?
・packメソッドの使い方
・unpackメソッドとは何か?
・unpackメソッドの使い方
packメソッドとunpackメソッドの使い方についてわかりやすく解説していますのでぜひ参考にしてください!
packとは
packメソッドとは、rubyのArrayクラスが持つインスタンスメソッドであり、引数で指定したテンプレート文字列にしたがって、配列の内容をバイナリに変換(パック)した文字列で返すメソッドです。
この説明では少し難解なので、ワンフレーズごとに細かく噛み砕いて解説していきます。
> rubyのArrayクラスが持つインスタンスメソッドであり、
「Arrayクラスのインスタンスメソッド」というのは配列に続けてpackメソッドを使えるということです。
[配列].pack()
packメソッドは、上記のようなコードで書くことができます。
> 引数で指定したテンプレート文字列にしたがって
packメソッドは、引数にテンプレートを文字列で指定することで、そのテンプレートに沿った形式で戻り値を返します。
テンプレート文字列とは、型を指定する文字列と長さを示す数字(省略時は1)で並べられた文字列のことを指します。
長さとして"*"を指定した場合は、「残りのデータ全て」を表します。
テンプレート文字列の例として、以下のような指定方法があります。
- "a":nul文字を詰めます
- "A4":長さ4つ分、スペースを詰めます
- "c*":残りのデータ全てを8bit符号付整数に変換(パック)します。
> 配列の内容をバイナリに変換(パック)した文字列で返すメソッド
バイナリとは、一般的にはテキストデータではないデータのことを言います。
- バイナリデータはコンピュータが解釈するデータ(人間が解釈するのは困難)
- テキストデータは人間が解釈可能なデータ
と理解しておくと良いでしょう。
つまり、packメソッドはコンピュータが解釈するデータに変換(パック)するメソッドなのです。
packメソッドの構文を、以下に示しておきます。
[配列].pack("テンプレート文字列")
"バイナリとして変換(パック)した文字列"
packの使い方
それでは、実際にサンプルプログラムを用いながら、packメソッドの使い方について解説していきます。
サンプルプログラム1
["abc"].pack("a") # ① ["abc"].pack("a4") # ② ["abc", "de"].pack("a2A3") # ③
サンプルプログラム1を実行した結果が以下になります。
"a" "abcx00" "abde "
サンプルプログラム1のそれぞれの行について解説します。
①は、テンプレート文字列に"a"(長さが省略された時は1と同等)が指定されているので、nul文字を詰めて返します。
配列の内容が1以上あるので、結果は長さ1の"a"になることがわかります。
②は、①と同様にテンプレート文字列に"a"が指定されており、長さは4まで指定されているので、長さ4までnul文字を詰めて返します。
配列の内容は3までなので、最後はnul文字(x00)を詰めて、"abcx00"が返ってきます。
③は、配列の要素が2つあり、それぞれに異なるテンプレート文字列を指定しています。
一つ目の要素"abc"では"a2"を適用し、2つ目の要素"de"に"A3"(長さ3までスペースを詰める)を適用した結果が返ってきます。
それぞれの結果は文字列として並べられて返ってくるので、"abde "となります。
もう一つ、以下のサンプルプログラム2についても考えてきましょう。
[82, 117, 98, 121].pack("c*")
このサンプルプログラム2を実行した結果が以下になります。
"Ruby"
前項の解説通りにサンプルプログラム2を読み解きます。
サンプルプログラム2は、配列[82, 117, 98, 121]をテンプレート文字列"c*"に合わせて変換(パック)し結果を返します。
テンプレート文字列"c*"は、残りのデータ全てを8bit符号付きの整数を表します。
そして文字コードがSJISの場合、配列[82, 117, 98, 121]の要素はそれぞれ["R", "u", "b", "y"]に当たるため、コンピュータが解釈して返す結果は"Ruby"となります。
このようにして、packメソッドは様々なテンプレート文字列に合わせて、コンピュータが解釈するデータに変換(パック)するメソッドなのです。
unpackとは
packメソッドに続いて、unpackメソッドについても解説いたします。
unpackメソッドの特徴としては以下になります。
- Stringクラスのインスタンスメソッドです
- テンプレート文字列にしたがってpackメソッドと反対の働きをします
- 戻り値は配列が返ります
unpackメソッドの書き方としては、文字列にメソッドを続けて、引数にテンプレート文字列を渡します。
unpackメソッドの構文を以下に示します。
“文字列".pack("テンプレート文字列")
"文字列をアンパックした要素を含む配列"
packメソッドと同様に引数にテンプレート文字列を渡しますが、異なる点としてunpackメソッドは文字列に繋げるメソッドであることに注意しましょう。
unpackの使い方
unpackメソッドもサンプルプログラムを用いて解説します。
サンプルプログラム3
"abc".unpack("a") # ④ "abc".unpack("a4") # ⑤ "abcde ".unpack("a3A3") # ⑥
サンプルプログラム3を実行した結果が以下になります。
["a"] ["abc"] ["abc", "de"]
それぞれの行について、以下に解説を記載します。
④は、テンプレート文字列に"a"(長さが省略された時は1と同等)が指定されているので、nul文字を削除して結果を返します。
文字列の長さが1以上あるので、結果は長さ1の["a"]になることがわかります。
⑤は、④と同様にテンプレート文字列に"a"が指定されており、長さは4まで指定されているので、長さ4までnul文字を削除して返します。
文字列の長さは3までなので、長さ3までの["abc"]が返ってきます。
⑥は、文字列の長さによって異なるテンプレート文字列を指定しています。
テンプレート文字列"a3"(nul文字を削除)を適用する文字列は長さ3までの"abc"となり、テンプレート文字列"A3"(スペースを削除)を適用する文字列は"de "になります。
それぞれの結果は配列の要素として返ってくるので、結果は["abc", "de"]となります。
このように、unpackメソッドは文字列に対して、指定したテンプレート文字列の書式に変換(アンパック)します。
まとめ
この記事では、packメソッドの使い方をサンプルプログラムを用いて解説しました。
packメソッドは、テンプレート文字列に合わせてバイナリデータ(コンピュータが理解するデータ)に変換(パック)するメソッドです。
また、packメソッドとは反対の働きをするunpackメソッドについても解説しているので、ぜひこの機会にpackメソッド/unpackメソッドをマスターしてください!