0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ハッシュとシンボル

Last updated at Posted at 2023-06-01

ハッシュとシンボル

ハッシュ

ハッシュは基本的には配列と同じですが、整数値以外のインデックス(要素の番号のこと)が使える点と、要素の並び順が保証されない点が配列と異なります。

>> user = {}                          # {}は空のハッシュ
=> {}
>> user["first_name"] = "Michael"     # キーが "first_name" で値が "Michael"
=> "Michael"
>> user["last_name"] = "Hartl"        # キーが "last_name" で値が "Hartl"
=> "Hartl"
>> user["first_name"]                 # 要素へのアクセスは配列の場合と似ている
=> "Michael"
>> user                               # ハッシュのリテラル表記
=> {"last_name"=>"Hartl", "first_name"=>"Michael"}

ハッシュは、キーと値のペアを波カッコで囲んで表記します。キーと値のペアを持たない波カッコの組({})は空のハッシュです。

ここで重要なのは、ハッシュの波カッコは、ブロックの波カッコとはまったく別物であるという点です(これは確かに紛らわしい点です)。ハッシュは配列と似ていますが、1つの重要な違いとして、ハッシュでは要素の「並び順」が保証されないという点があります 。要素の順序が重要である場合は、配列を使う必要があります。

ハッシュの1要素を角カッコを使って定義する代わりに、次のようにキーと値をハッシュロケットと呼ばれる=>によってリテラル表現するほうが簡単です。

>> user = { "first_name" => "Michael", "last_name" => "Hartl" }
=> {"last_name"=>"Hartl", "first_name"=>"Michael"}

シンボル

ここまではハッシュのキーとして文字列を使っていましたが、Railsでは文字列よりも シンボルを使う方が普通です。シンボルは文字列と似ていますが、クォートで囲む代わりにコロンが前に置かれている点が異なります。例えば:nameはシンボルです。もちろん、余計なことを一切考えずに、シンボルを単なる文字列とみなしても構いません。

ハッシュのキーとしてシンボルを採用する場合、user のハッシュは次のように定義できます。

>> user = { :name => "Michael Hartl", :email => "michael@example.com" }
=> {:name=>"Michael Hartl", :email=>"michael@example.com"}
>> user[:name]              # :name に対応する値にアクセスする
=> "Michael Hartl"
>> user[:password]          # 未定義のキーに対応する値にアクセスする
=> nil                      # 未定義のハッシュ値は単純にnil

シンボルとハッシュロケットの組み合わせを、次のようにキーの名前の「前」ではなく「後」にコロンを置き、その後に値が続くように置き換えられます(h2)。

>> h1 = { :name => "Michael Hartl", :email => "michael@example.com" }
=> {:name=>"Michael Hartl", :email=>"michael@example.com"}
>> h2 = { name: "Michael Hartl", email: "michael@example.com" }
=> {:name=>"Michael Hartl", :email=>"michael@example.com"}
>> h1 == h2
=> true

つまり、
{ :name => "Michael Hartl" }{ name: "Michael Hartl" }というコードは等価になります。

ネストされたハッシュ

ハッシュの値にはほぼ何でも使うことができ、他のハッシュを使うことすらできます。

>> params = {}        # 'params' というハッシュを定義する ('parameters' の略)。
=> {}
>> params[:user] = { name: "Michael Hartl", email: "mhartl@example.com" }
=> {:name=>"Michael Hartl", :email=>"mhartl@example.com"}
>> params
=> {:user=>{:name=>"Michael Hartl", :email=>"mhartl@example.com"}}
>>  params[:user][:email]
=> "mhartl@example.com"

Railsでは、このようなハッシュのハッシュ(またはネストされたハッシュ)が大量に使われています。

配列や範囲オブジェクトと同様、ハッシュもeachメソッドに応答します。例えば、:success:dangerという2つの状態を持つ flash という名前のハッシュについて考えてみましょう。

>> flash = { success: "It worked!", danger: "It failed." }
=> {:success=>"It worked!", :danger=>"It failed."}
>> flash.each do |key, value|
?>   puts "Key #{key.inspect} has value #{value.inspect}"
>> end
Key :success has value "It worked!"
Key :danger has value "It failed."

ここで、配列のeachメソッドでは、ブロックの変数は1つだけですが、ハッシュのeachメソッドでは、ブロックの変数は キーの2つになっていることに注意してください。したがって、 ハッシュに対してeachメソッドを実行すると、ハッシュ内にある「キーと値のペア」ごとに処理を繰り返します。

最後の例として、便利なinspectメソッドを紹介します。これは要求されたオブジェクトを表現する文字列を返します。

>> puts (1..5).to_a            # 配列を文字列として出力
1
2
3
4
5
>> puts (1..5).to_a.inspect    # 配列のリテラルを出力
[1, 2, 3, 4, 5]
>> puts :name, :name.inspect
name
:name
>> puts "It worked!", "It worked!".inspect
It worked!
"It worked!"

ところで、オブジェクトを表示するためにinspectを使うことは非常に多いので、 pメソッドというショートカットがあります。

>> p :name             # 'puts :name.inspect' と同じ
:name

省略

実は、Ruby では メソッド呼び出しの丸カッコは省略しても構いません
次の2つのコードは等価です。

> message1 = "Hello"
> message2 = "Thanx"
> message3 = "oraora!"
> message1.concat(message2, message3)
=> "Hello Thanx oraora!"
> message1 = "Hello"
> message2 = "Thanx"
> message3 = "oraora!"
> message1.concat message2, message3 #カッコを省略してメソッド呼び出しを書く
=> "Hello Thanx oraora!"

複雑なコード

次に、少し難しいコードを理解していきます。

 <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>

ここではRailsの組み込み関数stylesheet_link_tag(引数として指定されたソースのスタイルシート リンク タグを返す)を使ってます。しかし、ここで不思議な点がいくつもあります。第一に、丸カッコがありません。しかし、Rubyではメソッド呼び出しの丸カッコは省略しても構わないので次の2つの行は等価です。

# メソッド呼び出しの丸カッコは省略可能。
stylesheet_link_tag("application", "data-turbo-track": "reload")
# 上は以下のように書いても同じ
stylesheet_link_tag "application", "data-turbo-track": "reload"

したがって、次のコードはstylesheet_link_tagメソッドに引数を2個渡して呼んでいることになります。

次に不思議なのが、2つ目の引数はハッシュのようですが、波カッコがない点です。実は、ハッシュがメソッド呼び出しの 最後の引数である場合は、波カッコを省略できます。次の2つの行は等価です。

# 最後の引数がハッシュの場合、波カッコは省略可能。
stylesheet_link_tag("application", { "data-turbo-track": "reload" })
# 上は以下のように書いても同じ
stylesheet_link_tag("application", "data-turbo-track": "reload")

最初の引数(data-turbo-track)は、スタイルシートへのパスを指定する文字列です。上のコードは<%= ... %>で囲まれているので、結果はERBによってビューに挿入されます。

参考文献

Ruby on Rails Tutorial

Rails API

0
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?