Ruby:如何从类方法设置实例变量?

时间:2011-11-28 05:06:39

标签: ruby inheritance subclass instance-variables

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

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以便我可以在循环中访问它?

1 个答案:

答案 0 :(得分: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