2011-11-28 80 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