📜  Ruby 中的自动加载方法

📅  最后修改于: 2022-05-13 01:54:57.501000             🧑  作者: Mango

Ruby 中的自动加载方法

Ruby 有一个内置的模块自动加载功能,每当从父级或调用类或模块访问或调用特定模块或类时,它就会起作用。该模块收到调用后,将相应的文件路径注册到被调用模块。这是在第一次调用指定模块时执行的。这是延迟加载机制的一个实例,其中该模块仅在显式调用和调用模块时加载。

句法:

autoload(mod-ch,'file-name.rb')

这里, mod-ch是要调用的模块/类, file-name.rb 是要调用的文件路径。

以下示例说明了自动加载方法的使用:

示例 1:



文件名:f1.rb

Ruby
# Parent module
module A
    
  # First argument loads the module
  # B from the file f2.rb specified
  # in second argument
  autoload(:B, './f2.rb')
    
  # Prints the string before the
  # module B is loaded
  puts "Module B has not been loaded"
    
  # Explicitly calling the module B
  B
    
  # Prints the string after the
  # module B is loaded
  puts "Module B has been loaded"
    
# Module ends
end


Ruby
# Child module
module B
    
  # Prints the string when the module 
  puts 'Module B has started loading'
    
end


Ruby
# Parent module
module P
    
  # autoload method called
  autoload(:C, './c.rb')
    
  # Check if the module is 
  # registered in the namespace 
  p autoload?(:C)
    
  # Making explicit call to module C 
  C
    
  # Now checking if module C is loaded 
  p autoload?(:C) 
    
end


Ruby
# Child module
module C
    
 puts 'In progress'
    
end


Ruby
module A
    
  # Loading module C 
  autoload(:C, './c.rb')
    
  # Accessing the constants 
  # of the module
  p constants
    
end


Ruby
# Child module
module C
end


文件名:f2.rb

红宝石

# Child module
module B
    
  # Prints the string when the module 
  puts 'Module B has started loading'
    
end

执行文件 f1.rb 后,以下代码生成此输出:

Module B has not been loaded
Module B has started loading
Module B has been loaded

示例 2:

文件名:p.rb

红宝石

# Parent module
module P
    
  # autoload method called
  autoload(:C, './c.rb')
    
  # Check if the module is 
  # registered in the namespace 
  p autoload?(:C)
    
  # Making explicit call to module C 
  C
    
  # Now checking if module C is loaded 
  p autoload?(:C) 
    
end

文件名:c.rb

红宝石

# Child module
module C
    
 puts 'In progress'
    
end

执行文件 p.rb 后,以下代码会产生此输出:

'./c.rb'
In progress
nil

说明:在上面的例子中,当没有对模块进行显式调用时,自动加载方法返回包含该模块的文件的文件路径。在调用模块时,会打印模块的内容,这是一个字符串“In progress in this case”。加载模块后,第二次调用 autoload函数返回值 nil,因为模块 C 已经加载。



自动加载模块的工作:

在内部,自动加载方法将常量值与加载的文件名相关联。然后通过指定路径的文件名引用该常量。对此方法的调用标记了创建的常量具有未定义的值。

文件名:p.rb

红宝石

module A
    
  # Loading module C 
  autoload(:C, './c.rb')
    
  # Accessing the constants 
  # of the module
  p constants
    
end

文件名:c.rb

红宝石

# Child module
module C
end

执行文件 p.rb 后,以下代码会产生此输出:

[:C]

在这里,即使没有对模块进行显式调用,也会自动创建常量。创建的常量与模块同名。

自动加载方法的使用

  • 自动加载模块确保指定的模块或类是否已加载并存在于命名空间中。
  • 根据程序流的执行,调用模块。
  • 它还验证子模块或被调用模块是否已在程序执行流程中注册。