从 Ruby 中的继承类调用方法

Posted

技术标签:

【中文标题】从 Ruby 中的继承类调用方法【英文标题】:Calling Methods from Inherited Class in Ruby 【发布时间】:2020-07-13 22:19:13 【问题描述】:

我有以下课程:

模块

module AlertService
    module MessageTemplate
      def generate_message
        "test"
      end
    end
  end

父类:

module Client
  def post uri, params=
    Net::HTTP.post_form uri, params
  end
end

module AlertService
  class BaseAlert
    extend MessageTemplate
    include Singleton
    include Client
    def initialize; end
  end
end

儿童班:

module AlertService
class TestAlert < BaseAlert
  include Singleton
  def initialize
  options = 
    username: "Screen Alert Bot",
    http_client: Client
  
  @notifier = Slack::Notifier.new(rails.config.url, options)
  end

  def self.create_message
    message = generate_message
  end

  def self.send_message
    create_message
    @notifier.post blocks: message
  end
end
end

我可以像这样创建测试警报:s= AlertService::TestAlert

但是当我这样做时出现错误:

s.send_message

NoMethodError: undefined method `generate_message' for AlertService::TestAlert::Class

generate_message 是 BaseAlert 类中包含的 MessageTemplate 模块中的一种方法。为什么说我继承的类无权访问该方法?

【问题讨论】:

什么是generate_message?它没有在您的代码中列出。 @tadman 这是来自 MessageTemplate 模块的方法 【参考方案1】:

您没有正确使用Singleton。您包含它,但随后不使用它,而是完全绕过它并调用与 Singleton 无关的类方法。它们依次调用父类上不存在的类方法。

解决方案是按预期使用Singleton

module AlertService
  class BaseAlert
    include MessageTemplate
    include Singleton

    def initialize
    end
  end
end

module AlertService
  class TestAlert < BaseAlert
    def initialize
      @notifier = Slack::Notifier.new(Rails.configuration.url, Rails.configuration.options)
    end

    def create_message
      message = generate_message
    end

    def send_message
      create_message
      @notifier.post blocks: message
    end
  end
end

你现在在哪里call with instance as documented:

AlertService::TestAlert.instance.send_message

【讨论】:

该格式有意义。我仍然收到方法错误,generate_message NoMethodError: undefined method `generate_section_description'。这是模块中的一个方法,我不知道为什么我不能调用它 你确定是实例方法而不是类方法?此外,如果您在BaseAlert 中需要它,请将include 移动到该类中。我在这里更新了代码。 我会仔细检查我的代码,我还在示例中包含了模块 先检查方法是否真的存在,比如AlertService::TestAlert.instance_methods 哦,我使用的是扩展而不是包含!谢谢!还有一个问题,您是否以正确的方式引用 Client 模块? (我更新了代码以供参考)这是启动通知程序的一个选项,但该类看起来不像它识别模块

以上是关于从 Ruby 中的继承类调用方法的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法从 Ruby 中的实例调用私有类方法?

Ruby:从实例调用类方法

从 Ruby 中的模块/mixins 继承类方法

如何从 Ruby 中的实例方法访问受保护的类方法?

android其他类怎么调用继承自activity的类(mainactivity)中的非静态方法?

如何运行一个ruby类 中的方法