Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Ruby内部插件系统和模块(Rails用作框架)_Ruby On Rails_Ruby - Fatal编程技术网

Ruby on rails Ruby内部插件系统和模块(Rails用作框架)

Ruby on rails Ruby内部插件系统和模块(Rails用作框架),ruby-on-rails,ruby,Ruby On Rails,Ruby,我想创建一个基类,然后加载所有子类(插件),并通过每个循环处理所有子类。这是一个工作示例: require 'set' class Plugin # Keep the plugin list inside a set so we don't double-load plugins @plugins = Set.new def self.plugins @plugins end def self.register_plugins # Iterate ove

我想创建一个基类,然后加载所有子类(插件),并通过
每个
循环处理所有子类。这是一个工作示例:

require 'set'

class Plugin
  # Keep the plugin list inside a set so we don't double-load plugins
  @plugins = Set.new

  def self.plugins
    @plugins
  end

  def self.register_plugins
    # Iterate over each symbol in the object space
    Object.constants.each do |klass|
      # Get the constant from the Kernel using the symbol
      const = Kernel.const_get(klass)
      # Check if the plugin has a super class and if the type is Plugin
      if const.respond_to?(:superclass) and const.superclass == Plugin
        @plugins << const
      end
    end
  end
end

class DogPlugin < Plugin

  def self.handle_command(cmd)
    p "Command received #{cmd}"
  end

end
class CatPlugin < Plugin

  def self.handle_command(cmd)
    p "Command received #{cmd}"
  end

end

Plugin.register_plugins

# Test that we can send a message to each plugin
Plugin.plugins.each do |plugin|
  plugin.handle_command('test')
end
Set
为空,不会执行任何操作。为什么?

请参见此处的实时示例:

网络上还有其他类型的插件示例,但它们必须逐个初始化。此示例代码加载所有插件并在所有插件中执行相同的方法。我需要模块的此功能。

需要“设置”
require 'set'

module A
  class Plugin
    @plugins = Set.new

    def self.plugins
      @plugins
    end

    def self.register_plugins
      # Iterate over each symbol in the object space
      ::A.constants.each do |klass|
        # Get the constant from the Kernel using the symbol
        const = A.const_get(klass)
        puts const
        # Check if the plugin has a super class and if the type is Plugin

        if const.respond_to?(:superclass) && (const.superclass == Plugin)
          @plugins << const
        end
      end
    end
  end
end

module A
  class MyAction < Plugin
    def self.handle_command(cmd)
      puts "Command received #{cmd}"
    end
   end
end

A::Plugin.register_plugins
A::Plugin.plugins.each do |plugin|
  plugin.handle_command('test')
end
模块A 类插件 @plugins=Set.new def self.plugins @插件 结束 def self.register_插件 #迭代对象空间中的每个符号 ::A.常数。每个都有| #使用符号从内核获取常量 常数=A.const_get(klass) 放置常数 #检查插件是否有超类,类型是否为plugin if const.respond_to?(:superclass)&&(const.superclass==插件)
@插件这可能是加载顺序的问题。我们公司所做的是在
config/initializers
中创建一个文件,按照所需的顺序加载文件。在我的示例中,如果我更改顺序,它将失败。我认为样品很好。它与模块有关。因为当同一个例子没有模块
A
的时候,同样的顺序,它是有效的。你知道这是正确的吗?这似乎是一种比使用循环更好的实现方法。使用继承的
Ah。我懂了。我会用这个。谢谢。我很抱歉这么说,但我不太明白。你能根据上面的内容发布一个样本来唤醒我吗/我更新了一个工作版本,你需要加载模块本身的常量。太棒了。非常感谢你!我可以问一个简短的问题吗。我不想为此打开一个新的问题。当使用独立的ruby时,它可以工作,然而,在Rails中,我认为自动加载功能破坏了它。即使我明确要求它,也找不到MyAction(my_action.rb)类。你知道这件事吗?有什么问题吗?(当我使用Plugin将MyAction移动到同一个文件时,它会工作)。
require 'set'

module A
  class Plugin
    @plugins = Set.new

    class << self
      attr_reader :plugins
    end

    def self.register_plugins
      # Iterate over each symbol in the object space
      Object.constants.each do |klass|
        # Get the constant from the Kernel using the symbol
        const = Kernel.const_get(klass)
        # Check if the plugin has a super class and if the type is Plugin
        if const.respond_to?(:superclass) && (const.superclass == A::Plugin)
          @plugins << const
        end
      end
    end
  end
end

module A
  class MyAction < Plugin
    def self.handle_command(cmd)
      puts "Command received #{cmd}"
    end
   end
end

A::Plugin.register_plugins
A::Plugin.plugins.each do |plugin|
  plugin.handle_command('test')
end
require 'set'

module A
  class Plugin
    @plugins = Set.new

    def self.plugins
      @plugins
    end

    def self.register_plugins
      # Iterate over each symbol in the object space
      ::A.constants.each do |klass|
        # Get the constant from the Kernel using the symbol
        const = A.const_get(klass)
        puts const
        # Check if the plugin has a super class and if the type is Plugin

        if const.respond_to?(:superclass) && (const.superclass == Plugin)
          @plugins << const
        end
      end
    end
  end
end

module A
  class MyAction < Plugin
    def self.handle_command(cmd)
      puts "Command received #{cmd}"
    end
   end
end

A::Plugin.register_plugins
A::Plugin.plugins.each do |plugin|
  plugin.handle_command('test')
end