在Ruby中继承时的订单方法

时间:2014-10-19 03:39:46

标签: ruby inheritance

使用类继承时,有没有办法订购方法?我希望它们被排序,因为我继承自一个按顺序执行所有公共方法的类。

例如:

class Foo
  def action_two
    puts "action 2"
  end
end

class Bar < Foo
  def action_one
    puts "action 1"
  end
end

Bar.instance_methods # => [:action_two, :action_one, ...]

...我希望它返回[:action_one, :action_two, ...]

3 个答案:

答案 0 :(得分:2)

documentation没有说明订单,我实际上在使用Ruby 2.1.2时按照你想要的顺序得到它们。如果你想让它们以特定的顺序出现,那么我认为你必须自己做。您可以使用include_super参数instance_methods来获取当前类的方法,然后向superclass询问其方法:

class Bar < Foo
  #...
  def self.instance_methods
    super(false) + superclass.instance_methods
  end
end

如果您打算将BasicObject作为可能的超类处理,那么您需要在调用superclass.nil?之前添加superclass.instance_methods检查。

如果您的继承层次结构很深,那么您应该能够将此hackery放入最低的基类(在这种情况下为Foo)并让子类通过继承来获取它。

答案 1 :(得分:1)

为了做到这一点,您必须在将Bar#action_one继承到Foo之前定义Bar。由于类继承是在继承的类的创建时确定的,因此不能按原样执行。

解决此问题的一种方法是将Foo作为一个模块而不是一个类,并在定义Bar后将其包含在Bar#action_one中。

module Foo
  def action_two
    puts "action 2"
  end
end

class Bar
  def action_one
    puts "action 1"
  end
  include Foo
end

Bar.instance_methods
# => [:action_one, :action_two, ...]

答案 2 :(得分:-1)

Bar.ancestors.each_with_object([]) { |a, o| o << a.instance_methods }.flatten.uniq