Ruby has no pre/post increment/decrement operator. For instance, x++ or x-- will fail to parse. More importantly, ++x or --x will do nothing! In fact, they behave as multiple unary prefix operators: -x == ---x == -----x == ......
Coming from JavaScript, I had no idea that Ruby doesn't have an increment operator like ++ . It turns out that the author of Ruby, matz suggests the official way to increment and decrement variables in ruby is by using the += and -= operators.
i++ is known as post increment whereas ++i is called pre increment. i++ is post increment because it increments i 's value by 1 after the operation is over. Here value of j = 1 , but i = 2 . Here the value of i will be assigned to j first, and then i will be incremented.
The increment operator increases, and the decrement operator decreases, the value of its operand by 1. The operand must have an arithmetic or pointer data type, and must refer to a modifiable data object.
Here is how Matz(Yukihiro Matsumoto) explains it in an old thread:
Hi,
In message "[ruby-talk:02706] X++?"
on 00/05/10, Aleksi Niemelä <[email protected]> writes:
|I got an idea from http://www.pragprog.com:8080/rubyfaq/rubyfaq-5.html#ss5.3
|and thought to try. I didn't manage to make "auto(in|de)crement" working so
|could somebody help here? Does this contain some errors or is the idea
|wrong?
(1) ++ and -- are NOT reserved operator in Ruby.
(2) C's increment/decrement operators are in fact hidden assignment.
They affect variables, not objects. You cannot accomplish
assignment via method. Ruby uses +=/-= operator instead.
(3) self cannot be a target of assignment. In addition, altering
the value of integer 1 might cause severe confusion throughout
the program.
matz.
One reason is that up to now every assignment operator (i.e. an operator which changes a variable) has a =
in it. If you add ++
and --
, that's no longer the case.
Another reason is that the behavior of ++
and --
often confuse people. Case in point: The return value of i++
in your example would actually be 1, not 2 (the new value of i
would be 2, however).
It's not conventional in OO languages. In fact, there is no ++
in Smalltalk, the language that coined the term "object-oriented programming" (and the language Ruby is most strongly influenced by). What you mean is that it's conventional in C and languages closely imitating C. Ruby does have a somewhat C-like syntax, but it isn't slavish in adhering to C traditions.
As for why it isn't in Ruby: Matz didn't want it. That's really the ultimate reason.
The reason no such thing exists in Smalltalk is because it's part of the language's overriding philosophy that assigning a variable is fundamentally a different kind of thing than sending a message to an object — it's on a different level. This thinking probably influenced Matz in designing Ruby.
It wouldn't be impossible to include it in Ruby — you could easily write a preprocessor that transforms all ++
into +=1
. but evidently Matz didn't like the idea of an operator that did a "hidden assignment." It also seems a little strange to have an operator with a hidden integer operand inside of it. No other operator in the language works that way.
I think there's another reason: ++
in Ruby wouldn't be remotely useful as in C and its direct successors.
The reason being, the for
keyword: while it's essential in C, it's mostly superfluous in Ruby. Most of the iteration in Ruby is done through Enumerable methods, such as each
and map
when iterating through some data structure, and Fixnum#times
method, when you need to loop an exact number of times.
Actually, as far as I have seen, most of the time +=1
is used by people freshly migrated to Ruby from C-style languages.
In short, it's really questionable if methods ++
and --
would be used at all.
I think Matz' reasoning for not liking them is that it actually replaces the variable with a new one.
ex:
a = SomeClass.new def a.go 'hello' end # at this point, you can call a.go # but if you did an a++ # that really means a = a + 1 # so you can no longer call a.go # as you have lost your original
Now if somebody could convince him that it should just call #succ! or what not, that would make more sense, and avoid the problem. You can suggest it on ruby core.
You can define a .+
self-increment operator:
class Variable
def initialize value = nil
@value = value
end
attr_accessor :value
def method_missing *args, &blk
@value.send(*args, &blk)
end
def to_s
@value.to_s
end
# pre-increment ".+" when x not present
def +(x = nil)
x ? @value + x : @value += 1
end
def -(x = nil)
x ? @value - x : @value -= 1
end
end
i = Variable.new 5
puts i #=> 5
# normal use of +
puts i + 4 #=> 9
puts i #=> 5
# incrementing
puts i.+ #=> 6
puts i #=> 6
More information on "class Variable" is available in "Class Variable to increment Fixnum objects".
And in the words of David Black from his book "The Well-Grounded Rubyist":
Some objects in Ruby are stored in variables as immediate values. These include integers, symbols (which look like :this), and the special objects true, false, and nil. When you assign one of these values to a variable (x = 1), the variable holds the value itself, rather than a reference to it. In practical terms, this doesn’t matter (and it will often be left as implied, rather than spelled out repeatedly, in discussions of references and related topics in this book). Ruby handles the dereferencing of object references automatically; you don’t have to do any extra work to send a message to an object that contains, say, a reference to a string, as opposed to an object that contains an immediate integer value. But the immediate-value representation rule has a couple of interesting ramifications, especially when it comes to integers. For one thing, any object that’s represented as an immediate value is always exactly the same object, no matter how many variables it’s assigned to. There’s only one object 100, only one object false, and so on. The immediate, unique nature of integer-bound variables is behind Ruby’s lack of pre- and post-increment operators—which is to say, you can’t do this in Ruby: x = 1 x++ # No such operator The reason is that due to the immediate presence of 1 in x, x++ would be like 1++, which means you’d be changing the number 1 to the number 2—and that makes no sense.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With