使用动态加载的ruby文件避免全局变量

时间:2011-11-18 16:55:11

标签: ruby plugins dependency-injection global-variables

我现在处于一个位置,我有一个插件文件夹,其中可能有1或100个插件要加载。

现在的问题是,每个插件都需要在启动ruby文件中定义的类的实例。

一个非常简单的例子是:

#startup.rb

def load_plugins
    #... get each plugin file
    require each_plugin
end

class MuchUsedClass
    def do_something
        #...
    end
end

muchUsedInstance = MuchUsedClass.new
load_plugins

#some_plugin.rb

class SomePluginClass
    def initialize(muchUsedInstance)
        @muchUsedInstance = muchUsedInstance
    end

    def do_something_with_instance
        @muchUsedInstance.do_something
    end
end

somePluginInstance = SomePluginClass.new(muchUsedInstance)
somePluginInstance.do_something_with_instance

主要问题是当你打电话给需要时,它没有任何关于在被要求之前发生了什么的线索。所以我觉得在启动文件中创建一个全局变量只是为了满足所有其他所需文件是令人讨厌的,但它似乎是能够将一些数据传递给包含文件的唯一方法之一,我也可以创建一个单例类揭露其中一些,但这似乎有点讨厌。

由于我还不熟悉ruby并且仍然在浏览静态类型的眼镜,我可能会错过一个合适的模式来解决这个问题,在C#中我会选择依赖注入并且只是将这一切挂钩...

1 个答案:

答案 0 :(得分:2)

您的示例代码没有全局变量。全局变量的名称以$开头。你写的代码不起作用,因为muchUsedInstance只是一个局部变量,不会在不同的Ruby文件之间共享。

如果您不打算更改实例,可以轻松地将其存储为常量:

MuchUsedInstance = MuchUsedClass.new

您可以将其存储为类中的嵌套常量:

MuchUsedClass::Instance = MuchUsedClass.new

您可以将它作为实例变量存储在类对象中,并使用getter方法自动创建它(如果它不存在的话):

def MuchUsedClass.instance
  @instance ||= MuchUsedClass.new
end