Rails.application.config.autoload_paths和标准Ruby require/require_relative有什么区别? [英] What is the difference between Rails.application.config.autoload_paths and standard Ruby require/require_relative?

查看:150
本文介绍了Rails.application.config.autoload_paths和标准Ruby require/require_relative有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在application.rb中看到以下配置:

I see that the following configuration in application.rb:

config.autoload_paths += %W(#{config.root}/app/models/custom_pack/base)
config.autoload_paths += Dir["#{config.root}/app/models/custom_pack/custom_container/**/"]
config.autoload_paths += Dir["#{config.root}/app/models/custom_pack/helpers/**/"]
config.autoload_paths += Dir["#{config.root}/app/models/custom_pack/extensions/**/"]

位于autoload_paths中:

is in the autoload_paths:

Rails.application.config.autoload_paths.grep /custom/
 => ["/Users/dviglione/projects/core/app/models/custom_pack/base", "/Users/dviglione/projects/core/app/models/custom_pack/custom_container/", "/Users/dviglione/projects/core/app/models/custom_pack/helpers/", "/Users/dviglione/projects/core/app/models/custom_pack/extensions/"]

但是这些文件没有被加载.因为出现错误:

But these files are not being loaded. Because I get an error:

 `method_missing': undefined method `create_element' for #<MyElement:0x007f82eca39898> 

该create_element方法是在应该已加载的文件之一中定义的.

That create_element method is defined in one of the files that should have been loaded.

但是,当我使用require/require_relative时,它确实起作用:

However, when I use require/require_relative, it does work:

# /initializers/my_initializer.rb
require "custom_pack/base"

# models/custom_pack/base.rb    
require_relative 'custom_container/base'
require_relative 'custom_container/parent'
require_relative 'custom_container/child'

Dir[File.join(File.expand_path("../helpers", __FILE__), "*_helper.rb")].each { |file| require file }
Dir[File.join(File.expand_path("../extensions", __FILE__), "*_adapter.rb")].each { |file| require file }

根据我从文档中读取的内容,当您使用require'erb'时,Ruby在$ LOAD_PATH中列出的目录中查找文件.也就是说,Ruby遍历其所有目录,并针对每个目录检查它们是否具有名为"erb.rb"的文件.如果找到它们中的任何一个,则解释器将其加载并结束搜索.否则,它将在列表的下一个目录中再次尝试.如果列表用尽,则会引发LoadError.对于自动加载,其想法是,当诸如Post之类的常量丢失并丢失时,例如在app/models中存在post.rb文件时,Rails将会找到它,对其进行评估,并将Post定义为副作用. Rails有一个类似于$ LOAD_PATH的目录集合,可在其中查找post.rb.该集合称为autoload_paths.

From what I read from the documentation, when you use require 'erb', Ruby looks for the file in the directories listed in $LOAD_PATH. That is, Ruby iterates over all its directories and for each one of them checks whether they have a file called "erb.rb". If it finds any of them, the interpreter loads it and ends the search. Otherwise, it tries again in the next directory of the list. If the list gets exhausted, LoadError is raised. For autoloading, the idea is that when a constant like Post is hit and missing, if there's a post.rb file for example in app/models Rails is going to find it, evaluate it, and have Post defined as a side-effect. Rails has a collection of directories similar to $LOAD_PATH in which to look up post.rb. That collection is called autoload_paths.

那为什么需要require/require_relative起作用,而autoload_paths却没有呢?

So why does require/require_relative work, but autoload_paths does not?

推荐答案

这里可能发生了很多事情.

There's a number of things that could be going on here.

1.如果文件遵循以下路径:lib/foo/bar.rb,则需要按如下方式定义类:

1.If a file is following the path: lib/foo/bar.rb the class needs to be defined like:

class Foo::Bar
end

2.Autoload还会延迟加载文件,这意味着仅在调用模型时才加载它们. 例如:

2.Autoload also lazy loads files, which means your models are only loaded when you call them. For example:

puts "I was loaded!"

class MyLibrary
end

irb(main):001:0> require 'mylibrary'
I was loaded!
=> true

irb(main):001:0> autoload :MyLibrary, 'mylibrary'
=> nil
irb(main):002:0> MyLibrary.new
I was loaded!
=> #<MyLibrary:0x0b1jef>

关于autoload的实际用法,建议开始使用require.从理论上讲,autoload听起来不错,但是当某些类依赖于其他模块时,它可能会引起问题.因此,自动加载正在弃用.

As for the actual usage of autoload, it's recommended to start using require instead. In theory autoload sounds nice but it can cause problems when certain classes are dependent on other modules. Because of this autoload is in the process of being deprecated.

这篇关于Rails.application.config.autoload_paths和标准Ruby require/require_relative有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆