Best way to make an attribute always an array?

I use my MOO project to teach myself Test Driven Design, and it takes me to interesting places. For example, I wrote a test that says that an attribute on a particular object should always return an array, so -

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

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

The code I have for this is fine, but it doesn’t seem terribly ruby ​​to me:

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

Is there a more elegant, Ruby-ish way to do this?
(NB: if someone wants to tell me why this is a dumb test for writing, that would be interesting too ...)

+3
source share
5 answers

, , , ! Array(). , , - : , (, 0..42)?

, , . :

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?
+5

:

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]
+3

You can use the getter method to format the value.

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 #-> []
+2
source

In a different smell, as in my previous answers:


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 #-> []
+1
source

Use * to retrieve all parameters in an array in your initialization method


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

0
source

Source: https://habr.com/ru/post/1736629/


All Articles