在初始化中计算实例变量的最简洁方法是什么?

时间:2013-05-03 23:40:21

标签: ruby coding-style

假设我有一个课程,定义了我的日子的集合以及它们是多么古怪。在初始化函数中初始化@scores变量是否更好,如下所示:

class WackyDayScorer
  attr_reader :scores
  def initialize(start = Time.now, max = 90.days)
    @start  = start
    @limit  = start - max
    @scores = get_scores
  end

private
  def get_scores
    result = []
    t = @start.clone
    until t < max
      result << score_wackiness(t)
      t -= 1.day
    end
    result
  end
end

或在get_scores方法中初始化它,如下所示:

class WackyDayScorer
  attr_reader :scores

  def initialize(start = Time.now, max = 90.days)
    @start = start
    @limit = start - max
    get_scores
  end

private
  def get_scores
    @scores = []
    t = @start.clone
    until t < max
      @scores << score_wackiness(t)
      t -= 1.day
    end
  end
end

3 个答案:

答案 0 :(得分:0)

第一个是完全错误的。你在说

@scores = get_scores

但是get_scores没有返回有用的值,所以这很疯狂。相反,get_scores@scores直接和内部设置为副作用。

第二个至少是连贯的。

但就个人而言,我不会所做的 。我会说第一次你说的话:

@scores = get_scores

但我对get_scores的实施不会触及任何ivar。它将返回一个实际值:

  def get_scores
    scores = []
    # do stuff to scores
    return scores # or simply, scores
  end

答案 1 :(得分:0)

如果要在初始化中处理某些内容,请创建一个私有方法来处理计算,然后在#initialize中设置实例变量。我不会在方法中设置它,以防你想在类中的其他地方重用该计算而不会消灭你的实例变量。

class WackyDayScorer
  attr_accessor :scores

  def initialize(start = DateTime.now, max = 90.days)
    @start = start
    @limit = start - max
    @scores = calculate_scores
  end

private

  def calculate_scores
    (@limit..@start).to_a.map { |date_time| score_wackiness(date_time) }
  end
end

在#calculate_scores中,我们在限制日期和开始之间创建一个范围(向后计数,正如您所做的那样)并将每个结果发送到#score_wackiness方法。

答案 2 :(得分:0)

我建议明确定义分数的getter,记住计算并跳过所有仪式:

class WackyDayScorer
  def initialize(start = Time.now, max = 90.days)
    @start  = start
    @limit  = start - max
  end

  def scores
    @scores ||= begin
      result = []
      t = @start.clone
      until t < max
        result << score_wackiness(t)
        t -= 1.day
      end
      result
    end
  end
end

这基本上就是你在做什么,但它更直接。