为什么需要在Rails 3中重新加载代码?

Ven*_* D. 5 ruby caching ruby-on-rails sinatra

我是一名前PHP开发人员,学习Rails和Sinatra.在PHP中,每个页面请求都加载了所有必需的文件.如果我更改了一些代码并刷新了页面,我可以确定代码是新鲜的.

在Rails 3中,Controller代码在每个请求中都是新鲜的.但是,如果我修改/ lib文件夹中的任何代码,我需要重新启动服务器以使更改生效.

为什么会这样?这与Ruby的设计方式有关吗?Rails是否进行了一些优化以避免在每个请求上重新加载代码?

谢谢!

编辑:我最感兴趣的是幕后发生的事情.像Rails和Sinatra这样的框架是否为类做了一些特殊的缓存?如果是这样,他们做了什么?Ruby中的默认行为是每次请求都会重新加载所有代码吗?为什么我们需要像Shotgun for Sinatra这样的工具(http://sinatra-book.gittr.com/#automatic_code_reloading)?

Bra*_*don 20

当您处于开发模式时,您应该告诉Rails不要缓存您的类,以便每次重新加载.这意味着每个请求的类基本上都在rails解释器中重新定义.Rails.root/config/environments/development.rb中的设置:

config.cache_classes = false
Run Code Online (Sandbox Code Playgroud)

lib/dir中的类通常通过初始化程序加载,不受此设置的约束.

当您转向生产时,您将需要缓存所有类,因此请求更快,rails将对模型上的范围进行优化.

您可以在另一个初始化程序(可能称为Rails.root/config/initializers/development_reload.rb)中放入一些内容,它可以在开发中的每个请求(或者您正在处理的请求)中重新加载lib目录:

# file development_reload.rb
if Rails.env.development?
  ActionDispatch::Callbacks.after do
    load 'filename_in_lib'
    # or
    Dir.entries("#{Rails.root}/lib").each do |entry|
      load entry if entry =~ /.rb$/
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

我正在调用"load",所以它实际上重新加载文件,而"require"只检查它是否已加载并确定它已经有,所以它不会重新加载它.(我只是将它们放在一起并且不使用它,但Ruby非常灵活,并且允许你做很多.)明智地使用这样的东西,只在开发环境中使用.

为什么需要在Rails 3中重新加载代码?

Ruby是一种解释型语言(JRuby对预编译有一些支持,但它仍然被解释).在初始化时解释类的定义类似于编译php和以可执行格式部署(稍微).口译员不会一直在重新定义课程.

强制显式重新加载是对此类解释语言的优化.(如果您在PHP中进行AOT编译,则需要在更改后重新加载已编译的"字节码";默认的PHP使用即时编译,这是您正在利用的)