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

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

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

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

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

缓解这种情况的一种方法是:

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

或者,您可能更喜欢这样:

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

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

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

在String和#to_time上实现#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 ,复制就消失了。

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

我对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中熟悉它,但没有看到一种方法来为一个标识符添加别名,只是全局变量。