Question

Je travaille sur une classe Chart qui comporte un paramètre margin , qui contient : top , : bottom , : droit et : gauche . Ma première option a été de faire de margin un setter et de définir des valeurs telles que:

# Sets :left and :right margins and doesn't alter :top and :bottom 
chart.margins = {:left => 10, :right => 15}

C'est bien, parce que c'est clairement un configurateur, mais, après réflexion, je pense que cela pourrait être déroutant aussi: l'utilisateur pourrait penser que les marges ne contiennent que : left et : right valeurs, ce qui n'est pas correct. Une autre option est d’éliminer = et d’en faire une méthode ordinaire:

chart.margins(:left => 10, :right => 15)

Avec cette syntaxe, il est facile de comprendre ce qui se passe, mais ce n'est pas un outil de définition standard qui entre en conflit avec marges getter. Et il y a encore une autre option:

chart.margins(:left, 10)
chart.margins(:right, 15)

Je ne sais pas quoi penser à ce sujet. Pour moi, il est évident que la méthode est un setter, mais cette fois, je ne peux pas définir plusieurs valeurs avec un seul appel et le problème avec getter est à nouveau problématique. Je suis relativement nouveau chez Ruby et je ne suis pas encore habitué à tous les idiomes. Alors, qu'en pensez-vous les gars? Quelle est la meilleure option?

Était-ce utile?

La solution

Vous pouvez également créer une classe Margin afin de profiter de la syntaxe claire suivante:

class Margin
    attr_accessor :left, :right, :top, :bottom
    ...
end

class Chart
    attr_accessor :margins
    ...
 end


chart.margins.left = 10
puts chart.margins.right

Autres conseils

Vous n'êtes pas sûr de savoir si c'est le type de syntaxe que vous souhaitez rendre disponible (désolé si ce n'est pas le cas)

#!/usr/bin/ruby
class Margins < Struct.new(:top, :bottom, :left, :right) 
end

class Chart
  attr_reader :margins

  def initialize()
    @margins = Margins.new(0,0,0,0)
  end

  def margins=(hash)
    [:top, :bottom, :left, :right].each do |dir|
      if (hash[dir])
        @margins[dir] = hash[dir]
      end
    end
  end
end

c = Chart.new
c.margins.left = 10
c.margins={:top=>12,:bottom=>13}
puts c.margins.left
# 10
puts c.inspect;
# #<Chart:0xb7caaf8c @margins=#<struct Margins top=12, bottom=13, left=10, right=0>>

# However c.margins.foo = 12 would give you an error

En plus de la réponse de paradigmatic, vous pouvez ajouter une méthode à la classe Margins pour prendre en charge:

chart.margins.set :left => 10, :right => 15

Vous pouvez étendre la méthode margins = pour traiter un argument numérique:

chart.margins = 20

en sucre pour:

chart.margins = Margins.new(20, 20, 20, 20)

Je ne pense pas que créer une classe pour Margin soit une exagération. Vous pouvez toujours exposer ses valeurs sous forme de hachage à l'aide de to_hash ou quelque chose de similaire.

En outre, si vous le souhaitez, vous pouvez le faire fonctionner à la manière de DSL:

chart.margins do |m|
  m.left 10
  m.right 20
  m.vertical 5 # sets both top and bottom margin
end

Mais je suppose que je choisirais quand même l'approche de paradigmatic ...

Vous pouvez également vous en tenir à ce que vous aviez auparavant et utiliser la syntaxe de hachage normale.

margins["left"] = 10  #to set just one without changing the others
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top