Ruby doesn't implement x++ for Fixnum's because?

On Nov 4, 9:37 am, Seebs [email protected] wrote:

gsub! can work because somewhere inside the object there is a hunk of storage
which is separate from the object itself. Fixnum has no such storage to
refer to.

-s

Copyright 2009, all wrongs reversed. Peter S. / [email protected]://www.seebs.net/log/<-- lawsuits, religion, and funny pictureshttp://en.wikipedia.org/wiki/Fair_Game_(Scientology) ← get educated!

++ would have to be implemented as a method on objects which ARE their data

Not true. Check out the following, step by step:

def show(v)
“Got #{v}, class = #{v.class}, object_id = #{v.object_id}
(v.object_id-1)/2 = #{(v.object_id-1)/2 }”
end

class Fixnum
def pp # We can’t define ++ because of a compiler restriction.
self + 1
end
end

These lines show that a & b values are stored in there object_ids held
in the symbol table.
Don’t believe it? Read more.
a = 1; show (a) => Got 1; class = Fixnum; object_id = 3; v >> 1
= 1
b = 1; show (b) => Got 1; class = Fixnum; object_id = 3; v >> 1
= 1
a == b => true

Appending these lines shows that a & b values are distinct.
That is, after incrementing, a =2, b is unchanged; b is not
impacted by a’s change
a += 1; show (a) => Got 2; class = Fixnum; object_id = 5; v >> 1
= 2
show (b) => Got 1; class = Fixnum; object_id = 3; v >> 1 = 1

Appending these lines shows the ++’s alias pp works just find
a=1; show(a.pp) => Got 2; class = Fixnum; object_id = 5; v >> 1
= 2
show(b) => Got 1; class = Fixnum; object_id = 3; v >> 1 = 1

Appending these lines show that ++ crosses the Fixnum/Bignum boundary
a = 2**30-1; show (a) => Got 1073741823; class = Fixnum; object_id
= 2147483647; v >> 1 = 1073741823
show(a.pp) => Got 1073741824; class = Bignum; object_id =
22738520; v >> 1 = 11369260 # “v >> 1” is irrelevant, of course.

Do you agree?

Best wishes,
Richard

On Nov 4, 10:59 am, Yukihiro M. [email protected] wrote:

I don’t.

                                                    matz.

Hi Matz,

Thank you very much for your brilliant and enormous efforts in
creating Ruby and offering to the programming world as gift.

Only if you accept the language that can change the value of 1 to 2.

I know that you know Ruby extremely well. But I have written the
following tests on this issue of whether “1” ever gets changed to
“2”. I assume you have not looked at my post yesterday on this
issue. I’d be honored if you’d
look at the following comments and code and point out anything you
view as erroneous.

BTW, I’m not advocating x++ for Ruby. I’m just trying to understand
whether Ruby would literally change 1 to 2 as opposed to change a
variable that contains 1 to subsequently contain 2.

Best wishes,
Richard

def show(v)
“Got #{v}, class = #{v.class}, object_id = #{v.object_id}
(v.object_id-1)/2 = #{(v.object_id-1)/2 }”
end

class Fixnum
def pp # We can’t define ++ because of a compiler restriction.
self + 1
end
end

These lines show that a & b values are stored in their object_ids held
in the symbol table.
Don’t believe it? Read more.
a = 1; show (a) => Got 1; class = Fixnum; object_id = 3; v >> 1
= 1
b = 1; show (b) => Got 1; class = Fixnum; object_id = 3; v >> 1
= 1
a == b => true

Appending these lines shows that a & b values are distinct.
That is, after incrementing, a =2, b is unchanged; b is not
impacted by a’s change
a += 1; show (a) => Got 2; class = Fixnum; object_id = 5; v >> 1
= 2
show (b) => Got 1; class = Fixnum; object_id = 3; v >> 1 = 1

Appending these lines shows the ++’s alias pp works just find
a=1; show(a.pp) => Got 2; class = Fixnum; object_id = 5; v >> 1
= 2
show(b) => Got 1; class = Fixnum; object_id = 3; v >> 1 = 1

Appending these lines show that ++ crosses the Fixnum/Bignum boundary
a = 2**30-1; show (a) => Got 1073741823; class = Fixnum; object_id
= 2147483647; v >> 1 = 1073741823
show(a.pp) => Got 1073741824; class = Bignum; object_id =
22738520; v >> 1 = 11369260

“v >> 1” is irrelevant, of course.

RichardOnRails wrote:

BTW, I’m not advocating x++ for Ruby. I’m just trying to understand
whether Ruby would literally change 1 to 2 as opposed to change a
variable that contains 1 to subsequently contain 2.

I am confused.
irb(main):001:0> 1.succ
=> 2
irb(main):002:0> 1.object_id
=> 3
irb(main):003:0> 1.succ.object_id
=> 5
irb(main):004:0>

Is that good enough? If not, I’d recommend taking a look at…
irb(main):004:0> 1.class
=> Fixnum

Fixnum … Fixed number? :slight_smile:

On Thu, Nov 5, 2009 at 12:55 AM, RichardOnRails
[email protected] wrote:

BTW, I’m not advocating x++ for Ruby. I’m just trying to understand
whether Ruby would literally change 1 to 2 as opposed to change a
variable that contains 1 to subsequently contain 2.

Variables don’t contain values, they refer to objects. That’s the
fundamental difference. So if you say, for instance

a = “hello world”
a.upcase!
a #=> “HELLO WORLD”

the message “upcase!” is sent to the object “hello world”, not the
variable a. To see this:

a = “hello world”
b = a
a.upcase!
a #=> “HELLO WORLD”
b #=> “HELLO WORLD”

Fixnums are immutable objects; you can’t have any method that changes
their value. Hence no ++

martin

On 2009-11-04, RichardOnRails
[email protected] wrote:

class Fixnum
def pp # We can?t define ++ because of a compiler restriction.
self + 1
end
end

This doesn’t seem to do the right thing.

a = 1
a.pp

Is a now 2? If not, you haven’t implemented an increment operator.

Appending these lines shows that a & b values are distinct.
That is, after incrementing, a =2, b is unchanged; b is not
impacted by a?s change
a += 1; show (a) => Got 2; class = Fixnum; object_id = 5; v >> 1
= 2
show (b) => Got 1; class = Fixnum; object_id = 3; v >> 1 = 1

Right. You’ve changed which object a refers to, because you’ve
reassigned
a.

Appending these lines shows the ++?s alias pp works just find
a=1; show(a.pp) => Got 2; class = Fixnum; object_id = 5; v >> 1
= 2
show(b) => Got 1; class = Fixnum; object_id = 3; v >> 1 = 1

Not the same. The key is that, after “a += 1”, not only do you get 2,
but a is now 2.

Do you agree?

No.

For “a.pp” to be the same as a++ in other languages, you’d have to do:

a = 1; a.pp; show(a) => Got 2

If you don’t get a “2” by using a.pp, it’s not an increment, just a “one
more than”.

Consider a loop:

a = 1
while ((a += 1) < 10) do
puts a
end

Now, try:

a = 1
while (a.pp < 10) do
puts a
end

Doesn’t do the same thing.

-s

On Nov 4, 2:13 pm, Seebs [email protected] wrote:

a = 1

while (a.pp < 10) do
puts a
end

Doesn’t do the same thing.

-s

Copyright 2009, all wrongs reversed. Peter S. / [email protected]://www.seebs.net/log/<-- lawsuits, religion, and funny pictureshttp://en.wikipedia.org/wiki/Fair_Game_(Scientology) ← get educated!

Hi Peter,

This doesn’t seem to do the right thing.

a = 1
a.pp

Is a now 2? If not, you haven’t implemented an increment operator.

Thanks for this question. You’re so right. I couldn’t see it until
you pointed it out.

class Fixnum
def pp # We can’t define ++ because of a compiler restriction.
self + 1
end
end

doesn’t change self (which Ruby won’t allow for Fixnum’s!!! Which, of
course, is why your:

a = 1
while (a.pp < 10) do
puts a
end

produces an infinite number of 1’s …, or would if RAM were infinite
and hardware addressing mechanisms were infinite.

I grateful for you taking the time to identify my deficiencies.

Best wishes,
Richard

Walton H. wrote:

allow you to send an “increment” message to any object, which would
present!
=> 1.2
irb(main):008:0> i=i.succ
NoMethodError: undefined method succ' for 1.2:Float from (irb):8 from /usr/local/bin/irb:12:in

In an object that it makes sense to increment, define the #succ method!
It’s that easy!

But i.succ does Not work in the following:

i = 1
while (i < 10)
puts i.succ
end

the only way to get this to work is to use:
puts i; i = i.succ

which is not as clean as using puts i++.

On Wed, Nov 4, 2009 at 11:21 AM, Paul S. [email protected]
wrote:

So although a is a Fixnum, and 1 is a Fixnum, they respond to ++
differently?

Why would 1++ be illegal? I’d think it would just evaluate to 1.

Michael W. Ryder wrote:
[…]

But i.succ does Not work in the following:

i = 1
while (i < 10)
puts i.succ
end

the only way to get this to work is to use:
puts i; i = i.succ

which is not as clean as using puts i++.

This is unidiomatic Ruby. In fact, it’s becoming clear to me that just
about any use case for postfix ++ is unidiomatic Ruby. The cleanest
way in Ruby of doing what you did would be

(1…10).each {|i| puts i}

Incrementing is handled under the hood.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

On 2009-11-04, RichardOnRails
[email protected] wrote:

I grateful for you taking the time to identify my deficiencies.

I’d call it an oversight, not a personal failing.

It might make sense to want to be able to do
def pp()
old = self
self = self + 1
old
end

or something similar, but it’s not well-defined. The problem is that
fundamentally, when you have two variables, a and b, which both contain
the object 1 (a Fixnum), there’s no way to say “I want the object a
points
to to change, but not the object b points to” in a method call.
Because
the method call works on the object, not the variable.

-s

On Wed, Nov 4, 2009 at 1:46 PM, Marnen Laibow-Koser
[email protected]wrote:

This is unidiomatic Ruby. In fact, it’s becoming clear to me that just
about any use case for postfix ++ is unidiomatic Ruby. The cleanest
way in Ruby of doing what you did would be

(1…10).each {|i| puts i}

Incrementing is handled under the hood.

What if it’s not?

m = CounterInMemcacheOrSomething.new :foobar
m++

Tony A. wrote:

On Wed, Nov 4, 2009 at 1:46 PM, Marnen Laibow-Koser
[email protected]wrote:

This is unidiomatic Ruby. In fact, it’s becoming clear to me that just
about any use case for postfix ++ is unidiomatic Ruby. The cleanest
way in Ruby of doing what you did would be

(1…10).each {|i| puts i}

Incrementing is handled under the hood.

What if it’s not?

m = CounterInMemcacheOrSomething.new :foobar
m++

What semantics do you intend here? I’m not sure I understand.

In any case, you have several perfectly good alternatives:

  • use CounterInMemcacheOrSomething.all(:foobar).each{|m| …}

  • define CounterInMemcacheOrSomething#succ! if it’s mutable

  • or even use m += 1

++ is very useful in C-like languages and PHP. I thought it would be
useful in Ruby too, but I now believe that it wouldn’t, since it’s only
really good for stepping through structures – and Ruby handles that
better with iterators.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

On Wed, Nov 4, 2009 at 2:41 PM, Marnen Laibow-Koser
[email protected]wrote:

What semantics do you intend here? I’m not sure I understand.

You can think of it like:

alias_method :++, :increment!

puts i; i = i.succ

which is not as clean as using puts i++.

I’d argue it’s much, much cleaner. ++ has long been a source
of confusion for C programmers. Consider:

int i = 1;
while (i < 10)
{
printf("%d,",i++);
}

What does it ouput? 1,2,3,4,5,6,7,8,9, or 2,3,4,5,6,7,8,9,10,?

Because we’re all experienced C programmers here we of course know
it to be 1,2,3,4,5,6,7,8,9, but it’s not uncommon for experienced C
programmers to make mistakes around a++ vs ++a. On the other hand:

int i = 1;
while (i <10)
{
printf("%d,",i);
i+=1;
}

Makes it explicitly clear what is happening. Then consider the ruby
direct ruby translation:

i = 1;
while (i <10)
print “#{i},”
i+=1;
end

Even a non-programmer is going to have a pretty darn clear idea of
what is going on here. Sure it’s one line longer but much more
understandable, and therefore cleaner. If there is one thing
playing Perl Golf should have taught all programmers it’s that
shorter != better.

Now consider the ruby way:

10.times do |i|
print “#{i},”
end

Some length as the C code, but much more readable. Heck, it’s
almost English! Which is part of the beauty of Ruby: It’s simple,
natural, readable syntax. I’ve seen a lot of arguments that it
doesn’t fit with ruby’s object model, but to me that’s not the key
point. ++ doesn’t fit with Ruby’s elegant syntax.

Walton H. wrote:

Now consider the ruby way:

10.times do |i|
print “#{i},”
end

Some length as the C code, but much more readable. Heck, it’s
almost English!

Not for me it wasn’t. I had to try it to see that it actually works.
My initial impression was that it would print 10 copies of i. I still
don’t see where ‘i’ is incremented so this is one of those “magical”
constructs much like your impression of ++ in C. I would find this much
harder to maintain than the C version.

Which is part of the beauty of Ruby: It’s simple,

Michael W. Ryder wrote:

Walton H. wrote:

Now consider the ruby way:

10.times do |i|
print “#{i},”
end

Some length as the C code, but much more readable. Heck, it’s
almost English!

Not for me it wasn’t. I had to try it to see that it actually works.
My initial impression was that it would print 10 copies of i. I still
don’t see where ‘i’ is incremented

Well, you do have to know what Numeric#times yields to its block. But
that’s easy to look up. (However, it starts from 0, so it’s not quite
equivalent to the C.)

so this is one of those “magical”
constructs much like your impression of ++ in C.

No. The “magic” is different. In the Ruby version, a quick check in
the API tells you that the counter is incremented each time through the
loop. In the C version, OTOH, you have to think about exactly where
you’ve put the ++, and whether you really wanted the value before or
after the increment.

I would find this much
harder to maintain than the C version.

Only because you apparently are not familiar with common Ruby idioms.
The Ruby version has a lot less to go wrong in it, because the language
transparently handles incrementing the “loop index” at the right time.

Which is part of the beauty of Ruby: It’s simple,

Yes. Just don’t expect it to be much like C.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Well, you do have to know what Numeric#times yields to its block. But
that’s easy to look up. (However, it starts from 0, so it’s not quite
equivalent to the C.)

Whoop! Good point, that’s what I get for not actually testing my code.

Corrected (and even closer to English).

(1…9).each do |i|
print “#{i},”
end

Michael Wrote:

Not for me it wasn’t. I had to try it to see that it actually works.
My initial impression was that it would print 10 copies of i.
I still don’t see where ‘i’ is incremented

It isn’t incremented, at least not in MY code (if you must think in
terms of incrementing variables, then Ruby is incrementing it for me)
See the times method at:
http://ruby-doc.org/core/classes/Integer.html
That kind of looping is a pretty core Ruby concept.

Also the corrected version I wrote above should be a bit clearer. Also
I think your previous programming experience is hurting you here. To you
as (I’m guessing) a C programmer, to progress in a loop, you must
increment
modify variable. The average English speaker doesn’t think in those
terms.

Looking at my most recent example, the English equivalent would be for
each
‘i’ from 1 to 9 print ‘i’ followed by a comma. Sure, the words may not
be
in the precise order, but it comes a darn site closer to natural
language than:

int i=1;
while (i<10)
{
printf(“%d,”,i++);
}

Walton H. wrote:

Well, you do have to know what Numeric#times yields to its block. But

That version I understand just looking at it as it is equivalent to a
for loop. Your first version seemed more “magical” since I don’t know
where ‘i’ is getting incremented. At least with C I know where the
incrementing is occurring.

Also the corrected version I wrote above should be a bit clearer. Also
I think your previous programming experience is hurting you here. To you
as (I’m guessing) a C programmer, to progress in a loop, you must increment
modify variable. The average English speaker doesn’t think in those terms.

I started with Fortran in the early 1980’s, followed by Basic, Pascal,
Modula 2, and C. For over 25 years I have been mostly programming in
Business Basic. While Ruby has a lot of things going for it I miss some
of the features available in the other languages, especially the built
in curses and file handling in Business Basic.

On Nov 5, 4:11 am, Tony A. [email protected] wrote:

end

I could see this as being handy

What’s wrong with

def inc
incrementing_logic_goes_here
end

How is that any different?

Hi,

In message “Re: Ruby doesn’t implement x++ for Fixnum’s because ???”
on Thu, 5 Nov 2009 04:25:05 +0900, RichardOnRails
[email protected] writes:

|BTW, I’m not advocating x++ for Ruby. I’m just trying to understand
|whether Ruby would literally change 1 to 2 as opposed to change a
|variable that contains 1 to subsequently contain 2.

There’s no way to modify local variables by sending message in Ruby.

          matz.