gpt4 book ai didi

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

转载 作者:数据小太阳 更新时间:2023-10-29 07:09:02 27 4
gpt4 key购买 nike

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

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

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

谢谢!

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

最佳答案

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

config.cache_classes = false

lib/目录中的类通常是通过初始化程序加载的,不受此设置的约束。

当您转向生产时,您会希望缓存所有类,以便请求更快,并且 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

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

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

Ruby 是一种解释型语言(JRuby 对预编译有一些支持,但它仍然是解释型的)。在初始化时解释一次类的定义类似于编译 php 并以可执行格式部署(有点)。解释器不会一直为重新定义类而烦恼。

强制显式重新加载是对这种解释型语言的优化。 (如果你在 php 中进行 AOT 编译,你也需要在更改后重新加载编译的“字节码”;默认的 php 使用即时编译,这是你正在利用的)

关于ruby-on-rails - 为什么需要在 Rails 3 中重新加载代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5308970/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com