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