在Ruby中,foo = expression是合法的吗?

时间:2012-04-01 22:15:37

标签: ruby warnings

注意:我不确定该问题的名称,所以如果有人有更好的想法,请编辑它。

我会直接回答这个问题,因为不需要任何预先解释。

此代码:

!foo = true

生成此警告

warning: found = in conditional, should be ==

我会理解,如果在ifunless声明之后发生这种情况,但这不能远离他们(夸大其词)。我意识到我可以使用:

foo = true
!foo

我想,这个警告并不是什么大不了的事,但是当我不这样做时,Ruby会假设我做错了事,这有点令人恼火。


问题:

  • 这是一个错误吗?
  • 警告可以被禁用吗?

谢谢!

5 个答案:

答案 0 :(得分:10)

合法。 一个错误。警告可以被抑制。

您可以使用以下命令禁用警告:

$VERBOSE = nil

有趣的是,$VERBOSE是将false设置为与nil设置不同的情况。

顺便说一句,其他答案,至少在最初阶段,倾向于假设Ruby将表达式解析为

(!foo) = true

......但事实并非如此。它被解析为:

!(foo = true)

......所以它正在做OP所需要的。 Ruby没有规范或批准的标准,所以如果它在MRI(参考实现)中有效,那么它是合法的。

答案 1 :(得分:4)

正如先前的答案已经提出的那样,做你想做的事情并不是一件有效的事情。

!foo = true

评估为

!(foo = true)

也就是说,将true分配给foo并取消该作业的结果,归结为

!true

false

如果您想存储!true,则必须

foo = !true

如果你想将foo赋值为true而将否定赋值给另一个变量,那么它就是

foo2 = !(foo = true)

并且仍会引发警告,因为毕竟它是条件中的赋值。

  

我实际上想要将true赋给foo,然后在堆栈上获得foo的反面

真的没有多大意义。通过将其分配给变量(例如我的示例中的foo2),您可以“获得堆栈中的内容”。

如果这里的目的是分配一个实例变量并从方法返回否定,那么是的,你必须首先分配给变量然后显式地返回否定。这不是Ruby中的错误,但实际上是一个功能,为了清理代码,您不应该在一行中执行它,因为它与=时使用==的常见错误基本无法区分意思是。

答案 2 :(得分:4)

这只是一个警告,正在按照您的预期进行评估。您可以通过分配$ VERBOSE = nil来暂时禁用警告。

save_verbose, $VERBOSE = $VERBOSE, nil
result = !foo = true
$VERBOSE = save_verbos
result

其他places on the net,建议制作辅助方法ala

module Kernel
  def silence_warnings
    with_warnings(nil) { yield }
  end

  def with_warnings(flag)
    old_verbose, $VERBOSE = $VERBOSE, flag
    yield
  ensure
    $VERBOSE = old_verbose
  end
end unless Kernel.respond_to? :silence_warnings

但是,我只是在1.9.2和1.8.7中尝试了这个并且它在抑制“警告:发现=有条件,应该是==”

时无效

答案 3 :(得分:1)

从技术上讲,这是一项无效的左手任务。你想要

foo =!true

您无法为对象的反面指定值。什么不是foo? =)

答案 4 :(得分:1)

这是您的代码中的错误:

!var = anything

错了。您正尝试分配TrueClassFalseClass,这可能是!var返回的内容。

你想:

!var == true

现在你正在进行比较(尽管是不必要的比较)。