Ruby Utility Idiom

I'm working on a class Chartand a parameter marginthat contains the values of :top, :bottom, :rightand :left. My first option was to make a marginsetter and set these values:

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

This is good, because it is clearly a setter, but when I think it over, I think this can also be misleading: the user might think that the fields contain only values :leftand :rightthat is not so. Another option is to exclude =and make it the usual way:

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

Using this syntax is easy to understand what is happening, but it is not a standard network device and conflicts with marginsgetter. And there is another option:

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

I don’t know what to think about it. It’s obvious to me that the method is a setter, but this time I can’t set multiple values ​​with just one call, and the getter problem again. I'm relatively new to Ruby, and I'm not used to all the idioms yet. So what do you guys think? Which of the best options?

+3
source share
5 answers

You can also make the Margin class to use the following clear syntax:

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

class Chart
    attr_accessor :margins
    ...
 end


chart.margins.left = 10
puts chart.margins.right
+5
source

Not sure if this is the syntax you would like to make available (sorry if not :)

#!/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
+3
source

Margins :

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

margins = :

chart.margins = 20

:

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

, Margin - . to_hash - .

Alternatively, if you like, you can make it work in DSL style:

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

But I think that I would choose a paradigmatic approach ...

+2
source

You can also stick with what you had in the first place and use the usual hash syntax.

margins["left"] = 10  #to set just one without changing the others
+1
source

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


All Articles