Rubyでは連想配列のことをHash(ハッシュ)と呼びます。そしてHashはRubyのプログラムで便利に使える機能の1つです。では、なぜRubyでは連想配列のことをHashと呼ぶのでしょうか。
RubyのHashは、連想配列を実現するための仕組みであるハッシュテーブルが語源です。今回はなぜHashと呼ぶかと連想配列とはどのような仕組みなのかについて紹介します。
Hash(ハッシュ)とは何か
Rubyにおける連想配列はハッシュクラスで定義されており、そのデータをHash(ハッシュ)と呼びます。そしてHashとはハッシュテーブル(Hash Table)を基に作られて呼び方です。まずは連想配列となぜHashと呼ぶことになったかについて解説します。
RubyにおけるHashとは
Rubyのリファレンスマニュアルによると、RubyにおけるHashとはハッシュテーブルによる連想配列で、任意のオブジェクトにいるキーと、任意のオブジェクトによる値とを関連付けします。
なお、Rubyでは全ての変数がオブジェクトです。そのためRubyのプログラムに記述された文字列も1つのオブジェクトとして扱われます。そして、そのような文字列のオブジェクトを配列の添え字に使い、値となるオブジェクトを関連付けし、変数として使えるのがHashです。
RubyにおけるHashの例
hash = { "name" => "Ruby", "position" => "Study", "state" => "OK" } p hash["name"] # "Ruby"が表示される
Hashは連想配列
一般的にプログラミング言語では、配列は添え字に数字を使い、連想配列では数字の代わりに文字列を使います。そしてRubyで、この連想配列と同じ使い方が可能なオブジェクトがHashです。
なお配列は、データが順に並んでいるだけなので、添え字の数字に対応する位置のデータとして参照できます。しかし、連想配列では添え字の文字列とデータとを使います。
そして添え字とデータを素早く検索するのに使われるのがハッシュテーブルです。RubyではHashの検索にハッシュテーブルを使っており、他のプログラミング言語でも連想配列にハッシュテーブルを利用しています。
RubyでなぜHashと呼ぶのか
ほかのプログラミングで連想配列と呼ばれているのに、なぜ、Rubyではハッシュと呼ぶのでしょうか。それは、Rubyを開発したまつもとゆきひろ氏がRubyの開発で影響を受けたプログラミング言語Perlで連想配列のことをハッシュテーブル(Hash Table)と読んでいたことから、その前半のHashを使ったのだそうです。
なお、連想配列は英語では「Associative Array」と記述します。それをRubyでは「Hash」と読み替えている訳です。いかにもシンプルで読み易いプログラムが書けるRubyらしい呼び方ではないでしょうか。
ハッシュテーブルが使われる理由
先ほど紹介したように連想配列にハッシュテーブルが使われる理由は、キーの検索を短時間でできるからです。次からハッシュテーブルを利用するメリットについて解説します。
なぜキーそのもので検索できないのか
連想配列のキーに文字列を使うのであれば、その文字列を検索し、一致するキーとペアの値を参照すれば済むことです。そしてそのようなプログラムは、Rubyでも簡単に作れます。しかしそれではコンピュータのCPUで処理する場合、キーの文字列を構成する文字コードを使い、その全てが一致するものを探さなければなりません。
そして、連想配列の用途はコンピュータが普及しはじめた昔にもあり、当時のCPUは処理能力が遅く、キーとなる文字列そのもので一致するものを探していたのでは今よりもはるかに長い時間がかかりました。そのため高速に検索できる仕組みを必要となり、その仕組みとして採用された方法がハッシュテーブルです。
ハッシュテーブルの仕組み
ハッシュテーブルは、キーの文字列から重複のない数字に変換する特殊な計算式を用い、その数字を利用してキーを検索する方法です。そして、重複のない数字に変換する特殊な計算式として使われるのがHash関数であり、キーとそのキーからHash関数で計算した数字で作られたテーブルがハッシュテーブルです。
連想配列でキーを検索する場合、そのキーからHash関数で計算して数字を使い、ハッシュテーブルを検索してキーを探しだし、そのキーに対応する値を参照します。そしてこの方法ではHash関数で計算した数字で検索できることから、キーの文字列を使うよりもはるかに短時間で検索することが可能です。
Hash関数は暗号化にも使われる
RubyのHashで使われるHash関数は、同じ文字列から生成される数字は常に同じで、その数字から文字列を復元できないという特徴があるので、パスワードのチェックにも使われます。
なおこのようなHash関数で使われるアルゴリズムは1つではなく、暗号化のアルゴリズムとして有名なMD5やSHA1などが付かれます。そしてRubyでもDigestモジュールを使うことでそのようなHash関数を使用して暗号化が可能です。興味のある方は、Digestモジュールについても調べてみてください。
Hashオブジェクトの使い方
これまで紹介したようにRubyにおけるHashとは、他のプログラミング言語における連想配列で、ハッシュテーブルを利用してキーとなる文字列に対応した値を高速に参照できる機能です。
RubyのHashオブジェクトの使い方として注意してほしいポイントを解説します。
Hashを作る方法
RubyのHashを宣言するには、キーと値のペアを「=>」で繋ぎ、それらを{}で囲います。配列を宣言するには[]で囲いますが、Hashでは{}で囲うので注意してください。また、Hashのキーには、文字列の代わりにシンボルを使うことも可能です。さらにRubyが日本語に対応していれば、Hashのキーに日本語も使用できます。
Hashの定義例
hash1 = { "one" => "POTEPAN", "two" => "STYLE" } hash2 = { "名前" => "ポテパン", "所属" => "スタイル" } hash3 = { :name1 => "ポテパン", :name2 => "スタイル" }
また空のHashを宣言して、キーに対応する値を個別に設定することも可能です。
hash4 = {} hash4["名前"] = "ポテパン" hash4["所属"] = "スタイル" p hash4["名前"] + hash4["所属"]
Hashのデフォルト値
Hashを利用する場合、キーを使って検索し、それに一致する値を評価します。例えば、下記のように、Hashオブジェクトを宣言したら、そのオブジェクトの名称に続けて[]の中にキーを指定すれば、そのキーに関連した値を参照できます。
hash2 = { "名前" => "ポテパン", "所属" => "スタイル" } p hash2["名前"] # "ポテパン"が表示される p hash2["所属"] # "スタイル"が表示される
ただし、定義されていないキーを指定した場合、デフォルトの値としてnilが参照されます。
hash2 = { "名前" => "ポテパン", "所属" => "スタイル" } p hash2["役職"] # nilが表示される
なおデフォルト値はHashオブジェクト毎にdefaultメソッドで指定できます。
hash2 = { "名前" => "ポテパン", "所属" => "スタイル" } hash2.default = "無し" p hash2["役職"] # "無し"が表示される
Hashの値をクリアするには
宣言済のHashのキーと値のペアを全て削除し、空の状態にすることも可能です。そしてその場合clearメソッドを使います。
hash4 = {} hash4["名前"] = "ポテパン" hash4["所属"] = "スタイル" p hash4 # {"名前"=>"ポテパン", "所属"=>"スタイル"}が表示される hash4.clear p hash4 # {}が表示される
繰り返し処理の中で同じHashを使う場合、前に使ったキーが上書きされないと誤動作することもあります。そのような場合はclearメソッドを使って空にしてから利用してください。
まとめ
プログラミングで表計算のようなデータを扱う場合、列を連想配列で作り、さらにそれを行数分の配列にすると繰り返し処理でデータを扱えます。そしてRubyにおける連想配列がHashです。Hashを活用する方法を身に付けてスキルアップを目指しましょう。
なお、これまで紹介したようにRubyのHashという呼び名は、連想配列を実現するためのハッシュテーブルから命名されました。そしてハッシュテーブルは暗号化処理でよく使われるHash関数を使った仕組みです。ぜひHash関数の使い方も調べてみてください。