【问题标题】:Ruby - Reference subclass in class methodRuby - 类方法中的引用子类
【发布时间】:2015-10-26 23:49:14
【问题描述】:

不确定 Ruby 是否可以做到这一点,但我正在尝试编写一个包含多个方法的类,这些方法将由多个子类共享。这个超类将包含我希望子类继承的类和实例方法。假设我永远不会直接使用超类,我只是用它来抽象出重复的方法(思考 DRY)。这涉及到常量(API URI)会随着子类的变化而变化。

这是我正在尝试做的一个示例:

class Foo
  attr_accessor :param
  def initialize(param)
    @param = param
  end
  def self.get
    <SubClass>.new(self::MY_CONSTANT)
  end
end

class Bar < Foo
  MY_CONSTANT = 'Woot'
end

class Baz < Foo
  MY_CONSTANT = 'Pew Pew'
end

我想要的行为是这样的:

Bar.get
puts Bar.param # => Woot
Baz.get
puts baz.param # => Pew Pew

这可能吗?我是不是完全错误地处理了这个问题?

更新

根据@Nathan,self.get 方法中的self.new 在这里起到了作用。

[39] pry(main)> test = Bar.get
=> #<Bar:0x000001072ecc20 @param="Woot">
[40] pry(main)> test.param
=> "Woot"
[41] pry(main)> test
=> #<Bar:0x000001072ecc20 @param="Woot">
[42] pry(main)> test.class
=> Bar
[43] pry(main)> test2 = Baz.get
=> #<Baz:0x000001071b5528 @param="Pew Pew">
[44] pry(main)> test2.class
=> Baz
[45] pry(main)> test2.param
=> "Pew Pew"

【问题讨论】:

  • 您可能会发现对代码 puts 语句进行加盐会很有帮助,这些语句会为您提供 self 的值。例如,class Klass; def my_method; puts "self in #{__method__} = #{self}"; end; end; Klass.new.my_method #=&gt; self in my_method = #&lt;Klass:0x007fbd4987fdd0&gt;

标签: ruby class inheritance


【解决方案1】:

使用self

Foo.get 内部,self 是您在其上调用get 的类,当您执行Bar.getBaz.get 时,这将分别是BarBaz

因此,如果您有&lt;SubClass&gt;,只需输入self,一切都会如您所愿。

def self.get
  self.new(self::MY_CONSTANT)
end

您也可以省略 self,因为这是 Ruby 在未指定显式对象时自动使用的。

def self.get
  new(self::MY_CONSTANT)
end

另外,在您测试值的代码中,我认为您的意图是:

bar = Bar.get
puts bar.param # => Woot
baz = Baz.get
puts baz.param # => Pew Pew

最后,至于这是否是最好的方法,那是基于意见的,但我觉得奇怪的是,当它已经作为常量可用时,你试图将值传递给 initialize。换句话说,如果您有一个方法需要使用 API URI,只需直接引用该常量,而不是使用 @param 初始化实例本身。您可以像这样在实例方法中引用常量:self.class::MY_CONSTANT

【讨论】:

  • 太棒了,谢谢!出于某种原因,我认为self 将是对BarBaz 的当前实例的引用,因此它会尝试针对现有实例调用.new。感谢您的快速回答!
  • 哦!至于您的最后评论,谢谢您的建议。在我的真实代码中,我直接在休息客户端调用中使用常量,而不是将其分配给实例变量。似乎是一种显示所需行为的快速方法,但它并不完整。好收获!
猜你喜欢
  • 1970-01-01
  • 2015-03-03
  • 1970-01-01
  • 2015-04-04
  • 2014-08-24
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 2015-04-23
相关资源
最近更新 更多