使属性始终为数组的最佳方法是什么?

时间:2010-03-12 10:06:43

标签: ruby oop tdd

我正在使用我的MOO项目自学测试驱动设计,它带给我有趣的地方。例如,我写了一个测试,说特定对象的属性应该总是返回一个数组,所以 -

t = Thing.new("test")
p t.names  #-> ["test"]

t.names = nil
p t.names #-> []

我对此的代码没问题,但对我来说这似乎并不太可靠:

class Thing

   def initialize(names)
      self.names = names
   end

   def names=(n)
      n = [] if n.nil?
      n = [n] unless n.instance_of?(Array)

      @names = n
   end

   attr_reader :names
end

有没有更优雅,Ruby-ish这样做的方式?
(注意:如果有人想告诉我为什么这是一个愚蠢的测试,那也很有趣......)

5 个答案:

答案 0 :(得分:5)

我想指出已经有一种内置方法可以做你想要的!它被称为Array()。问自己的问题是:可转换为数组的类会发生什么变化(如0..42)?

我觉得大多数Rubyist都会期望他们会被转换。所以:

class Thing
  attr_accessor :names

  def initialize(names)
    self.names = names
  end

  def names=(values)
    @names = Array(values)
  end
end

您将获得相同的结果,例如:

t = Thing.new("car")
t.names  #-> ["car"]

t.names = nil
t.names  #-> []

t.names = 42
t.names  #-> [42]

t.names = [1, 2, 3]
t.names #-> [1, 2, 3]

t.names = 1..3
t.names #-> [1, 2, 3]  # Is this what you want, or not?

答案 1 :(得分:3)

试试这个:

class Thing

   def initialize(names)
      self.names = names
   end

   def names=(n)
     @names= [*(n||[])]
   end

   attr_reader :names
end

让我们测试一下课程:

t = Thing.new("car")
t.names  #-> ["test"]

t.names = nil
t.names  #-> []

t.names = [1, 2, 3]
t.names #-> [1, 2, 3]

答案 2 :(得分:2)

您可以使用getter方法格式化值。

class Thing

  def initialize(names)
    self.names = names
  end

  def names
    [*@names].compact
  end

  def names=(values)
    @names = values
  end

end

t = Thing.new("test")
p t.names  #-> ["test"]

t.names = nil
p t.names #-> []

答案 3 :(得分:1)

其他气味就像我以前的答案一样:


class Thing
  def initialize(*names)                                                                                                                                                                                                                                                      
    @names = names
  end 
  def names
    @names || []
  end 
  def names=(*names)
    @names = names
  end 
end

t = Thing.new("test")
p t.names  #-> ["test"]

t.names = nil 
p t.names #-> []

答案 4 :(得分:0)

使用*在初始化方法

中获取数组中的所有参数

class Thing
   attr_accessor :names

   def initialize(*names)
      @names = names
   end
end

t = Thing.new("test")
p t.names  #-> ["test"]

t.names = nil
p t.names #-> nil