Railsでブロック内の変数はどこから来ているのか
2013年10月28日
突然生じているように見えるブロック内の変数が、
どこから来ているのかを調べました。
どこから来ているのかを調べました。
例えば、ActiveRecord のこういうコードや:
class Entry < ActiveRecord::Base scope :filter, -> { entries = arel_table where(:id, 1) } end
RSpec のこういうコードで:
describe 'Foo' do it 'Bar' do end end
突然出てくる where なり arel_table なり it なりは、
どこで定義されているのかということです。
"where" って、お前こそどっから来たんだよ!
ActiveRecord の方
クラス定義中のスコープである self 以下にあるものでした。
先の where(:id, 1) はこれらのように書いても一緒です:
self.where(:id, 1) Entry.where(:id, 1)
-> は lambda と等価ですが、
クラス定義中に lambda を定義した場合は、
クラス定義中のスコープである(省略されている)self も含めて、
束縛したクロージャになっているんですね。
だから where も arel_table も Entry クラスが元々持っている
全クラスメソッドをそのまま呼び出せるのでした。
(あ private の時はどうなるんだろ.. 今度調べる)
そもそも、クラス定義中はスコープが self になるのも知らなかったんですが
それについては以下を参考にしました。
クラス/メソッドの定義 – クラス定義
RSpec の方
これは多分、ブロックの引数で渡しているんだと思いますが..
https://github.com/rspec/rspec-core/blob/master/lib/rspec/core/example_group.rb#L58
https://github.com/rspec/rspec-core/blob/master/lib/rspec/core/example_group.rb#L86
詳しいことは読めていません..