是否有一种干净的方式来填充rubram方法中的哈希参数可能不需要的参数?

时间:2014-01-07 16:02:41

标签: ruby parameters dry

假设我们有一个名为mail的函数,它可以接收一个Hash对象,包含from,to,subject,body等发送邮件,所以我们经常把它称为

mail(from: 'from@source.com', to: 'to@destination.com', subject: 'hello', body: 'world')

但有时我们不需要从地址提供,而且这个函数有一个默认值,所以在这种情况下我们会这样调用:

mail(to: 'to@destination.com', subject: 'hello', body: 'world')

但是等等,如果我们确定是否应根据环境为from提供价值,请说我们有一段这样的代码:

if user == me
    mail(to: 'to@destination.com', subject: 'hello', body: 'world')
else
    mail(from: 'from@source.com', to: 'to@destination.com', subject: 'hello', body: 'world')

它不干净,如果我们有多个值,那么?所以我来到这里:

params = { subject: 'hello', body: 'world' }
params[:from] = 'from@source.com' unless user == me
params[:to] = 'to@destination.com' unless custom == me
mail(params)

所以,最后,我的问题是我的头衔,有什么建议吗?

2 个答案:

答案 0 :(得分:0)

mail(
  from: ('from@source.com' unless user == me),
  to: ('to@destination.com' unless custom == me), 
  subject: 'hello', 
  body: 'world' 
)

这将导致将nil作为条件参数的值传递,如果不需要它们的话。在大多数情况下,这应该可以正常工作,因为评估缺失的密钥通常也会导致nil。如果这对您来说是个问题,您可以删除nil值:

params = { ... }.reject{|k,v| v.nil?}
mail params

答案 1 :(得分:0)

另一种选择是使用Object#tap。在您使用has_key?来确定是否分配默认值(而不仅仅是检查哈希是否为该键返回真值)时,这可能比PinnyM的解决方案更好:

def mail(options={})
  puts "From: " + (options[:from] || "default@source.com")
  puts "To: "   + (options[:to]   || "other@source.com")
  puts "Subject: " + options[:subject]
  puts "Body: " + options[:body]
end

me = "Ajedi32"
user = me
custom = "Other Guy"

mail(
  {
    subject: 'hello',
    body: 'world'
  }.tap { |opts|
    opts[:from] = 'from@source.com' unless user == me
    opts[:to] = 'to@destination.com' unless custom == me
  }
)

输出:

From: default@source.com
To: to@destination.com
Subject: hello
Body: world

我不确定它比你目前的解决方案更清洁......