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

发布于 2024-12-18 13:27:11 字数 1006 浏览 0 评论 0原文

我不确定这个问题的标题是否正确,但我不知道还能怎么问。我有需要全局注册的类,以便稍后调用。除了非常重要的部分之外,我已经完成了大部分工作。当子类继承父类时,它注册了一个新实例,但是当调用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 以便我可以在循环中访问它?

I'm not sure that's the right title for this question, but I don't know how else to ask it. I have classes that need to be registered globally so they can be called later. I have most of it working except for a very important part. When the child inherits from the parent class, it registers a new instance, but when the on_message class method is called, I can't figure out how to set the instance variables that I need.

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

How can I design this so that the @regex will be set so I can access it within the loop?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蓝梦月影 2024-12-25 13:27:11

我终于找到了一个可行的解决方案,并且我现在添加了可执行的整个代码。只需将代码存储在文件 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

I finally found a solution that works, and I have added now the whole code that is executable. Just store the code e.g. in file callexample.rb and call it by ruby callexample.rb

The main difference of my solution to the question is that the call to on_message now creates the instance with the relevant arguments and registers the created instance. Therefore I have deleted the method inherited because I don't need it any more.

I have added some puts statements to demonstrate in which order the code works.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文