2015-04-05 121 views
0

我是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 

所以我在模块收银员的定义里面,但我也得到实例化模块收银员的一个实例,并在这里使用它?这一行发生了什么?当我在代码中定义收银员的位置时,我怎样才能指定收银员?在Java中,我认为我没有在类的定义中实例化一个类。

回答

1

您还没有实例收银员在这里(你不能在Ruby中创建模块的情况下,无论如何);你只是引用了Cashier常量,它指的是Module的一个实例,当你到达这条线时已经定义了这个实例。

红宝石创建一个空的模块实例,并将其分配给凭借module Foo的富恒定。模块主体定义可以被视为重新打开空模块并向其添加附加功能。 Ruby不需要完整的模块定义来“完成”一个模块并将其分配给一个常量;它是在甚至考虑到主体定义之前创建和分配的。

也就是说,代码:

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的解释性意味着它倾向于将模块和类的定义稍微松散一些,这就是允许这种行为的原因。

+1

这不是在编译语言既空前,几乎所有的现代语言让函数名函数体内已经定义:在'C','无效无限(无效){无限(); }'不会抛出编译错误。 :) – Amadan 2015-04-06 04:41:24

相关问题