ruby方法 - 如何减少方法中params的数量?

时间:2013-10-15 03:35:40

标签: ruby optimization parameters

我知道更少的params更好,超过2(或3或4,取决于文献)是代码气味。

如果我有使用params的代码,例如以下内容:

class DoubleSeries
  def self.generate_sequences(seq1_start, seq2_start, seq1_step, seq2_step, iterations)
    seq1,seq2=seq1_start,seq2_start
    result=[]
    (1..iterations).each do
      result << seq1 << seq2
      seq1+=seq1_step
      seq2+=seq2_step
    end
    result
  end
end

当它们全部提供函数时,如何从5减少参数的数量?

2 个答案:

答案 0 :(得分:6)

我想如果你想严格遵守Sandi Metz rules,那么OOP方式就是你要走的路。

class Sequence
  attr_reader :start, :step

  initialize(start, step)
    @start = start
    @step = step
  end
end

sequence_1 = Sequence.new(seq1_start, seq1_step)
sequence_2 = Sequence.new(seq2_start, seq2_step)

class DoubleSeries
  def self.generate_sequences(sequence_1, sequence_2, iterations)
    item_1, item_2 = sequence_1.start, sequence_2.start
    result=[]
    iterations.times do
      result << item_1 << item_2
      item_1 += sequence_1.step
      item_2 += sequence_2.step
    end
    result
  end
end

[我的代码(michael):

enter image description here

答案 1 :(得分:2)

如果你不能没有参数,那么该参数必须保留。仅仅因为具有小签名的方法是首选,这并不意味着当需要每个参数时,长方法签名都是错误的。

但是,如果您真的想作弊并缩短签名,可以尝试:

class DoubleSeries
  def self.generate_sequences(array_args)
    seq1_start, seq2_start, seq1_step, seq2_step, iterations = *array_args
    seq1,seq2=seq1_start,seq2_start
    result=[]
    (1..iterations).each do
      result << seq1 << seq2
      seq1+=seq1_step
      seq2+=seq2_step
    end
    result
  end
end

但是,我认为我所写的内容不如你最初写的那样清晰(因为论证更加含糊不清)。我刚给出了一个代码示例,向您展示您只能有一个参数,但它可能不是最好的方法。

做你想做的事的另一种方法是改变你生成序列的方式。 E.g

class DoubleSeries
  def self.generate_sequence(seq1_start, seq1_step, iterations)
    seq1=seq1_start
    result=[]
    (1..iterations).each do
      result << seq1
      seq1+=seq1_step
    end
    result
  end        
end

x = DoubleSeries.generate_sequence(1,5,5)
y = DoubleSeries.generate_sequence(4,6,5)
x.zip(y).flatten

或者,使用Ruby 2.0和Lazy Enumerators

range = 1..Integer::INFINITY
seq_1 = range.lazy.collect{|n| (n-start_1 % seq_1_step) == 0}.first(iterations)
seq_2 = range.lazy.collect{|n| (n-start_2 % seq_2_step) == 0}.first(iterations)
seq_1.zip(seq_2).flatten