Ruby setter成语

时间:2009-11-30 12:25:02

标签: ruby idioms setter

我正在使用Chart课程,它有一个margin参数,其中包含:top:bottom:right和{{1} }值。我的第一个选择是让:left成为一个setter并设置如下值:

margin

这很好,因为它显然是一个制定者,但经过一番思考后,我认为它也可能令人困惑:用户可能认为边距仅包含# Sets :left and :right margins and doesn't alter :top and :bottom chart.margins = {:left => 10, :right => 15} :left值,是什么不对。另一种选择是消除:right并使其成为普通方法:

=

使用这种语法,很容易弄清楚发生了什么,但它不是标准的setter并且与chart.margins(:left => 10, :right => 15) getter冲突。而且还有另一种选择:

margins

我不知道该怎么想。对我来说,很明显这个方法是一个setter,但这次我不能只用一次调用设置多个值,而getter又有问题。我对Ruby比较陌生,我还没有习惯所有的习语。所以,你觉得男人们怎么样?哪个是最佳选择?

5 个答案:

答案 0 :(得分:5)

您还可以使Margin类享受以下清晰语法:

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

class Chart
    attr_accessor :margins
    ...
 end


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

答案 1 :(得分:3)

不确定这是否是您希望提供的语法(如果不是,请抱歉:)

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

答案 2 :(得分:2)

除了范例的答案,你可以在Margins类中添加一个方法来支持:

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

您可以扩展marginins =方法来处理数字参数:

chart.margins = 20

作为糖:

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

答案 3 :(得分:2)

我认为为Margin创建一个类是不合理的。您始终可以使用to_hash或类似的东西将其值公开为哈希值。

此外,如果您愿意,可以使其以DSL风格运行:

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

但我想我会选择范式的方法......

答案 4 :(得分:1)

你也可以坚持使用你的第一个并使用正常的哈希语法。

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