Code Fix

中級

シンボルキーのハッシュを文字列キーで参照すると nil になる

:name(シンボル)と"name"(文字列)は別のオブジェクトとして扱われるため、シンボルキーで作ったハッシュを文字列キーで参照すると見つからずnilが返ります。

なぜエラーが出ないのか

出力: nil
(エラーなし)
Rubyは何も報告しません。文法として正しいためです
出力: nil
実際の挙動 — 期待した結果と食い違っている箇所
見つけ方
エラーが出ないので、出力を目で確かめるしかありません。この種の誤りが最も発見が遅れます

このエラーが出る典型パターン

パターン1

 1  user = {name: "Taro"}
 2  puts user["name"].inspect
                 ^
出力: nil

:name(シンボル)と"name"(文字列)は別のオブジェクトです。シンボルキーのハッシュを文字列キーで探すと見つかりません。

直し方: "name":name にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  profile = {email: "taro@example.com"}
 2  puts profile["email"].inspect
                    ^
出力: nil

キーの見た目の文字が同じでも、シンボルと文字列はハッシュの中では別物として扱われます。

直し方: "email":email にします。

この問題を解いてみる →

パターン3

 1  config = {host: "localhost"}
 2  puts config["host"].inspect
                   ^
出力: nil

ハッシュリテラルで {host: ...} と書くと、キーは自動的にシンボル:hostになります。

直し方: "host":host にします。

この問題を解いてみる →

パターン4

 1  item = {sku: "A100"}
 2  puts item["sku"].inspect
                ^
出力: nil

キーの型を取り違えると、存在するはずの値がnilとして扱われ、後続の処理でバグにつながります。

直し方: "sku":sku にします。

この問題を解いてみる →

パターン5

 1  ticket = {seat: "12A"}
 2  puts ticket["seat"].inspect
                   ^
出力: nil

ハッシュを作った側の書き方(シンボルか文字列か)に合わせてアクセスする必要があります。

直し方: "seat":seat にします。

この問題を解いてみる →

よくある誤解

「キーの見た目の文字が同じなら、シンボルでも文字列でも同じキーとして扱われるはず」という思い込みは誤りです。ハッシュのキー照合はオブジェクトとしての等価性で行われるため、:nameと"name"は別のキーです。

まとめ

シンボルキーのハッシュを文字列キーで参照すると nil になるは中級でつまずきやすい項目です。上の5パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)