我可以在 Ruby 中的模块内部使用模块吗?

Can I used a module inside of a module in Ruby?

我是 Ruby 的新手。我对在这里阅读的一些代码感到困惑:

http://hawkins.io/2012/03/defining_plugins_gems_railties_and_engines/

这是代码:

module Cashier
  class Railtie < ::Rails::Railtie
    config.cashier = Cashier

    initializer "cashier.active_support.cache.instrumentation"
      ActiveSupport::Cache::Store.instrument = true
    end
  end
end

我对这行感到惊讶,这在大多数语言中是不允许的:

    config.cashier = Cashier

所以我在 Cashier 模块的定义中,但我也可以实例化 Cashier 模块的实例并在这里使用它?这条线上发生了什么?当我在定义 Cashier 的代码中时,如何分配 Cashier?在 Java 中,我认为我从未在 class 的定义中实例化过 class。

您没有在此处实例化 Cashier(您无法在 Ruby 中创建模块实例);你只是在引用 Cashier 常量,它指的是 Module 的一个实例,当你到达这一行时它已经定义好了。

Ruby 创建一个空的 Module 实例,并根据 module Foo 将其分配给 Foo 常量。模块主体定义可以看作是重新打开空模块并向其添加附加功能。 Ruby 不需要完整的模块定义即可 "finalize" 一个模块并将其分配给一个常量;它是在考虑主体定义之前创建和分配的。

即代码:

 module Foo
   puts Foo.object_id
 end

在功能上等同于:

# Create a new Module instance and assign it to the Foo constant
Foo = Module.new

# Reopen the Module instance assigned to the constant Foo for modification
module Foo
  # Do stuff in here to add functionality to the Foo module
  # Since Foo is already defined, we can get its object_id.
  puts Foo.object_id
end

从编译语言的角度来看,这当然没有意义(毕竟,如果你还没有完成它的定义,你怎么知道 Cashier 是什么?),但是 Ruby 的解释性质意味着它倾向于更宽松地对待模块和 class 定义之类的东西,这就是允许这种行为的原因。