Things That Newcomers to Ruby Should Know (11/24/02)

And given that the concept of ‘x++’ is very rarely needed in a
Ruby program, having iterators instead of for-loops, those extra
three characters are actually a very small percentage, amortised
over the entire program.
Regardless, is there a reason not to have ‘++’? It’s the kind of
shortcut that many programmers expect and I just can’t think of
any reason not to have it.

It’s applicable to a small subset of the total set of classes.
Really, x++ is the same as x.succ!, and x.succ! won’t work because
there’s no assignment and you can’t change self.

Remember that Fixnums are immediate/singleton objects (there is one
and only one instance of the Fixnum object with value 5), so you
couldn’t have x.succ! (or x++) do anything meaningful – again,
because “self” cannot be changed, even if x.succ! was meaningful for
other objects.

If it’s “magicked” to x += 1 (which itself is magic for x = x + 1),
then you run into the problem of applicability to non-Numeric
classes.

All in all, it’s a shorthand that doesn’t really make sense in Ruby.

Speaking of which, wouldn’t the “best” Ruby idiom for:
x += 1
really be:
x = x.succ
? This, at least, would work cleanly with any “countable” object. I
think.

Following the principle of Least Surprise, I’d expect to find this
feature, unless there is a good reason to avoid it.

Ruby is really designed to the Princple of Matz’s Least Surprise.
Ruby works 95% of the time for me with no surprises, but I’m not
Matz, so there will always be some surprise there for me. Usually
pleasant.

IMO, there are good reasons to avoid x++ (aside from the fact that
it really to modifies “self”, which I really think is a bad idea).
The main reason to avoid it is that it isn’t really needed in Ruby.
In the Ruby that I’ve done so far, Text::Format uses it in one
place, which would be removed if I switch to any of the
Array#zip/Array#braid methods proposed recently; in RTidy/CityDesk I
use it extensively to add to the progress (which means I should
probably refactor the progress handling into its own class) for the
progress bar calculations.

Everything else is done with native Ruby loops – I find that I just
don’t care about incrementing indexes, because Ruby does the right
thing for me.

-austin
– Austin Ziegler, austin@halostatue.ca on 2002.11.25 at 21.46.33

···

On Tue, 26 Nov 2002 09:21:48 +0900, Daniel Carrera wrote:

Hello dblack,

Tuesday, November 26, 2002, 3:25:34 AM, you wrote:

(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.

the same applied to ‘<<’? :slight_smile:

···


Best regards,
Bulat mailto:bulatz@integ.ru

It’s syntax sugar only,

so a[x += 1] = a[x = x + 1] => a[x+1] # => x = x + 1.

···

On Tuesday, 26 November 2002 at 9:32:44 +0900, Gavin Sinclair wrote:

Ruby can’t/won’t replicate this behaviour, so swiping the operators would
mislead. I don’t know what a[x += 1] does in Ruby, and I’m not going to ask.


Jim Freeze

There is only one thing in the world worse than being talked about, and
that is not being talked about.
– Oscar Wilde

:slight_smile: I’ll answer anyway. It’s nothing mysterious,
exactly what it looks like – the equivalent of
a pre-increment. (The inner expression has to be
evaluated first.)

Hal

···

----- Original Message -----
From: “Gavin Sinclair” gsinclair@soyabean.com.au
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Monday, November 25, 2002 6:32 PM
Subject: Re: Things That Newcomers to Ruby Should Know (11/24/02)

I don’t know what a[x += 1] does in Ruby, and I’m not going to ask.

This relates to my email a few minutes earlier about collect_with_index, but
how would you do this without incrementing an index, given the current lack
of existance of a collect_with_index method?

To take a string, split it into paragraphs, turn each of them into an HTML


and number them:

i = 0; string.split(“\n”).collect{ |para| ‘

’ + (i += 1).to_s + " - " + para
}.join(“\n”)

Tim Bates

···

On Tue, 26 Nov 2002 01:33 pm, Austin Ziegler wrote:

Everything else is done with native Ruby loops – I find that I just
don’t care about incrementing indexes, because Ruby does the right
thing for me.


tim@bates.id.au

It’s applicable to a small subset of the total set of classes.
Really, x++ is the same as x.succ!, and x.succ! won’t work because
there’s no assignment and you can’t change self.

I don’t follow that. Why is it that I can do string.chomp! but it is not
conceivable to do x.succ!? Aren’t you changing self with string.chomp!?

Daniel.

It’s applicable to a small subset of the total set of classes.
Really, x++ is the same as x.succ!, and x.succ! won’t work because
there’s no assignment and you can’t change self.

I don’t follow that. Why is it that I can do string.chomp! but it is not
conceivable to do x.succ!? Aren’t you changing self with string.chomp!?

Daniel.

No. Hopefully the following makes sense.

irb(main):001:0> s = “String\n”
“String\n”
irb(main):002:0> s.id
134560740
irb(main):003:0> s.chomp!
“String”
irb(main):004:0> s.id
134560740
irb(main):005:0> x = 4
4
irb(main):006:0> x.id
9
irb(main):007:0> x += 1
5
irb(main):008:0> x.id
11

The prevailing point is that “x = 4; x++” translates into Ruby most closely as
x = 4
x.succ!

Of course, Integer#succ! is not defined, for good reason. What does
4.succ!
mean? Turn all 4’s into 5’s?

4 is an unmodifiable object. “Hello”.chomp! is fine because “Hello” is a
modifiable object.

Gavin

···

From: “Daniel Carrera” dcarrera@math.umd.edu

Hi Daniel,

Gavin has given you some answers and concepts based on Ruby
itself. Another answer can be found by looking at how Ruby objects are
implemented in C. If you read the “Extending Ruby” chaper in the pickaxe
book, Ruby variables all have the (C) type of ‘VALUE’, which is either a
pointer to a Ruby object or an immediate value (such as Fixnum). In
principle, you cannot have a “self-changing” method for objects which have
immediate values (such as Fixnum, Symbol, true, false, and nil).

(Well, reading my own post, I conclude that in principle, we can actually
have x.succ! if x is a Bignum; oh, boy… But it is never going to be
implemented, as the conversion between Fixnum and Bignum is automatic.)

Regards,

Bill

···

Daniel Carrera dcarrera@math.umd.edu wrote:

I don’t follow that. Why is it that I can do string.chomp! but it is not
conceivable to do x.succ!? Aren’t you changing self with string.chomp!?

Nope.

x.succ! says “x should be changed to be the succeeding object”.
x.chomp! says “x should have newlines removed from itself.”

x.succ! results in a new object; x.chomp! does not.

-austin
– Austin Ziegler, austin@halostatue.ca on 2002.11.25 at 23.22.04

···

On Tue, 26 Nov 2002 12:14:58 +0900, Daniel Carrera wrote:

It’s applicable to a small subset of the total set of classes.
Really, x++ is the same as x.succ!, and x.succ! won’t work
because there’s no assignment and you can’t change self.
I don’t follow that. Why is it that I can do string.chomp! but it
is not conceivable to do x.succ!? Aren’t you changing self with
string.chomp!?

[snip]

4 is an unmodifiable object. “Hello”.chomp! is fine because “Hello” is a
modifiable object.

Thanks, I’m understanding more now. I guess that the next logical
question is why is 4 unmodifiable and “a” modifiable? I don’t see why a
string would be modifiable and a number not.

Just like you can say that the number 4 is set, and cannot be turned into
a 5, you can also say that the letter “a” is set and cannot be turned into
a “b”. Yet, I can write:

“a”.gsub!(/a/,“b”)

Isn’t it then arbitrary to declare numbers unmodifiable but declare
strings modifiable? Perhaps Matz has a good reason for this.

Daniel.

It’s applicable to a small subset of the total set of classes.
Really, x++ is the same as x.succ!, and x.succ! won’t work
because there’s no assignment and you can’t change self.
I don’t follow that. Why is it that I can do string.chomp! but it
is not conceivable to do x.succ!? Aren’t you changing self with
string.chomp!?
No. Hopefully the following makes sense.

More to the point:

irb(main):004:0> s = “Hello”
“Hello”
irb(main):005:0> s.id
20841200
irb(main):006:0> s.succ!
“Hellp”
irb(main):007:0> s.id
20841200
irb(main):008:0>

The prevailing point is that “x = 4; x++” translates into Ruby
most closely as
x = 4
x.succ!

Of course, Integer#succ! is not defined, for good reason. What
does 4.succ! mean? Turn all 4’s into 5’s?

4 is an unmodifiable object. “Hello”.chomp! is fine because
“Hello” is a modifiable object.

Actually, I think that the proper term is that 4 is an immediate
object. It’s the immediacy (and the “singleton-object” nature of
Fixnums) which makes the difference.

This leads, of course, to an interesting question. How can one
implement a Fixnum-like behaviour (“singleton-object”) in any given
Ruby class? (That is, one and only one instance of a given value.)

-austin
– Austin Ziegler, austin@halostatue.ca on 2002.11.25 at 23.26.11

···

On Tue, 26 Nov 2002 12:28:15 +0900, Gavin Sinclair wrote:

“Gavin Sinclair” gsinclair@soyabean.com.au writes:

irb(main):001:0> s = “String\n”
“String\n”
irb(main):002:0> s.id
134560740
irb(main):003:0> s.chomp!
“String”
irb(main):004:0> s.id
134560740

Confusing implementation limitations and language design was Perl 5’s big
problem. Don’t let it become Ruby’s big problem too.

···


Do not go gentle into that good night/Rage, rage against the dying of the light

Hi –

···

On Tue, 26 Nov 2002, Austin Ziegler wrote:

On Tue, 26 Nov 2002 12:14:58 +0900, Daniel Carrera wrote:

It’s applicable to a small subset of the total set of classes.
Really, x++ is the same as x.succ!, and x.succ! won’t work
because there’s no assignment and you can’t change self.
I don’t follow that. Why is it that I can do string.chomp! but it
is not conceivable to do x.succ!? Aren’t you changing self with
string.chomp!?

Nope.

x.succ! says “x should be changed to be the succeeding object”.
x.chomp! says “x should have newlines removed from itself.”

x.succ! results in a new object; x.chomp! does not.

But wait – see your next post :slight_smile:

David


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

[snip]

4 is an unmodifiable object. “Hello”.chomp! is fine because “Hello” is a
modifiable object.

Thanks, I’m understanding more now. I guess that the next logical
question is why is 4 unmodifiable and “a” modifiable? I don’t see why a
string would be modifiable and a number not.

Just like you can say that the number 4 is set, and cannot be turned into
a 5, you can also say that the letter “a” is set and cannot be turned into
a “b”. Yet, I can write:

“a”.gsub!(/a/,“b”)

Isn’t it then arbitrary to declare numbers unmodifiable but declare
strings modifiable? Perhaps Matz has a good reason for this.

Daniel.

It’s for performance, mainly (exlusively?). In Java, integers are fixed
quantities. In Ruby, integers are fixed quantities with objectlike properties.
Besides, numbers are the bread and butter of programming. Could you imagine,
instead of
x = 4
you had to do
x = Integer.new(4)
?

Even if the former were syntax sugar for the latter, it would still be a bit
strange. Maybe I’m just used to it.

I have no conceptual problem with the difference between numbers and Strings.
“a” is not a string, per se. It’s an object whose data is considered to be a
string. Changing the “a” to a “b” is merely changing the data of the object.

Perhaps some people would argue that the same should be true for numbers, but I
doubt anyone’s life would change if it were.

Gavin

···

From: “Daniel Carrera” dcarrera@math.umd.edu

Hi –

[snip]

4 is an unmodifiable object. “Hello”.chomp! is fine because “Hello” is a
modifiable object.

Thanks, I’m understanding more now. I guess that the next logical
question is why is 4 unmodifiable and “a” modifiable? I don’t see why a
string would be modifiable and a number not.

Just like you can say that the number 4 is set, and cannot be turned into
a 5, you can also say that the letter “a” is set and cannot be turned into
a “b”. Yet, I can write:

“a”.gsub!(/a/,“b”)

You’re not changing the letter ‘a’ itself; you’re changing a string
which has the letter ‘a’ in it.

To put it another way:

You can have more than one “a” string:

s = “a”
t = “a”

and if you change or increment s:

s.succ! # s is now “b”

t doesn’t change.

But there’s only one of each number. If you were allowed to do

3.succ!

or

3 += 1

then when you did this:

puts 3 * 5

the output would be “20”, because you would have incremented the
actual object 3.

David

···

On Tue, 26 Nov 2002, Daniel Carrera wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

“Gavin Sinclair” gsinclair@soyabean.com.au writes:

irb(main):001:0> s = “String\n”
“String\n”
irb(main):002:0> s.id
134560740
irb(main):003:0> s.chomp!
“String”
irb(main):004:0> s.id
134560740

Confusing implementation limitations and language design was Perl 5’s big
problem. Don’t let it become Ruby’s big problem too.

The above code merely demonstrates that String#chomp! doesn’t modify ‘self’,
rather it modifies the data of the object.

The only “implementation limitations” discussed here are that integers are
immediate values. No problems arise from this - except that ++ doesn’t behave
as in C/Java/Perl. And that’s not even a problem, just a surprise for some
people.

I agree with the sentiment though; just hope that it doesn’t apply to Ruby so
far.

Gavin

···

From: “Simon Cozens” simon@simon-cozens.org

Well, that’s what I get for posting when I did … (:

In the case of an immediate object, what I said is correct. In the
case of a value object, what I said is absolutley wrong (:

-austin
– Austin Ziegler, austin@halostatue.ca on 2002.11.26 at 08.16.18

···

On Tue, 26 Nov 2002 22:10:04 +0900, dblack@candle.superlink.net wrote:

On Tue, 26 Nov 2002, Austin Ziegler wrote:

Nope.

x.succ! says “x should be changed to be the succeeding object”.
x.chomp! says “x should have newlines removed from itself.”

x.succ! results in a new object; x.chomp! does not.
But wait – see your next post :slight_smile:

But there’s only one of each number. If you were allowed to do

3.succ!

or

3 += 1

then when you did this:

puts 3 * 5

the output would be “20”, because you would have incremented the
actual object 3.

David

Reminds me of the joke: 2^3 = 27, for sufficiently large values of 2.

And my favourite, which will only be understood by those who write it down in
mathematical notation: the limit as omega approaches infinity of three is
eight.

OK, OK, here’s an ASCII version.

lim
3 = 8
w → oo

Gavin

···

From: dblack@candle.superlink.net

You’re not changing the letter ‘a’ itself; you’re
changing a string
which has the letter ‘a’ in it.

To put it another way:

You can have more than one “a” string:

s = “a”
t = “a”

and if you change or increment s:

s.succ! # s is now “b”

t doesn’t change.

But there’s only one of each number. If you were
allowed to do

3.succ!

or

3 += 1

then when you did this:

puts 3 * 5

the output would be “20”, because you would have
incremented the
actual object 3.

David


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

So wouldn’t it make send to have a somewhat global
.succ! method and only allow the programmer to
increment (++) on those that have it?

I mean, C doesn’t allow 3++ either (well, it may ALLOW
it, but it doesn’t mean anything). I think that
argument is pretty bogus.

Jason Persampieri
Programmer
Kush Games

“Gavin Sinclair” gsinclair@soyabean.com.au writes:

Confusing implementation limitations and language design was Perl 5’s big
problem. Don’t let it become Ruby’s big problem too.

The above code merely demonstrates that String#chomp! doesn’t modify ‘self’,
rather it modifies the data of the object.

What I’m saying is that proof-by-current-implementation isn’t a great way
to argue the presence or absence of a feature.

The only “implementation limitations” discussed here are that
integers are immediate values. No problems arise from this - except
that ++ doesn’t behave as in C/Java/Perl. And that’s not even a
problem, just a surprise for some people.

It may not even be a surprise. I don’t think that most people would
care (or even notice) that a hypothetical foo.succ! gave them a
different object back from the one they started with.

···


There’s no cinnamon and no lemon or orange involved. If there were, it was a
heretic who mixed it up and the mixer should be impaled on a stake and buggered
by the Shrike for two hours, then taken down and forced to rub the wounds with
the mix until death sets in. - Ingvar Mattsson cares about cocktails.