Ruby autoload 用法小结

flydragon · September 04, 2018 · 1993 hits

摘要

分别梳理三种不同的用法

  • 内核 (Kernel.autoload)
  • 模块 (Module.autoload)
  • Rails 扩展 (ActiveSupport::Autoload)

内核方法 (Kernel.autoload)

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

  • 当常量首次访问时,进行require加载,节约内存。
  • 相当于require的智能模式

实例代码

# /home/deploy/a.rb
module A
  def self.hi
    puts 'hi i am module A'
  end
end

puts  'file a.rb has load'

autoload 模式

# irb
autoload(:A, '/home/deploy/demo.rb')

A.hi 
# => file a.rb has load
# hi i am module A

require 模式

# irb

# 执行后,文件立即被加载
require '/home/deploy/demo/a.rb' # => file a.rb has load

A.hi # => hi i am module A

模块方法 (Module.autoload)

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.

  • 当常量在指定命名空间内访问时,进行文件加载
  • 相当于受保护的require的智能模式

实例代码

# /home/deploy/a.rb
module A
  def self.hi
    puts 'hi i am module A'
  end

  module B
    def self.hi
      puts 'hi i am module B'
    end
  end
end
puts 'file a has load'

运行

当访问A:B时加载文件

# irb
module A
end

A.autoload(:B, '/home/deploy/a.rb')

A::B.hi
# => file a has load
# hi i am module B

Rails 扩展 (ActiveSupport::Autoload)

  • 内核autoload方法的扩展,在约定的路径 (ActiveSupport::Inflector.underscore) 中加载文件
  • 省去了写具体路径麻烦
  • 详细实现可以查看源码

代码目录

lib/
  sso.rb
  sso
    a.rb
    b.rb

实例代码

# lib/sso.rb
module Sso
  extend ActiveSupport::Autoload

  autoload :A
  autoload :B
  autoload :C
end

# lib/sso/a.rb
module Sso
  module A
    def self.hi
      puts 'hi i am module A'
    end
  end
end

puts 'file a has load'

# lib/sso/a.rb
module Sso
  module B
    def self.hi
      puts 'hi i am module B'
    end
  end
end

puts 'file b has load'

运行

# rails c
require 'sso' # => true

# 加载sso/a文件
Sso::A.hi # =>
          # file a has load
          # hi i am module A

# 加载sso/b文件
Sso::B.hi # =>
          # file b has load
          # hi i am module B

# 加载sso/c文件
Sso::C.hi # => LoadError: cannot load such file -- sso/c         
No Reply at the moment.
You need to Sign in before reply, if you don't have an account, please Sign up first.