Ruby: Как установить переменные экземпляра из метода класса? - PullRequest
3 голосов
/ 28 ноября 2011

Я не уверен, что это правильный заголовок для этого вопроса, но я не знаю, как еще его задать.У меня есть классы, которые должны быть зарегистрированы во всем мире, чтобы они могли быть вызваны позже.У меня есть большая часть работы, за исключением очень важной части.Когда дочерний объект наследует от родительского класса, он регистрирует новый экземпляр, но когда вызывается метод класса 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 голосов
/ 29 ноября 2011

Я наконец нашел решение, которое работает, и теперь я добавил весь исполняемый код.Просто сохраните код, например, в файле 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
...