条件子句中的赋值是好的ruby样式吗?

条件子句中的赋值是好的ruby样式吗?,ruby,coding-style,Ruby,Coding Style,为了写得更简洁,而不是这样做: test_value = method_call_that_might_return_nil() if test_value do_something_with test_value end 我一直在分配条件: if test_value = method_call_that_might_return_nil() do_something_with test_value end 这种款式不好吗?更简洁的语法: do_something_with tes

为了写得更简洁,而不是这样做:

test_value = method_call_that_might_return_nil()
if test_value
  do_something_with test_value
end
我一直在分配条件:

if test_value = method_call_that_might_return_nil()
  do_something_with test_value
end
这种款式不好吗?更简洁的语法:

do_something_with test_value if test_value = method_call_that_might_return_nil()
如前所述,是不允许的,根据Matz()的说法,在1.9中仍然是这样


考虑到赋值和比较之间可能存在的混淆,这是否会使阅读代码变得太困难?

是的,我认为这是一种糟糕的风格,因为赋值和比较之间可能存在混淆。只需再分配一行代码,然后再进行测试,这样可以避免将来有人认为这是一个bug,并将其修补为使用
=

一个有点普遍的习惯用法是使用
,看起来像这样:

tmp = method_call_that_might_return_nil and do_something_with tmp
另一种可能是显式地调用
#nil?
,这样意图就会变得更清楚一些;特别明显的是,您实际上是想分配而不是比较:

unless (tmp = method_call_that_might_return_nil).nil?
  do_something_with tmp
end

简洁的代码不一定是更好的代码。简洁性在改善作者与未来维护者之间预期代码行为的沟通时非常有用。我认为我们中有足够多的人来自这样的背景:我们在
if
块中意外地分配了任务(当我们打算进行相等比较时),我们更喜欢绝对清楚地表明分配是有意的,而不是比较的风格。已经提到的<代码> .nIL./COD>成语具有该属性,并且我认为它比在如果条件下的裸赋值更干净。不过,我真的不认为为作业增加一行代码有什么害处。

C程序员经常这样做。我也不认为Ruby有什么问题,只要它清楚发生了什么。

我认为它没问题。对条件中赋值的厌恶来自于知道键入==时漏掉的键击会将比较变成意外赋值。在文体上禁止在条件下使用赋值,这使得此类意外事件引人注目(有时在语言上,如在C语言中,许多编译器在遇到条件下的赋值时都会发出警告)。另一方面,测试也使此类事故引人注目。如果你的代码被测试覆盖,你可以考虑丢弃这些禁止。

< P>函数的编程方式就是使用。这是链接方法调用的一种可读方式,中间的一个零停止了该链。因此,您的示例如下:

method_call_that_might_return_nil.andand.tap {|obj| do_something_with obj}
## or, in the common case: ##
method_call_that_might_return_nil.andand.do_something

在条件句中使用赋值是一种很好的风格。如果这样做,请将条件括在括号中

#坏(+警告)
如果v=array.grep(/foo/)
做某事(v)
#一些代码
结束
#好(MRI仍会抱怨,但RuboCop不会)
if(v=array.grep(/foo/)
做某事(v)
#一些代码
结束
#好
v=array.grep(/foo/)
如果v
做某事(v)
#一些代码
结束

由于警告,执行
if
子句中的赋值时有一股刺鼻的气味。如果您确实要处理
else
案例,则
案例。。。在…
中,模式匹配可以提供以下功能:

case method_call_that_might_return_nil
in nil
  # handle nil case
in test_value # pattern match to a new variable 
  # handle non-nil case with return value of method assigned to test_value
end
或者


我认为必须在简洁和易懂之间划清界限。我认为,在我们必须了解几种不同语言的今天,在不损害现有程序员知识的情况下使用某些语言的酷新特性是一个好主意。作为一个专业的程序员,为什么我需要在不同的语言之间搜索这样的语法适应性呢?我宁愿花时间在谷歌上搜索手头的问题。例如,如何在ruby.Rubocop和本ruby样式指南中使用多线程建议避免:链接到样式指南的特定部分:问题是ruby在分配条件时会发出警告。如果没有,我怀疑它在ruby中会像在C中一样受欢迎。当它工作时,我得到一个
警告:found=in conditional,should=
有人能解释为什么第一个(没有括号)不好吗?@KenRatanachaiS。它不好的原因是,通常情况下,您在条件中执行直接向上的相等性检查(使用
=
),而赋值(
=
)是一种常见的打字错误。当您在条件中进行赋值时,需要用括号括起来,这对读者来说是一个额外的提示,说明赋值是故意的,而不是打字错误。@DevonParsons,谢谢。所以这是为了避免打字错误。但有时在IF条件下的作业也会给我带来意想不到的结果。可能是作用域问题。@Murphy是的,在条件赋值或条件块中引入作用域的变量在条件作用域结束后都可用。
case method_call_that_might_return_nil
in test_value if test_value # pattern match to a new variable if not nil
  # handle non-nil case with return value of method assigned to test_value
else
  # handle nil case
end