Domanda

Sto lavorando su una classe Chart e ha un parametro margin , che contiene : top , : bottom , : right e : left . La mia prima opzione era di rendere margin un setter e impostare valori come questo:

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

È bello, perché è chiaramente un setter, ma, dopo qualche pensiero, penso che potrebbe anche essere fonte di confusione: l'utente potrebbe pensare che i margini contengano solo : left e : right , cosa non è giusto. Un'altra opzione è eliminare = e renderlo un metodo normale:

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

Con questa sintassi, è facile capire cosa sta succedendo, ma non è un setter standard e è in conflitto con il getter margini . E c'è ancora un'altra opzione:

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

Non so cosa pensare al riguardo. Per me, è ovvio che il metodo è un setter, ma questa volta non posso impostare più valori con una sola chiamata e c'è di nuovo il problema con getter. Sono relativamente nuovo con Ruby e non mi sono ancora abituato a tutti i modi di dire. Quindi, cosa ne pensate ragazzi? Qual è l'opzione migliore?

È stato utile?

Soluzione

Puoi anche creare una classe Margin per godere della seguente sintassi chiara:

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

class Chart
    attr_accessor :margins
    ...
 end


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

Altri suggerimenti

Non sono sicuro se questo è il tipo di sintassi che vorresti rendere disponibile (scusa se no:)

#!/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

Oltre alla risposta di paradigmatic, è possibile aggiungere un metodo alla classe Margins per supportare:

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

È possibile estendere il metodo margins = per trattare un argomento numerico:

chart.margins = 20

come zucchero per:

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

Non penso che creare una classe per Margin sia eccessivo. Puoi sempre esporre i suoi valori come hash usando to_hash o qualcosa di simile.

Inoltre, se vuoi, puoi farlo funzionare in stile DSL:

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

Ma credo che sceglierei comunque l'approccio paradigmatico ...

Potresti anche attenerti a ciò che avevi prima e usare la normale sintassi hash.

margins["left"] = 10  #to set just one without changing the others
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top