这个Ruby成语是否有更好的替代方案?

时间:2010-01-14 22:57:23

标签: ruby-on-rails ruby idioms

我发现自己在控制器中编写了这么多代码:

params[:task][:completed_at] = Time.parse(params[:task][:completed_at]) if params[:task][:completed_at]

不要特意把我在这里做的事情挂掉,因为每次都会改变原因;但是在很多情况下我需要检查params中的值并在将其移交给createupdate_attributes之前进行更改。

重复params[:task][:completed_at]三次感觉非常糟糕。有更好的方法吗?

3 个答案:

答案 0 :(得分:11)

稍微缩短这一点的一种方法是:

if c = params[:task][:completed_at]
  params[:task][:completed_at] = Time.parse(c)
end

或者,你可能更喜欢这个:

params[:task][:completed_at] &&= Time.parse(params[:task][:completed_at])

在第二种情况下,只有在左侧是“真实”的情况下才会进行分配。

答案 1 :(得分:0)

我想你可以考虑做这样的事情。

在String和NilClass上实现#to_time,可能在extensions.rb中(如Ruby Best Practices中所推荐的那样,例如

require 'time'
class String
  def to_time
    Time.parse(self) # add error/exception handling to taste
  end
end

class NilClass
  def to_time
    nil
  end
end

然后你可以调用params[:task][:created_at].to_time并且复制已经消失。

我完全不确定这必然构成“最佳做法”,但恕我直言,它符合问题的目标......

答案 2 :(得分:0)

我对Ruby并不十分熟悉,但由于它有Perl根,可能有一个允许你这样编写它的结构:

$_ = Time->parse($_) for params[:task][:completed_at] || ();

基本上利用for循环来创建变量的别名(如果存在)

可能是这样的:

(params[:task][:completed_at] || ()).each { |i| i = Time.parse(i) }

编辑:

我看到Ruby有alias个关键字。我不熟悉它给出一个Ruby示例,但在Perl中,上面也可以编写:

local *_ = \$params[$task][$completed_at];

$_ = Time->parse($_) if defined;

指定$_将成为$params[$task][$completed_at]

的别名

我尝试在Ruby中熟悉它,但没有找到一种方法来为一个标识符添加别名,只是全局变量。