2

Railsアプリケーションで次のようなものが表示されます。

Application.routes.draw do
    root :to => "accounts#index"
end

ここで、「/」が要求されたパスである場合に、レールがどこにルーティングするかを定義すると言われています。しかし、Railsコードで定義されているこの「root」関数はどこにありますか?このトリックを機能させるためにどのようなスコーピングの問題が関係しているのかわかりません。

ブロックが関数に渡されていることがわかりdrawます。したがって、渡されたブロックを実行するためにdraw関数が呼び出されると想定しています。しかし、関数が魔法のように渡されたブロックのスコープ内にあるyield理由はまだわかりません。root

4

2 に答える 2

5

rootに定義されています。ActionDispatch::Routing::Mapper::Baseこれはに含まれていActionDispatch::Routing::Mapperます。

一見しただけではなく、舞台裏で起こっていることが少しあります。

の定義を見ると、そのdraw理由がわかります。

# action_dispatch/routing/route_set.rb
def draw(&block)
  # ...
  eval_block(block)
  # ...
end

ブロックは(を使用して)procに変換され、少し下に定義されているproc&に渡されます。eval_block

def eval_block(block)
  # ...
  mapper = Mapper.new(self)
  # ...
  mapper.instance_exec(&block)
end

したがって、結局のところ、yieldまったく使用されていません。渡すブロックはApplication.routes.draw、のインスタンスのコンテキストで評価されているだけですActionDispatch::Routing::Mapper

に追加puts selfするとconfig/routes.rb、これが実際に動作していることがわかります。

Application.routes.draw do
  puts self
end

実行するrake routesと、次のようなものが得られます。

#<ActionDispatch::Routing::Mapper:0x007feadf52cbd8>
# ...

詳細については、以下を参照してください。

http://ruby-doc.org/core-1.8.7/Object.html#method-i-instance_exec https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/routing/route_set .rb#LC296 https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/routing/mapper.rb#LC336 http://www.amazon.com/Metaprogramming-Ruby-Program-Like -長所/dp/ 1934356476

于 2013-02-05T02:05:01.567 に答える
1

https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/routing/mapper.rb

def root(options = {})
  options = { :to => options } if options.is_a?(String)
  match '/', { :as => :root, :via => :get }.merge!(options)
end

https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/routing.rb

module Routing
  autoload :Mapper, 'action_dispatch/routing/mapper'
于 2013-02-04T22:47:29.677 に答える