`
fantaxy025025
  • 浏览: 1309079 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

Rails源码阅读(13)rails中的autoload和ruby的autoload

 
阅读更多

Rails源码阅读(13)rails中的autoload和ruby的autoload

 

ruby的autoload

autoload(module, filename) → nilclick to toggle source

Registers filename to be loaded (using Kernel::require) the first time that module (which may be a String or a symbol) is accessed in the namespace of mod.

module A
end
A.autoload(:B, "b")
A::B.doit            # autoloads "b"

可以看出是在 Kernel中的方法。

 

rails的autoload

在active_support中

gems/activesupport-3/lib/active_support/dependencies/autoload.rb

 

    def autoload(const_name, path = @@at_path)
      full = [self.name, @@under_path, const_name.to_s, path].compact.join("::")
      location = path || Inflector.underscore(full)

      if @@eager_autoload
        @@autoloads[const_name] = location
      end
      super const_name, location
    end

 rails重写了这个方法。

 

做了两件事情:

#1 如果path已经被指定了,即代码作者已经指定了load file,则走ruby默认的方法,即代码中的super

#2 如果path麽有指定,则以当前的Module名字为作用域,加上const_name以及其他的一些东西(见文件的其他代码),拼接成一个文件名字。

    简而言之,如果没有指定path,则从当前的命名空间内找那个文件。寻找方法其实就是rails通用的方法,从这点上来看,仍然遵守了rails的“一致性”。

 

    第二点是要注意很容易出错,即只有在path没有指定情况下才走rails的机制。如果指定了path就不走这套机制了,一定注意。

    比如下面的写法:

 

class A
  require "active_support/all"
  extend ActiveSupport::Autoload
  autoload :B, "b"
end

 加载哪个文件呢?

 

如果认为是加载 a/b  文件就错了。注意这里path不是空。

正确答案是加载”b“文件,和ruby的机制一样。

 

rails为什么不做成总是在当前的命名空间内找呢?

因为这破坏了默认的ruby的机制。

这样导致很多不用active_support的gem就没法工作了。

比如:

# Captcha-Plugin for Rails
module EasyCaptcha
  autoload :Espeak, 'easy_captcha/espeak'
。。。
end

 如果用rails的机制,那就得加载文件”easy_captcha/easy_captcha/espeak“了,这是致命的。

 rails只好这样做,如果你指定了path,就走原机制吧。

 

小姐:

    rails的auto_load只是补充了一下path为空的情况下的常量寻找方法。其他的没有变。别用混了。

    好处是什么?

    懒人原则和默认原则和一致性原则。

    如果我不写,大家都知道在哪里(遵循rails的原则)。

    如果我写了,那就覆盖默认原则,使用我写的。

 

其他补充

    其实造rails的人更懒,才造就了rails。就像这个autoload一样,源码里还有不少辅助方法,专门给懒人用的,如果写的时候觉得重复代码不少,就可以看看源码了,懒的程序员一般想的都差不多。

 

+

=

-

-

=

+

 

分享到:
评论

相关推荐

    VIM的Rails编辑插件rails.vim.zip

    rails.vim提供了常用的一些命令,可以帮助开发,例如:Rgenerate, Rake, Rfind,RTview等,很方便,也很实用。...拷贝 autoload/rails.vim, plugin/rails.vim, 和 doc/rails.txt 到 ~/.vim 目录. 标签:rails

    授予访问权限:Rails的基于多角色和白名单的授权gem(不仅是Rails!)

    授予访问权限骄傲地制造AccessGranted是基于多角色和白名单的Rails授权gem。 而且它是轻量级的(约300行代码)!安装将gem添加到您的gemfile中: gem 'access-granted' , '~> 1.1.0' 运行bundle命令进行安装。 然后...

    grape-sample:在 Rails 应用程序中使用 Grape 生成 API

    它与 Ruby on Rails 集成良好,允许开发者在 Rails 应用程序中轻松地创建和管理 API。下面我们将深入探讨如何在 Rails 应用程序中使用 Grape 以及其核心特性。 ### 1. 安装 Grape 在你的 Rails 项目中,首先需要...

    php_rails_router:[已弃用] Rails 的路由器,用 PHP 编写

    主要问题在 GH-1 中描述)。 用法 使用Router\Routes::draw并给它一个闭包。 您将嵌套闭包,以模仿 DSL。 基本路由将作为参数注入到闭包中,例如 <?php //do require 'vendor/autoload'; and stuffs Router \ ...

    Ruby

    Ruby中的类可以自由定义方法,甚至可以为已有类添加方法,这是通过 reopen 类来实现的。 ### 2. 动态性 Ruby的动态性体现在许多方面:类型检查是在运行时进行的,这意味着可以在程序运行过程中改变变量的类型;...

    涌入:使用ActiveJob和Redis的快速分布式工作流运行程序

    Ruby on Rails 对于RoR,需要完整的环境就足够了: require_relative './config/environment.rb' 并通过将其目录添加到config/application.rb autoload_paths中,确保正确加载了您的作业和工作流: config ....

    Laravel开发-slimphp-vanilla

    它的设计灵感来自于Ruby on Rails的ActiveRecord,允许开发者以面向对象的方式操作数据库,极大地简化了数据库交互。 在"Laravel开发-slimphp-vanilla"项目中,开发者选择将这两个组件结合起来,以获得最佳的性能和...

    W4D5

    3. **块和闭包**:Ruby中的块是一段可传递的代码,可以作为参数传递给方法,闭包则是能够访问其定义时作用域的函数。 4. **元编程**:Ruby允许在运行时修改类和对象,这使得元编程变得非常强大且灵活。 5. **简洁的...

    关于PHP常见面试题.pdf

    - **Ruby:** 更侧重于简洁和表达力,有Rails框架,非常适合快速开发。 - **Java:** 强类型语言,适用于大型企业级应用。 **优势:** - **易用性:** PHP的语法相对简单,学习曲线平缓。 - **广泛的社区支持:** ...

    trucker:迁移遗留数据的助手

    gem "trucker" 生成基本卡车司机文件script/generate truck 这将执行以下操作: 将旧版适配器添加到database.yml 添加app/models/legacy目录在Rails Initializer配置块中将app/models/legacy添加到autoload_paths ...

    PHPActiveRecord-开源

    ActiveRecord 是一种设计模式,最初在 Ruby on Rails 框架中被广泛应用。它将数据库表中的记录映射为类的对象,每个表对应一个类,表中的列对应类的属性。这样,开发者可以通过操作对象的方法来执行 CRUD(创建、...

    用 Composer构建自己的 PHP 框架之设计 MVC

    在MVC架构中,模型(Model)代表数据和业务逻辑层,视图(View)负责展示数据,控制器(Controller)则作为中间层处理输入并调用模型和视图。这种分离的架构模式能够使代码更加模块化,易于管理和维护,也便于团队协作开发...

    numeroporextenso-php::heavy_dollar_sign::writing_hand_selector:Converte数字em valor por可扩展

    '/vendor/autoload.php' ; use WGenial \ NumeroPorExtenso \ NumeroPorExtenso ; $ extenso = new NumeroPorExtenso ; $ extenso = $ extenso -> converter ( 123.45 ); echo $ extenso ; // cento e vinte três ...

Global site tag (gtag.js) - Google Analytics