【问题标题】:Can I control what an array of custom objects looks like in Ruby?我可以控制自定义对象数组在 Ruby 中的样子吗?
【发布时间】:2017-11-02 23:18:16
【问题描述】:

我有一个名为 Thing 的自定义类和一个 Thing 对象数组,如下所示:

class Thing
  attr_accessor :name

  def initialize(name)
    @name = name
  end

  def to_s
    @name
  end
end

a = []
a << Thing.new("Fred")
a << Thing.new("George")
a << Thing.new("Steve")
a

当我查看 irb 中的数组时,我希望它看起来像这样:

[Fred, George, Steve]

而不是这个(对象信息): [#, #, #]

换句话说,当我用 irb 查看数组时,我希望能够看到数组中每个元素的 to_s 值。有没有办法做到这一点?

【问题讨论】:

  • 这个a.map{|o|o.name} #=&gt; ["Fred", "George", "Steve"]a.map(&amp;:name) #=&gt; ["Fred", "George", "Steve"] 怎么样?
  • 如果你想要一个类的所有实例,你可以写ObjectSpace.each_object(Thing).map(&amp;:name) #=&gt; ["Fred", "George", "Steve"]。有关详细信息,请参阅here

标签: arrays ruby


【解决方案1】:

您可能希望覆盖 #inspect 以获得对象的可读版本:

class Thing
  attr_accessor :name

  def initialize(name)
    @name = name
  end

  def inspect
    @name
  end
end

a = []
a << Thing.new("Fred")
a << Thing.new("George")
a << Thing.new("Steve")
a

=> [Fred, George, Steve]

【讨论】:

  • 这正是我想要的。谢谢!
【解决方案2】:

就其价值而言,irb 通常不是代码的接口,因此最好不要过多地迎合对象在狭窄上下文中的表示方式。

您可以按照 Adam Sheehan 的建议覆盖 inspect。这将适用于Thing 的任何实例,根据您的应用程序的其余部分,这可能是可取的或不可取的。

如果您只希望此特定对象集合的这种表示形式,另一种选择是定义自定义集合:

class Things < Array
  def inspect
    "[#{ map(&:name).join(', ') }]"
  end
end

a = Things.new
a << Thing.new("Fred")
a << Thing.new("George")
a << Thing.new("Steve")
a

您还可以将您的 Array 转换为 Things 的实例:

a = []
a = Things.new(a)

这实际上是一个Decorator

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-22
    • 2017-05-12
    • 2015-03-11
    • 1970-01-01
    • 1970-01-01
    • 2019-01-08
    相关资源
    最近更新 更多