Does it? Foo = is the expression legal in Ruby?

Note. I'm not really sure what to name the question, so if anyone understands better please edit it.

I will go straight to the question as no explanation is required.

This code:

!foo = true

      

generates this warning

warning: found = in conditional, should be ==

      

I would understand if this happened after the instruction if

or unless

, but it couldn't be further from them (exaggeration). I understand that I can use:

foo = true
!foo

      

I suppose the warning doesn't really matter, but it's a little annoying that Ruby assumes I'm doing something wrong and when I'm not.


Questions:

  • This is mistake?
  • Can the warning be turned off?

Thank!

+3


source to share


5 answers


Is legal. Not a mistake. The warning can be suppressed.

You can turn off the warning:

$VERBOSE = nil

      

Interestingly, this $VERBOSE

is the case where setting something for false

does something other than setting it on nil

.

By the way, the other answers, at least initially, tend to suggest that Ruby parses an expression as



(!foo) = true

      

... but it isn't. It is parsed as:

!(foo = true)

      

... and so it does exactly what the OP wanted. And there is no specification or ratified standard for Ruby, so if it works in MRI (reference implementation) then it is legal.

+9


source


As the previous answers have said, this is not really what you are doing.

!foo = true

      

assessed as

!(foo = true)

      

That is, assign true

foo

and get the negation of the result of that assignment, which boils down to

!true

      

or

false

      



If you want to keep !true

it should be

foo = !true

      

If you want to assign true to foo and negate another variable, that would be

foo2 = !(foo = true)

      

and that will still raise a warning, because after all, it's a conditional assignment.

I really want to assign true to foo and then get the opposite foo on the stack

Doesn't make much sense. You "get something on the stack" by assigning it to a variable, like foo2

in my example.

If the goal here is to assign an instance variable and return the negation from the method, then yes, you will have to assign the variable first and then explicitly return the negation. This is not a bug in Ruby, but actually a function, and for clean code, you shouldn't do it on one line, because it's basically indistinguishable from a common usage error =

when it comes to ==

.

+4


source


This is just a warning and evaluates as you expect. You can temporarily disable warnings by assigning $ VERBOSE = nil.

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

      

Other places on the net , suggest making a helper method 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

      

But I just tried this in 1.9.2 and 1.8.7 and it was ineffective for suppressing the "warning: found = in conditional, must be =="

+4


source


This is a technically incorrect left hand assignment. Do you want to

foo =! true

You cannot assign a value to the opposite of an object. What's not foo? =)

+1


source


This is a bug in the code:

!var = anything

      

Wrong. You are trying to assign either TrueClass

, FalseClass

which (possibly) returns !var

.

Do you want to:

!var == true

      

Now you are making a comparison (albeit unnecessary).

+1


source







All Articles