2011-11-28 84 views
3

我不确定这是这个问题的正确标题,但我不知道还有什么要问的。我有需要全局注册的类,以便稍后调用它们。除了非常重要的部分,我大部分工作。当孩子继承父类时,它会注册一个新实例,但是当调用类方法时,我无法弄清楚如何设置我需要的实例变量。Ruby:如何从类方法设置实例变量?

class MyExtension < ExtensionBase 

    on_message '/join (.+)' do |username| 
    # this will be a callback function used later 
    end 

end 

class ExtensionBase 

    def self.inherited(child) 
    MainAppModule.registered_extensions << child.new 
    end 

    def self.on_message(string, &block) 
    # these need to be set on child instance 
    @regex = Regexp.new(string) 
    @on_message_callback = block 
    end 

    def exec(message) 
    args = @regex.match(message).captures 
    @on_message_callback.call(args) 
    end 

end 

# somewhere else in the code, I find the class that I need... 

MainAppModule.registered_extensions.each do |child| 
    puts child.regex.inspect # this is nil and I dont want it to be 
    if message =~ child.regex 
     return child.exec(message) 
    end 
end 

我该如何设计这样才能设置@regex以便我可以在循环内访问它?

回答

0

我终于找到了一个可行的解决方案,现在我添加了可执行的整个代码。只需存储代码在文件callexample.rb并调用它通过ruby callexample.rb

我解决这个问题的主要区别在于调用on_message现在创建与相关参数的实例并注册创建的实例。因此我删除了方法inherited,因为我不再需要它了。

我已经添加了一些puts声明来演示代码的工作顺序。

class MainAppModule        ## Added class 
    @@registered_extensions = [] 
    def self.registered_extensions; @@registered_extensions; end 
end 

class ExtensionBase 
    attr_reader :regex 

    def self.on_message(string, &block) 
    MainAppModule.registered_extensions << self.new(string, block) 
    end 

    def initialize(string, block) 
    @regex = Regexp.new(string) 
    @on_message_callback = block 
    end 

    def exec(message) 
    args = @regex.match(message).captures 
    @on_message_callback.call(args) 
    end 
end 

class MyExtension < ExtensionBase 

    on_message '/join (.+)' do |username| 
    # this will be a callback function used later 
    puts "Callback of #{self} called." 
    "returnvalue" 
    end 
end 

# somewhere else in the code, I find the class that I need... 
MainAppModule.registered_extensions.each do |child| 
    puts "Value of regex: #{child.regex}" # this is no more nil 
    message = '/join something' 
    if message =~ child.regex 
     puts "On match evalue 'child.exec(message)' to: #{child.exec(message)}" 
    end 
end