Search code examples
rubyoperatorscomparison-operators

Why is x-- a valid ruby statement but it doesn't do anything?


I know ruby doesn't support integer increment x++ or decrement x-- as C does. But when I use it, it doesn't do anything and doesn't throw an error either. Why?

Edit:

Sorry the code I actually found was using --x, which is slightly different, but the question remains: Why?

x = 10
while --x > 0
  y = x
end

Solution

  • In Ruby, operators are methods. --x, x++, x==, etc all can do wildly different things. -- and ++ are not themselves valid operators. They are combinations of operators.

    In the case of your provided code, --x is the same as -(-x).

    If x == 5, then -x == -5 and --x == 5.

    ---x would be -(-(-x)), and so on.

    Similarly, x-- alone on a line is technically valid, depending on what the next line of code contains.

    For example, the following method is valid:

      def foo
        x = 1
        y = 10
        x--
        y
      end
    

    The last two lines of that method get interpreted as x - (-y) which calculates to 1 - (-10).

    The result doesn't get assigned to any value, so the x-- line would appear to do nothing and the function would just return the result: 11.

    You could even have nil on the last line of the function instead of y, and you wouldn't get a syntax error, but you would get a runtime error when the function is called. The error you would receive from x--nil is:

    NoMethodError: undefined method `-@' for nil:NilClass
    

    That means that -nil is invalid since NilClass does not define the method -@. The @ indicates that - works as a unary operator. Another way to express --x by invoking the unary operators manually is [email protected]@

    x-- just on its own is not valid. It requires a Numeric object to follow it (or any object which implemented -@). That object can be on the next line. x== would work the same way.