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一样,源码里还有不少辅助方法,专门给懒人用的,如果写的时候觉得重复代码不少,就可以看看源码了,懒的程序员一般想的都差不多。

 

+

=

-

-

=

+

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值