2012-02-09
pushしちゃったコミットのコメントを直す方法
git | |
![]()
結論。そのリポジトリは捨てて作り直そう。
方法。git filter-branchやgit rebase -i (のreword)などでコメントを変更することはできるけど、そうすると変更されたコメントの新しいコミットが作られるだけで古いコメントのコミットも残る。
この古いコメントのコミットは、新たに作るリポジトリにはコミットしないで、新しいコミットの方のブランチだけをコミットすればOK。
あと、新しいリポジトリに移行したいブランチはちゃんとローカルに作っておかないと、pushできないのでちゃんとbranchをローカルに作るべし。
$ git checkout 移行したいブランチ名
でoriginを削除
$ git remote rm origin
コメントの修正はfilter-branchが楽です。 ( http://www.clear-code.com/blog/2012/1/5.html で紹介されている例 )
$ git filter-branch --msg-filter 'sed -e "s/Merge.*internal.*\$/Merge/"' -f
で、ここで新しく作られたブランチと、古いブランチがちゃんと分かれていることを確認したら、それを新しいリポジトリに移行しよう。
まず新しいリポジトリを作る。
githubならadmin画面からdeleteして、もう一回同じ名前で作るのはアリ。
ただしチームのメンバーに同じ名前だけど別物だから気を付けてね、と話しておく必要がある。
次にoriginを再設定する
$ git remote add origin 新しいリポジトリのURL
移行したいブランチをpushしまくる
$ git push origin 移行したいブランチ名
それからタグ関係も一緒に移行できればいいんだけど、古いブランチの方に付けられているので、無理っぽい。
自分で新旧のコミットのコメントを読んで新しい方に手動でタグを貼るしかなさそう。
これで多分オッケーなはず。
2012-01-20
2012-01-13
developmentを実現したいのでコードを読んでみる#5
昨日ログを出力するように変更したrailsを使って、ほとんど素のrails3のアプリでサーバの起動、GETリクエストx3、サーバの停止までにActionDispatch::Reloaderの各メソッドがどのように呼びだされるのか、developmentとproductionの場合それぞれについて出力してみました。
production
起動時
ActionDispatch::Reloader.to_cleanup(<Proc:0x00000100e78410@/Users/akima/workspace/rails/railties/lib/rails/application/bootstrap.rb:55>)
module Rails class Application module Bootstrap include Initializable # (中略) initializer :set_clear_dependencies_hook, :group => :all do ActionDispatch::Reloader.to_cleanup do ActiveSupport::DescendantsTracker.clear ActiveSupport::Dependencies.clear end end
ActionDispatch::Reloader.to_prepare(<Proc:0x00000100e4e250@/Users/akima/workspace/rails/activesupport/lib/active_support/i18n_railtie.rb:21>)
module I18n class Railtie < Rails::Railtie # (中略) initializer "i18n.callbacks" do ActionDispatch::Reloader.to_prepare do I18n::Railtie.reloader.execute_if_updated end end
ActionDispatch::Reloader.prepare!
ActionDispatch::Reloader#initialize(nil)
module Rails class Application module Finisher include Initializable # (中略) initializer :run_prepare_callbacks do ActionDispatch::Reloader.prepare! end
module ActionDispatch class Reloader include ActiveSupport::Callbacks # (中略) # Execute all prepare callbacks. def self.prepare! self.trace_log(:prepare!) new(nil).run_callbacks :prepare end
GET /tests/foo?idx=1
ActionDispatch::Reloader.to_prepare(<Proc:0x00000102279838@/Users/akima/workspace/rails/railties/lib/rails/application/finisher.rb:63 (lambda)>)
module Rails class Application module Finisher include Initializable # (中略) initializer :set_routes_reloader do |app| reloader = lambda { app.routes_reloader.execute_if_updated } reloader.call ActionDispatch::Reloader.to_prepare(&reloader) end
ActionDispatch::Reloader.to_cleanup(<Proc:0x00000100e0ceb8@/Users/akima/workspace/rails/activerecord/lib/active_record/railtie.rb:83>)
ActionDispatch::Reloader.to_prepare(<Proc:0x00000100d3ccb8@/Users/akima/workspace/rails/activerecord/lib/active_record/railtie.rb:94>)
module ActiveRecord # = Active Record Railtie class Railtie < Rails::Railtie # (中略) initializer "active_record.set_dispatch_hooks", :before => :set_clear_dependencies_hook do |app| ActiveSupport.on_load(:active_record) do ActionDispatch::Reloader.to_cleanup do ActiveRecord::Base.clear_reloadable_connections! ActiveRecord::Base.clear_cache! end end end config.after_initialize do ActiveSupport.on_load(:active_record) do instantiate_observers ActionDispatch::Reloader.to_prepare do ActiveRecord::Base.instantiate_observers end end end
GET /tests/foo?idx=2
なし
GET /tests/foo?idx=3
なし
サーバを停止
なし
まとめ
development
起動時
ActionDispatch::Reloader.to_cleanup(<Proc:0x000001023916a8@/Users/akima/workspace/rails/railties/lib/rails/application/bootstrap.rb:55>)
ActionDispatch::Reloader.to_prepare(<Proc:0x00000100f58150@/Users/akima/workspace/rails/activesupport/lib/active_support/i18n_railtie.rb:21>)
これらはproductionと同じ。
ActionDispatch::Reloader#initialize(#<ActionDispatch::Callbacks:0x0000010421f318 @app=#<ActiveRecord::ConnectionAdapters::ConnectionManagement:0x0000010421f340 @app=.... )
/Users/akima/workspace/rails/actionpack/lib/action_dispatch/middleware/stack.rb:112:in `build' /Users/akima/workspace/rails/railties/lib/rails/engine.rb:447:in `app'
module ActionDispatch class MiddlewareStack # (中略) def build(app = nil, &block) app ||= block raise "MiddlewareStack#build requires an app" unless app middlewares.reverse.inject(app) { |a, e| e.build(a) } end
module Rails class Engine < Railtie # (中略) def app @app ||= begin config.middleware = config.middleware.merge_into(default_middleware_stack) config.middleware.build(endpoint) end end
GET /tests/foo?idx=1
ActionDispatch::Reloader.prepare!
ActionDispatch::Reloader#initialize(nil)
これらはproductionの起動時に実行されるものと同じ
ActionDispatch::Reloader.to_prepare(<Proc:0x000001027b3358@/Users/akima/workspace/rails/railties/lib/rails/application/finisher.rb:63 (lambda)>)
productionのGET /tests/foo?idx=1で実行されるものと同じ
ActionDispatch::Reloader#call({"GATEWAY_INTERFACE"=>"CGI/1.1", "PATH_INFO"=>"/tests/foo", "QUERY_STRING"=>"idx=1", ...)
module Rack class Sendfile # (中略) def call(env) status, headers, body = @app.call(env) if body.respond_to?(:to_path) case type = variation(env)
ActionDispatch::Reloader.to_cleanup(<Proc:0x00000103355328@/Users/akima/workspace/rails/activerecord/lib/active_record/railtie.rb:83>)
ActionDispatch::Reloader.to_prepare(<Proc:0x0000010334c890@/Users/akima/workspace/rails/activerecord/lib/active_record/railtie.rb:94>)
productionのGET /tests/foo?idx=1で実行されるものと同じ
ActiveRecord::ConnectionAdapters::ConnectionManagement::Proxy#close
ActionDispatch::Reloader.cleanup!
ActionDispatch::Reloader#initialize(nil)
module Rack module Handler def service(req, res) # (中略) status, headers, body = @app.call(env) begin res.status = status.to_i headers.each { |k, vs| if k.downcase == "set-cookie" res.cookies.concat vs.split("\n") else # Since WEBrick won't accept repeated headers, # merge the values per RFC 1945 section 4.2. res[k] = vs.split("\n").join(", ") end } body.each { |part| res.body << part } ensure body.close if body.respond_to? :close end end
module ActionDispatch class Reloader # (中略) # Execute all cleanup callbacks. def self.cleanup! self.trace_log(:cleanup!) new(nil).run_callbacks :cleanup end # (中略) module CleanupOnClose def close ActionDispatch::Reloader.trace_log_impl("#{self.class.name}#close") super if defined?(super) ensure ActionDispatch::Reloader.cleanup! end end
GET /tests/foo?idx=2
ActionDispatch::Reloader#call({"GATEWAY_INTERFACE"=>"CGI/1.1", "PATH_INFO"=>"/tests/foo", "QUERY_STRING"=>"idx=2", ...)
GET /tests/foo?idx=3
ActiveRecord::ConnectionAdapters::ConnectionManagement::Proxy#close
ActionDispatch::Reloader.cleanup!
ActionDispatch::Reloader#initialize(nil)
ActionDispatch::Reloader#call({"GATEWAY_INTERFACE"=>"CGI/1.1", "PATH_INFO"=>"/tests/foo", "QUERY_STRING"=>"idx=3", ...)
サーバを停止
ActiveRecord::ConnectionAdapters::ConnectionManagement::Proxy#close
ActionDispatch::Reloader.cleanup!
ActionDispatch::Reloader#initialize(nil)
2012-01-12
developmentを実現したいのでコードを読んでみる#4
だんだん、ソースコードを読むだけではしんどくなってきたので、ちょっとずるをします。
先日rails new --devの使い方を書きましたが、
http://d.hatena.ne.jp/akm/20120110#1326216516
railsの調査用のコードを入れまくって、ブログに書こうとおもって、forkしたので、それを参照するように--devオプションを使ってrailsアプリを作り、それをちょっと動かしてどこから呼び出されているのかを調べちゃおうという魂胆です。
ActionDispatch::Reloaderに対してはこんな感じの出力を追加しました。
https://github.com/akm/rails/commit/b0e5006cd2797c634cb596e7c3cddfa1fc3ffb44
2012-01-10
developmentを実現したいのでコードを読んでみる#3
昨日は、ActionDispatch::Reloader で使われている ActiveSupport::Callbacks のドキュメントを読みました。
今日はそれが ActionDispatch::Reloader でどう使われているのかを追いかけたいと思います。
https://github.com/rails/rails/blob/3-1-stable/actionpack/lib/action_dispatch/middleware/reloader.rb
まず定義されているコールバックは、 :prepare と :cleanup の2つです。
どちらも :scope => :name というオプションが指定されているので、コールバックで呼び出されるのがオブジェクトの場合、それぞれ#prepare と #cleanup メソッドが呼び出されます。
で、コールバックを登録するのは、 to_prepare と to_cleanup というクラスメソッドです。
なので、to_prepare, to_cleanup, prepare!, cleanup! を呼び出している箇所が分かればいいような予感がします。
to_prepare
-*- mode: grep; default-directory: "~/.rvm/gems/ruby-1.9.2-head@tengine_console/gems/" -*- Grep started at Wed Jan 11 00:42:47 grep -nr to_prepare actionpack-3.1.3/lib railties-3.1.3/lib actionpack-3.1.3/lib/action_dispatch/middleware/callbacks.rb:11: delegate :to_prepare, :to_cleanup, :to => "ActionDispatch::Reloader" actionpack-3.1.3/lib/action_dispatch/middleware/reloader.rb:34: def self.to_prepare(*args, &block) railties-3.1.3/lib/rails/application/finisher.rb:22: initializer :add_to_prepare_blocks do railties-3.1.3/lib/rails/application/finisher.rb:23: config.to_prepare_blocks.each do |block| railties-3.1.3/lib/rails/application/finisher.rb:24: ActionDispatch::Reloader.to_prepare(&block) railties-3.1.3/lib/rails/application/finisher.rb:59: # Force routes to be loaded just at the end and add it to to_prepare callbacks railties-3.1.3/lib/rails/application/finisher.rb:65: ActionDispatch::Reloader.to_prepare(&reloader) railties-3.1.3/lib/rails/railtie/configuration.rb:55: # Array of callbacks defined by #to_prepare. railties-3.1.3/lib/rails/railtie/configuration.rb:56: def to_prepare_blocks railties-3.1.3/lib/rails/railtie/configuration.rb:57: @@to_prepare_blocks ||= [] railties-3.1.3/lib/rails/railtie/configuration.rb:62: def to_prepare(&blk) railties-3.1.3/lib/rails/railtie/configuration.rb:63: to_prepare_blocks << blk if blk railties-3.1.3/lib/rails/railtie.rb:77: # # Add a to_prepare block which is executed once in production railties-3.1.3/lib/rails/railtie.rb:79: # config.to_prepare do
to_cleanup
-*- mode: grep; default-directory: "~/.rvm/gems/ruby-1.9.2-head@tengine_console/gems/" -*- Grep started at Wed Jan 11 00:44:47 grep -nr to_cleanup actionpack-3.1.3/lib railties-3.1.3/lib actionpack-3.1.3/lib/action_dispatch/middleware/callbacks.rb:11: delegate :to_prepare, :to_cleanup, :to => "ActionDispatch::Reloader" actionpack-3.1.3/lib/action_dispatch/middleware/reloader.rb:40: def self.to_cleanup(*args, &block) railties-3.1.3/lib/rails/application/bootstrap.rb:55: ActionDispatch::Reloader.to_cleanup do
parepare!
-*- mode: grep; default-directory: "~/.rvm/gems/ruby-1.9.2-head@tengine_console/gems/" -*- Grep started at Wed Jan 11 00:45:24 grep -nr "prepare!" actionpack-3.1.3/lib railties-3.1.3/lib actionpack-3.1.3/lib/action_controller/metal/testing.rb:21: @_response.prepare! actionpack-3.1.3/lib/action_dispatch/http/response.rb:192: alias prepare! to_a actionpack-3.1.3/lib/action_dispatch/middleware/reloader.rb:23: # middleware stack, but are executed only when +ActionDispatch::Reloader.prepare!+ actionpack-3.1.3/lib/action_dispatch/middleware/reloader.rb:45: def self.prepare! railties-3.1.3/lib/rails/application/finisher.rb:41: ActionDispatch::Reloader.prepare! railties-3.1.3/lib/rails/console/app.rb:30: ActionDispatch::Reloader.prepare!
cleanup!
-*- mode: grep; default-directory: "~/.rvm/gems/ruby-1.9.2-head@tengine_console/gems/" -*- Grep started at Wed Jan 11 00:45:58 grep -nr "cleanup!" actionpack-3.1.3/lib railties-3.1.3/lib actionpack-3.1.3/lib/action_dispatch/middleware/reloader.rb:24: # or +ActionDispatch::Reloader.cleanup!+ are called manually. actionpack-3.1.3/lib/action_dispatch/middleware/reloader.rb:50: def self.cleanup! actionpack-3.1.3/lib/action_dispatch/middleware/reloader.rb:62: ActionDispatch::Reloader.cleanup! railties-3.1.3/lib/rails/console/app.rb:29: ActionDispatch::Reloader.cleanup!
それぞれ調べないといけないんですが、
railties-3.1.3/lib/rails/console/app.rb:29: ActionDispatch::Reloader.cleanup! railties-3.1.3/lib/rails/console/app.rb:30: ActionDispatch::Reloader.prepare!
で、rails consoleでの reload! の実装として使われているのが発見できました。
https://github.com/rails/rails/blob/3-1-stable/railties/lib/rails/console/app.rb
rails new --devの使い方
rails | |
![]()
$ git clone https://github.com/rails/rails.git $ cd rails/ $ git branch -r $ git checkout 3-2-stable $ cd .. $ ruby rails/railties/bin/rails new rails3_20120110 --dev
これでcloneしたリポジトリの(3-2-stableブランチ)を参照するrailsアプリが生成できます。
http://edgeguides.rubyonrails.org/3_0_release_notes.html#living-on-the-edge
2012-01-09
developmentを実現したいのでコードを読んでみる#2
昨日はRails::Applicationの継承関係をはっきりさせて、初期化のあたりをどうなっているのかRails Guideのドキュメントをみつけてわーいってところまで行きました。
Rails::Railtie <|---- Rails::Engine <|---- Rails::Application
http://guides.rubyonrails.org/initialization.html
で、本題は何だったのかっていうと、
./application.rb:168: middleware.use ::ActionDispatch::Reloader unless config.cache_classes
でございます。
初期化周りは上のドキュメントとコードをざっくり読んで分かった気になったけど、実はたぶん分かっていないことが分かってはいるけど、あえて分かったように振る舞ってみることで先に進んじゃいます。
というわけで今日は本丸 ActionDispatch::Reloader のコードを読みます。
ActionDispatch::Reloader
https://github.com/rails/rails/blob/3-1-stable/actionpack/lib/action_dispatch/middleware/reloader.rb
分かった気になっているので、誤解を恐れず書いてみるとRack::Serverを継承したRails::Serverのインスタンスがリクエストを処理する際にappをcallするのですが、そのappにはmiddlewareがわらわらとくっついていて、callの呼び出しに対してフィルタをかける感じです。
そのmiddlewareの一つが読もうとしているActionDispatch::Reloaderです。なのでcallメソッドが理解できれば良いはずなんですが、
def call(env)
run_callbacks :prepare
response = @app.call(env)
response[2].extend(CleanupOnClose)
response
rescue Exception
run_callbacks :cleanup
raise
end
最初のrun_callbacksでいきなり躓きましたwこれはきっと、includeされているActiveSupport::Callbacksで定義されているメソッドなんでしょう。
ActiveModel::Callbacksもこいつを使ってるのは知ってたのですが、ここでも出てきやがりました。ちょっとActiveSupport::Callbacksをやっつけましょう。
ActiveSupport::Callbacks
https://github.com/rails/rails/blob/3-1-stable/activesupport/lib/active_support/callbacks.rb
ソースコードを見ると結構難しいことをたくさんやっている感じなので、まずはドキュメントを見てみましょう。
http://api.rubyonrails.org/classes/ActiveSupport/Callbacks.html のExampleを見てみると、define_callbacks でコールバックのkindだけ定義して、set_callbackでコールバックのkindに対して、いつ何をするのかを登録できる。で、実際に動くときにrun_callbacksをkindを指定して実行すると、set_callbackでkindに対して登録されたコールバックが呼び出される、って感じですね。
ポイントはrun_callbackがインスタンスメソッドなのに対して、
define_callbacks と set_callback はクラスメソッドってこと。なので、上のリンク先には後者は書いてなくて、 http://api.rubyonrails.org/classes/ActiveSupport/Callbacks/ClassMethods.html
に説明が書いてあります。
ざーっと読んだ感じだと、 ActiveSupport::Callbacks.define_callbacks の :scope オプションが難しいっすね。
define_callbacks :save, :scope => [:kind, :name]
という風に定義されて、
set_callback :save, :before, Audit.new
という風にコールバック用のオブジェクトが指定されていたら、 Audit#before_saveメソッドが実行されると。
define_callbacks :save, :scope => [:kind]
ならAudit#beforeで
define_callbacks :save, :scope => [:name]
ならAudit#saveなんだそうですよ。
kindが before/after/aroundで、nameが指定されたdefine_callbackに指定されたcallbacksの要素ってことですね。
おっけー。じゃあ気を取り直して ActionDispatch::Reloader を読もう!と思ったけど、明日早いのでもう寝ます。また明日ー。
2012-01-08
developmentを実現したいのでコードを読んでみる#1
Railsのdevelopmentモードのように特定のディレクトリ以下のソースコードを適切なタイミングで読み直す機能を作りたいのですが、実際Railsって何やっているのか分からんので調べます。
cache_classes
railsアプリの config/environments/development.rb には大抵
config.cache_classes = false
と書いてあります。クラスのキャッシュを無効にするって意味っすね。
この設定がどこで使われているのか、railsの設定はrailtiesに書いてあるのでgrepしてみました。
-*- mode: grep; default-directory: "~/.rvm/gems/ruby-1.9.2-head@tengine_console/gems/railties-3.1.3/lib/rails/" -*- Grep started at Sun Jan 8 20:35:42 grep -nri cache_classes . ./application/bootstrap.rb:64: ActiveSupport::Dependencies.mechanism = config.cache_classes ? :require : :load ./application/configuration.rb:9: :cache_classes, :cache_store, :consider_all_requests_local, ./application/configuration.rb:95: self.cache_classes = true ./application/finisher.rb:49: if config.cache_classes && !$rails_rake_task ./application/finisher.rb:70: if config.cache_classes && !config.dependency_loading ./application.rb:22: # "allow_concurrency", "cache_classes", "consider_all_requests_local", "filter_parameters", ./application.rb:168: middleware.use ::ActionDispatch::Reloader unless config.cache_classes ./generators/rails/app/templates/config/environments/development.rb.tt:7: config.cache_classes = false ./generators/rails/app/templates/config/environments/production.rb.tt:5: config.cache_classes = true ./generators/rails/app/templates/config/environments/test.rb.tt:8: config.cache_classes = true ./railtie/configuration.rb:39: # Third configurable block to run. Does not run if config.cache_classes
実はloadが使われる
developmentモードではActiveSupport::Dependenciesはrequireではなく、loadを使ってロードします。
ActiveSupport::Dependenciesが動く場合ってことは、const_missingあたりから命名規則にしたがってファイルをロードするあたりの話っすね、たぶん。
./application/bootstrap.rb:64: ActiveSupport::Dependencies.mechanism = config.cache_classes ? :require : :load
middleware.use ::ActionDispatch::Reloader
./application.rb:168: middleware.use ::ActionDispatch::Reloader unless config.cache_classes
一番大事そうなのはココ。developmentモードではミドルウェアがActionDispatch::Reloaderを使うそうです。
middlewareってRackとかの話だよね?これまでちゃんと調べたことなかったので、middlewareを調べましょう!
middleware
まず、ここに登場しているmiddlewareは何かと言えば、ここに書いてある。
https://github.com/rails/rails/blob/3-1-stable/railties/lib/rails/application.rb#L146
def default_middleware_stack
ActionDispatch::MiddlewareStack.new.tap do |middleware|
if rack_cache = config.action_controller.perform_caching && config.action_dispatch.rack_cache
require "action_dispatch/http/rack_cache"
middleware.use ::Rack::Cache, rack_cache
end
#...
end
end
ActionDispatch::MiddlewareStack.new.tapに渡されるブロックの引数でした。
ActionDispatch::MiddlewareStack
これは何ぞ?と検索してみる。ActionDispatchだからactionpack以下にあるはず・・・
https://github.com/rails/rails/blob/3-1-stable/actionpack/lib/action_dispatch/middleware/stack.rb
ココですね。
ActionDispatch::MiddlewareStackクラスの定義の中に、Middlewareクラスの定義があって、ActionDispatch::MiddlewareStackクラスの具体的な記述は
以降に書かれています。
include Enumerableとかしてるし、initializeメソッドで
@middlewares = []
とかやっているので、前述のMiddlewareクラスのオブジェクトを複数個持ってなんかする奴なんでしょうな。
具体的な使われ方として、
middleware.use ::ActionDispatch::Reloader
が意味するところをまずは知りたいんだけど、useメソッドの定義を読むと引数とブロックを、前述のMiddleware.newの引数に渡しちゃってmiddlewareを生成してそれをmiddlewaresに追加してるってことっすね。
def use(*args, &block)
middleware = self.class::Middleware.new(*args, &block)
middlewares.push(middleware)
end
ActionDispatch::MiddlewareStack::Middleware
じゃあその前述のMiddlewareを知っておきたいところなんだけど、
https://github.com/rails/rails/blob/3-1-stable/actionpack/lib/action_dispatch/middleware/stack.rb#L6
def initialize(klass_or_name, *args, &block)
@klass = nil
if klass_or_name.respond_to?(:name)
@klass = klass_or_name
@name = @klass.name
else
@name = klass_or_name.to_s
end
@classcache = ActiveSupport::Dependencies::Reference
@args, @block = args, block
end
引数の最初にClassかクラスの名前を期待していて、Classが指定された場合は@klassに代入されるけど、そうじゃない場合は@klassはnilのまま。
それ以外はそのまま@argsに代入される。こいつはどこで使われるかって言うと、
def build(app)
klass.new(app, *args, &block)
end
buildメソッドで指定されたklass.newの引数として、このメソッドの引数appとともに@argsの内容が渡されるんだけど、klassメソッドにはこう書いてある。
def klass
@klass || classcache[@name]
end
名前を指定した場合には、classcacheから検索するようになっています。
classcacheはinitializeで指定されているActiveSupport::Dependencies::Referenceですね。
middleware.use ::ActionDispatch::Reloader
もう一度考えてみると、ActionDispatch::MiddlewareStackのインスタンスであるmiddlewareに::ActionDispatch::Reloaderをクラスを指定してuseさせているので、
ActionDispatch::MiddlewareStack::Middleware.new(::ActionDispatch::Reloader)
あとは、どこかでこれのbuildメソッドが呼び出されるタイミングがあるはずなんだけど、
実は ActionDispatch::MiddlewareStack#build で ActionDispatch::MiddlewareStack::Middleware#build が呼び出されます。
def build(app = nil, &block)
app ||= block
raise "MiddlewareStack#build requires an app" unless app
middlewares.reverse.inject(app) { |a, e| e.build(a) }
end
こいつはどこから呼び出されるのか?これはRails::Engine#appから呼び出されます。
Rails::Engine
railtiesをActionDispatch::MiddlewareStackでgrepしてみると、以下の2つが見つかります。
-*- mode: grep; default-directory: "~/.rvm/gems/ruby-1.9.2-head@tengine_console/gems/railties-3.1.3/lib/" -*- Grep started at Sun Jan 8 22:52:59 grep -nri ActionDispatch::MiddlewareStack . ./rails/application.rb:146: ActionDispatch::MiddlewareStack.new.tap do |middleware| ./rails/engine.rb:606: ActionDispatch::MiddlewareStack.new
それぞれ Rails::Appliation#default_middleware_stack と Rails::Engine#default_middleware_stack から呼び出されています。
Rails::Appliation? そうです。railsアプリのconfig/application.erbに記述されるアレです。
module Blog class Application < Rails::Application
で、この Rails::Application は Rails::Engine を継承しているわけですね。
https://github.com/rails/rails/blob/3-1-stable/railties/lib/rails/application.rb#L36
じゃあこの Rails::Engine はというと、 Rails::Railtie を継承しています。
https://github.com/rails/rails/blob/3-1-stable/railties/lib/rails/engine.rb#L333
https://github.com/rails/rails/blob/3-1-stable/railties/lib/rails/railtie.rb#L113
まとめるとこういう継承をしているわけですね。
Rails::Railtie <|---- Rails::Engine <|---- Rails::Application
Rails::Applicationのインスタンスがいつ生成されるのかが知りたくなるわけですが、これを追っかけるのは大変!と思っていたら強い味方発見。
http://guides.rubyonrails.org/initialization.html
すばらしい!
続きはまた明日。










