開発備忘録 2018/10/19
Ruby の代入演算子 ||=
Ruby の実装でたまに見かけるこの記述について調べてみた。
user ||= fetch_user
上記の式は user
が未定義だと fetch_user
が呼び出されて user
に代入され、そうでないなら user
を返す。
何故こうなるのかが分からなかったが、どうやらこの式は以下のように展開されるらしい。
user || (user = fetch_user)
Ruby の場合 ||
は左辺が真なら右辺は評価しないという性質があるので、user
が定義済みなら user
を返し、そうでないなら fetch_user
が呼び出され代入される、という仕組みになっていたようだ。
RSpec のモック化
Twitter からユーザーのツイートを取得するクライアントが実装されており、それを使ってユーザーのツイート一覧を表示する Controller があるとする。
class TweetsController < ApplicationController def index twitter_client = TwitterClient.new render json: { tweets: twitter_client.fetch_tweets } end end
この Controller のテストを書くときに、ツイートを取得する部分 (twitter_client.fetch_tweets
) をモック化する必要があるが、RSpec の場合はこう書く。
tweet_mock = %i[ 'こんにちは' 'はじめまして' ] allow(twitter_client).to receive(:fetch_tweets).and_return(tweet_mock)
これにより fetch_tweets
は tweet_mock
を返すようになり、テストが書けるようになる。
ちなみに allow
は expect
と書くこともでき、両者の違いは allow
は fetch_tweets
が呼びだされていなくてもエラーにはならないが、expect
の方は fetch_tweets
が呼び出されていないとエラーになる。
Ruby における Hash の定義方法
{'key' => 'value'} => {"key"=>"value"} {:key => 'value'} => {:key=>"value"} {key: 'value'} => {:key=>"value"}
最後の書き方は Ruby 1.9 以降の書き方ですが、いまはもうこの書き方が主流な感じがしますね。
最初と最後の書き方では key が文字列になるかシンボルになるかの違いがありますが、可能なら key はシンボルで定義した方がいいと思います。
Ruby のシンボルはただの数値 (:key なら 256348 という感じ) なので、文字列の生成と比べてコストが低いです。
またシンボルは何回呼び出してもひとつしか生成されない (皆んなが 1 つのオブジェクトを参照する) ので、そういった意味でもシンボルの方がパフォーマンスが高いです。
以上の理由から、hash を定義するときは key はなるべくシンボルで定義した方がいいですね。