【Ruby】キーが文字列のHashを生成する

Ruby

こんにちは、しきゆらです。
今回は、RubyでHashを生成するときの挙動を整理しておきます。

ここ最近、サービスにデータを投入するためにCSVを生成する機会が多くあります。
その場合、CSVのヘッダーを投入するサービス側で定義されている場合がほとんどです。
大抵は、ヘッダーは日本語で指定されていることが多いです。
なので、投入するCSVを作成するためにHashを作っています。

この中で、Hashを生成するときの書き方により、キーをシンボル・文字列どちらにするかを書き分けることができます。
この時の挙動を誤解していたのでメモしておきます。

・・・CSVを直接操作するより、HashをCSVに変換したほうが便利なのでHashを作っていきます。

RubyのHash式

Hash式は、RubyでHashを生成する方法の1つです。
Hashリテラル、というと思っていたんですがドキュメントを見るとHash式というようです。

RubyでHashを生成するとき、キーとしてよく使うのはシンボルです。

シンボルは数値と同じような文字列、というイメージのオブジェクトです。
文字列だと、同じ文字列だったとしても内部的には別オブジェクトになりますが
シンボルの場合は、同じシンボルは同じオブジェクトを参照します。

Hashのキーとして利用する場合は文字列よりもシンボルのほうがメモリにやさしいと思います。
とはいえ、HashをCSVに変更する場合、キーを文字列にしておいた方が便利なのでi以下のように書いてみました。

value = {
  "キー1": 1,
  "キー2": 2,
} 
#=> {:キー1=>1, :キー2=>2}

上記の通りキーと値の間をコロンでつなぐと、キーはシンボルになります。
この挙動を勘違いしていました。

キーをシンボルにする場合

value = {
  キー1: 1,
  キー2: 2,
} 
#=> {:キー1=>1, :キー2=>2}

上記のように書いた場合のみキーがシンボルになると思っていましたが、
間をコロンでつなげばキー部分をクォーテーションで囲っても囲まなくてもシンボルとなります。

キーを文字列にする場合

キーを文字列にしたい場合は以下のように=>でつなぐ必要があります。

value = {
  "キー1" => 1,
  "キー2" => 2,
} 
#=> {"キー1"=>1, "キー2"=>2}

ということで、Hashを作るときの記法によりキーを文字列にしたい場合にはお気をつけください。

なお、シンボルだろうが文字列だろうがHash#transform_keysでまとめて変換ができるのでこっちを使ってもよいと思います。

まとめ

今回は、RubyでHashを生成するときのキーの記述による挙動の違いをメモしました。
Hashはよく使うものでしたが、普段と違う動機で使うと思わぬ挙動に躓く、ということでした。

今回は、ここまで。

おわり

Posted by しきゆら