为什么我们需要弹出Hash来创建这个计算方法?

时间:2013-05-24 01:40:21

标签: ruby hash

def add(*numbers)
    numbers.inject(0) { |sum, number| sum + number }  
end

def subtract(*numbers)
  sum = numbers.shift
  numbers.inject(sum) { |sum, number| sum - number }  
end

def calculate(*arguments)
  # if the last argument is a Hash, extract it 
  # otherwise create an empty Hash
  options = arguments[-1].is_a?(Hash) ? arguments.pop : {}
  options[:add] = true if options.empty?
  return add(*arguments) if options[:add]
  return subtract(*arguments) if options[:subtract]
end

有人可以用简单的英语向我解释为什么我们需要检查此代码中的最后一个参数是否为哈希然后弹出它:

options = arguments[-1].is_a?(Hash) ? arguments.pop : {} 

由于

2 个答案:

答案 0 :(得分:4)

显然,此函数接受可选的“options”哈希作为参数以及整数列表。选项列在参数列表的末尾。所以函数必须检查它,如果有选项哈希,则弹出它并将它放在选项变量中。

答案 1 :(得分:2)

实现代码的方式是使用参数列表调用calculate方法。在该列表中,如果它是Hash,则最后一个参数将是一个选项哈希。执行arguments.pop将从参数列表中提取选项哈希。

calculate(1,2,3,{add: false, subtract: true})最终将返回subtract(1,2,3)

操作

calculate(1,2,3)最终会调用add(1,2,3)

<强>更新

要回答您对其他答案的评论,您需要将其从arguments变量中弹出,因为addsubtract方法的实施方式。如果你注意到这些方法开始移动参数或对参数使用注入,如果最后一个参数是一个哈希则没有多大意义。这就是为什么在将arguments变量发送到其他方法之前将其弹出的原因。

这个实现是一个有趣的方法,因为它允许传入任意数量的整数参数和一个可选的最后options hash

通常你会看到像这样定义的方法

def testing(arg1, arg2, options={})
  # some manipulation of the args and options
end

但是这种处理方式需要你为你想要传递给方法的每个参数创建一个参数