letとlet!の違いがわからない
違いというか使い分け方がわからない
(追記アリ)
letは使われたタイミングで処理される。let!は毎回処理をされる。
てっきり、letは一回初期化されたら使いまわされるんだと思っていたけど、呼び出されたときは毎回初期化するようだ。
describe 'let_test' do let(:sample_1){ puts "****let****"; 'sample1'} let!(:sample_2){ puts "****let!****"; 'sample2'} before do puts "before---" end after do puts "after----" end it { sample_1.should eq 'sample1'} it { sample_1.should eq 'sample1'} it { sample_2.should eq 'sample2'} it { sample_2.should eq 'sample2'} end
実行結果はこんな感じ。
%rspec --format doc let_spec.rb let_test ****let!**** before--- ****let**** after---- should eq "sample1" ****let!**** before--- ****let**** after---- should eq "sample1" ****let!**** before--- after---- should eq "sample2" ****let!**** before--- after---- should eq "sample2" Finished in 0.00204 seconds 4 examples, 0 failures
ちょっと見にくいけど、let及びlet!の{}が呼ばれたタイミングを確認している。letは遅延評価されるみたいなのを読んだことがあったので、一回呼ばれたらキャッシュされる(つまり、sample_1が二回目に呼ばれたときは ****let**** が呼ばれない)と思っていたがそうではなかった。とすると、どちらにせよ使うときには初期化されるのだから使い分ける必要があるのだろうか……というところでよくわからなくなって頭がフットーしそうになった。
The RSpec Book (Professional Ruby Series)
- 作者: David Chelimsky,Dave Astels,Zach Dennis,角谷 信太郎,豊田 祐司,株式会社クイープ
- 出版社/メーカー: 翔泳社
- 発売日: 2012/02/22
- メディア: 大型本
- 購入: 7人 クリック: 141回
- この商品を含むブログ (16件) を見る
これに何か書いてありそうなんだけど、ちょっと手元にない*1ので、メモがてら書いておく。あわよくば識者が教えてくれるかもしれないしネ!!(詳しい方、おしえてください><)
教えてもらった
letはキャッシュされるんだけども、その範囲はbefore〜it〜afterの範囲で一回しか初期化されないという意味だそうな。つまり上記のコードではあんまり意味がなかったのだった!
*1:会社におきっぱなし……