【问题标题】:How can I call a method at the end of every subclass declaration from a superclass?如何在超类的每个子类声明的末尾调用方法?
【发布时间】:2018-01-21 21:19:44
【问题描述】:

编辑 - 更改问题以澄清我需要什么并消除任何混淆

我有一个超类,其中包含需要在每个子类中调用的类方法:

class SuperClass
   def self.super_method
     puts "super method was called"
   end
end

我需要在每个子类的末尾调用这个方法(在定义所有方法之后):

class SubClassA < SuperClass
  def some_method
    puts "some method was called"
  end
  super_method
end

class SubClassB < SuperClass
  def some_other_method
    puts "some method was called"
  end
  super_method
end

但是,我不想在每个子类的末尾手动调用 super_method,就像上面的示例一样。相反,我想找到某种方法在超类的每个子类的末尾自动调用此函数,这与继承的方法类似

class SuperClass
   def self.super_method
     puts "super method was called"
   end

   self.inherited(subclass)
     subclass.super_method
   end 
end

继承不起作用的原因是,一旦子类从超类继承(在“class SubClassA

class SuperClass
   def self.super_method
     puts "super method was called"
   end

   self.methods_loaded(subclass) #not a real built in method, but hopefully something like this exists
     subclass.super_method
   end 
end

如果ruby没有内置这样的方法,那我该如何模拟这个功能呢?

老问题

注意 - 我将保留旧问题的一部分。如果您知道 swift 协议/委托模式,我认为下一部分将有助于明确我需要什么以及为什么。如果您不这样做,请随意忽略此问题。

我正在努力在 ruby​​ 中创建自定义类,以添加类似于 Swift 中的协议/委托模式的模式。我几乎完成了,就目前而言,以下代码可以完成我需要的一切:

class SampleProtocol < Protocol
  required_method :number_of_sections_in
  required_method :number_of_rows_in_section
end

class SampleClass < SwiftClass
  inherit_protocols :SampleProtocol
  def number_of_sections_in; end
  verify_conforms_to_protocols
end

我不会详细介绍它是如何工作的,因为这不是现在的问题,但基本上 SwiftClass 包含上面的两个方法调用; inherit_protocols 和 verify_conforms_to_protocols。如果我要运行上面的代码,它会引发自定义方法缺失错误,因为示例类不包含所需的方法:在 SampleProtocol 中定义的 number_of_rows_in_section。在 verify_conforms_to_protocols 方法中引发错误。

所以基本上,所有这些逻辑都有效。我现在遇到的问题是我不喜欢在每个继承协议的类的末尾调用 verify_conforms_to_protocols 。相反,我正在寻找一种方法让 SwiftClass 的每个子类调用该方法 在 运行该子类的所有其他内部设置代码(即:必须在所有方法之后调用它已定义,否则类将永远不会符合协议。)

我怎样才能做到这一点?

【问题讨论】:

  • 我没有完全遵循,因为我不熟悉这种模式(或 Swift),但听起来使用 prepend 可能会达到你的预期......ruby-doc.org/core-2.0.0/Module.html#method-i-prepend跨度>
  • 是的,模式并不是超级重要,只是我需要在子类中声明所有其他方法之后调用方法 verify_conforms_to_protocol,但我不想手动将其放在每个子类的结尾。当我回到我的电脑上时,我会研究 prepend 看看它是否有效。
  • 一种方法是实现self.method_added(name) 方法,该方法将当前定义的方法与self.methods(false) 或self.instance_methods(false) 中定义的方法列表进行比较。更多信息method_addedstackoverflow.com/questions/48352057/…
  • @JoshBrody 我编辑了这个问题,所以希望我现在需要什么更清楚一点。至于 method_add 和 prepend 都不起作用。 method_add 不起作用,因为需要在定义所有方法之后调用超级方法,而不是添加每个方法。根据我在阅读 prepend 后的理解,它适用于模块,我正在处理类。

标签: ruby inheritance


【解决方案1】:

我不明白你怎么能做你想做的事,而不求助于用丑陋的棍子吹得非常好的东西,就像下面这样。

class SuperClass
  self.singleton_class.send(:attr_accessor, :last_subclass)

  def self.super_method
    puts "super method was called from #{self}"
  end

  def self.inherited(subclass)
    last_subclass.send(:super_method) unless last_subclass.nil?
    self.last_subclass = subclass
  end 
end

class SubClassA < SuperClass
  def some_method
    puts "some method was called"
  end
end

class SubClassB < SuperClass
end
  #super method was called from SubClassA

class SubClassC < SuperClass
end
  #super method was called from SubClassB

class SubClassDummy < SuperClass
end
  #super method was called from SubClassC

请注意,如果您从 IRB 运行此程序,则每次运行时都需要退出并重新启动 IRB。

【讨论】:

    猜你喜欢
    • 2015-07-10
    • 1970-01-01
    • 1970-01-01
    • 2020-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多