Sunday, March 18th, 2007
++preincrement
Sunday, March 18th, 2007 11:08 pmA lot of programming languages, going back to at least C, support preincrement/postincrement operators ++ and --. For instance (in perl, with \n ignored for clarity):
43
43
44
Explicitly, the expression ++variable changes variable to be variable + 1. The value of the expression is the new value of variable. On the other hand, the expression variable++ changes variable to be one larger, but the value of the expression is the old value of the variable. In most languages, ++variable is equivalent to variable += 1. 1 receives special treatment because of the sheer volume of C code which accesses successive items in an array or increments or decrements a counter.
Ruby is an interesting language. It's got a lot of flexible syntax, borrowed in large part from perl. But in Ruby, everything* is an object and all operations are method calls on an object. Any class can define a + method, so 'book' + 'keeper' == 'bookkeeper' and matrix notation is easy to handle. Classes cannot define a += operator. Instead, ruby treats
Why? - and + are unary operators.
I should also note that Python has the same behavior as Ruby (and had it first). In addition, Python lets a class define its own __iadd__ method which responds to += syntax:
I wrote this post in part because Googling ruby "++" returned lots of pages which mention both Ruby and C++. And since ++ doesn't have any particular significance to the language, none of the documentation returned by ruby "++" -"c++" mentioned it. So by mentioning python, ruby, ++, --, plus plus, minus minus, and operator in close succession I hope to aid future confused language converts. Thanks to #ruby-lang for the quick answer.
I should also mention that ++i in these languages is equivalent to the LISP/Scheme
(Un?)fortunately, that function only affects one variable. (++j) would complain that the function ++j doesn't exist.
*: Not quite everything in Ruby is an object or method call. Control structures like if then else are expressions (unlike languages such as C, Java, Perl, and Python), but they are not method calls; you cannot override the if method (unlike functional languages like LISP and Scheme or pure object-oriented languages like Smalltalk and Io).
$i = 42
print ++$i
43
print $i++
43
print $i++
44
Explicitly, the expression ++variable changes variable to be variable + 1. The value of the expression is the new value of variable. On the other hand, the expression variable++ changes variable to be one larger, but the value of the expression is the old value of the variable. In most languages, ++variable is equivalent to variable += 1. 1 receives special treatment because of the sheer volume of C code which accesses successive items in an array or increments or decrements a counter.
Ruby is an interesting language. It's got a lot of flexible syntax, borrowed in large part from perl. But in Ruby, everything* is an object and all operations are method calls on an object. Any class can define a + method, so 'book' + 'keeper' == 'bookkeeper' and matrix notation is easy to handle. Classes cannot define a += operator. Instead, ruby treats
i += 42
as shorthand for i = i + 42
and l = [1, 2, 3]; l += [4, 5, 6]
produces [1, 2, 3, 4, 5, 6]. But a warning to C, C++, Java, and Perl junkies: ++ and -- do not work the same way:irb(main):001:0> i = 42
=> 42
irb(main):002:0> --i
=> 42
irb(main):003:0> ++i
=> 42
irb(main):004:0> i++
SyntaxError
Why? - and + are unary operators.
-42
is equivalent to 0.-42
(that's invoking the "-" method on 0 with 42 as an argument, possibly clearer as 0.-(42)
). +foo
is equivalent to 0.+(foo)
. Furthermore, unary operators can be repeated: -(-42)
is the same as --42
is the same as 42
(since there are two negatives). ++foo
is the same as ++++++++++foo
is the same as +(+(foo))
is the same as foo
. Furthermore, whitespace is ignored, so while i++
as the last line of a block is a syntax error, the following may surprise you:irb(main):001:0> 42++
irb(main):001:0* --42
=> 84
I should also note that Python has the same behavior as Ruby (and had it first). In addition, Python lets a class define its own __iadd__ method which responds to += syntax:
>>> l = [1, 2, 3]
>>> l += [4, 5, 6]
>>> l
[1, 2, 3, 4, 5, 6]
>>> l.__iadd__([7, 8, 9])
[1, 2, 3, 4, 5, 6, 7, 8, 9]
I wrote this post in part because Googling ruby "++" returned lots of pages which mention both Ruby and C++. And since ++ doesn't have any particular significance to the language, none of the documentation returned by ruby "++" -"c++" mentioned it. So by mentioning python, ruby, ++, --, plus plus, minus minus, and operator in close succession I hope to aid future confused language converts. Thanks to #ruby-lang for the quick answer.
I should also mention that ++i in these languages is equivalent to the LISP/Scheme
(+ (+ i))
. Furthermore, in those languages you can define your own implementation of the ++ or -- function. You can even define a variable i
and functions ++i, --i, i++, and i--:> (define i 42)
> (define ++i (lambda () (set! i (+ i 1)) i))
> i
42
> (++i)
43
> (++i)
44
(Un?)fortunately, that function only affects one variable. (++j) would complain that the function ++j doesn't exist.
*: Not quite everything in Ruby is an object or method call. Control structures like if then else are expressions (unlike languages such as C, Java, Perl, and Python), but they are not method calls; you cannot override the if method (unlike functional languages like LISP and Scheme or pure object-oriented languages like Smalltalk and Io).