That's Ruby, Virginia!

Well, you wrote a great Array Analyzer
Here it is:

def array_101
for i in [0 … self.length]
puts “#{i} => #{self[i]}”
end
end

And prepared the following array for test:

a = [‘a’,‘s’,‘d’]

What do you think, it will print?

Yeeees, you are right.
And the answer is…

0…3 => asd

:-)))))))))

try it at home:

irb(main):001:0> def array_101
irb(main):002:1> for i in [0 … self.length]
irb(main):003:2> puts “#{i} => #{self[i]}”
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> a = [‘a’,‘s’,‘d’]
=> [“a”, “s”, “d”]
irb(main):007:0> a.array_101
0…3 => asd
=> [0…3]
:wink:

Henry S. [email protected] writes:

Well, you wrote a great Array Analyzer
Here it is:

def array_101
for i in [0 … self.length]
puts “#{i} => #{self[i]}”
end
end

for i in 0 … self.length
does what you would expect. In your example you iterate over an array
with one element, and this element is a range. So the result isn’t
really
unexpected.

Tom

Henry S. wrote:

Here it is:

def array_101
for i in [0 … self.length]
puts “#{i} => #{self[i]}”
end
end

class Array
def array_101
each_with_index{|e,i|
puts “#{i} => #{e}”
}
end
def array_102
puts (0…self.size).zip(self).map{|a| a.join(’ => ')}
end
end

On 8/25/06, William J. [email protected] wrote:

def array_101
each_with_index{|e,i|
puts “#{i} => #{e}”
}
end
def array_102
puts (0…self.size).zip(self).map{|a| a.join(’ => ')}
end
end

Much better this way.

To fix the original code, use (0…self.length) - note these are not
square brackets. Alternatively, you can use (0…10).to_a to turn a
range into an array.

Max

Henry S. wrote:

a = [‘a’,‘s’,‘d’]

What do you think, it will print?

Yeeees, you are right.
And the answer is…

0…3 => asd

:slight_smile: Well, it did exactly what you said
it should do. It iterated over the
contents of the array [0…self.length]
(which has only one element, the range
0…self.length).

Cheers,
Hal

Your code only works in irb. You get an error, as you should, if you
run it ‘real’ Ruby.
In irb ‘array_101’ gets added to Array. That’s the only reason
‘a.array_101’ doesn’t produce an error. In “real” Ruby, the following
produces your result, as it should.

#! /usr/bin/ruby -w

class Array
def array_101
for i in [0…length]
p self[i] ### prints the array because i = 0…length, not 0.
puts “#{i} => #{self[i]}”
end
end
end

a = %w[a s d]

a.array_101

["a", "s", "d"] 0...3 => asd

The only thing I don’t understand is why ‘array_101’ gets added to
Array in irb.

Regards, Morton

Thanks. You’ve cleared up my confusion as to why array_101 accepts an
array as a receiver in irb. Since it gets added as public method of
Kernel, it appears as a public method of every class in irb. I
think that’s evil enough to be regarded as a bug.

Regards, Morton

Thank you, guys for trying to fix the code. Sure, I had 1001 way to fix
it and I did.
The reason for the post was to inform community about the case. For me
with a long dinosaurâ??s tail of various languages it is unexpectable yet,
however I could understand the logic behind it.

Is it a bug or feature, I do not know. At least it was something, people
should know :wink:

Thank you
Henry

On 8/24/06, Morton G. [email protected] wrote:

def array_101
["a", "s", "d"] 0...3 => asd

The only thing I don’t understand is why ‘array_101’ gets added to
Array in irb.

It doesn’t it gets added to the Kernel module, just like in real Ruby.

The difference is that in irb, it’s a public method and in real Ruby
it’s private, I think that this came up in another context in the past
few days.

== file array_101.rb ==
def array_101
for i in [0…self.length]
puts “#{i} => #{self[i]}”
end
end

a = [‘a’, ‘s’, ‘d’]
p a
p a.array_101

class X
end

p X.new.array_101
=== end of file array101.rb===
$ ruby array101.rb
[“a”, “s”, “d”]
array101.rb:9: private method `array_101’ called for [“a”, “s”,
“d”]:Array (NoMethodError)

but change the file to wrap the method in the Kernel module
module Kernel
def array_101

end
end

$ ruby array101.rb
[“a”, “s”, “d”]
0…3 => asd
[0…3]
array101.rb:3:in array_101': undefined method length’ for
#<X:0xb7e1f7b4> (NoMethodError)
from array101.rb:16

Note that we are getting through a.array_101, but now we blow up on
X.new.array_101, but INSIDE the array_101 method, because since it’s
in Kernel, and class Object includes Kernel, makes it available to ALL
objects.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

IPMS/USA Region 12 Coordinator
http://ipmsr12.denhaven2.com/

Visit the Project Mercury Wiki Site
http://www.mercuryspacecraft.com/

Well, that is a modification. No public\private\irb etc… :)))

=============Program ====================
#Version 2. For native Ruby
puts “Source is: #$0”
puts “File is: #{FILE}”

class Array
def array_101A
for i in [0 … self.length]
puts “#{i} => #{self[i]}”
end
end
end

a = [‘a’,‘s’,‘d’]
a.array_101A

=========== Results ======================
C:\Documents and Settings\Admin>ruby -w c:/PJ/play/test/lib/t3.rb
Source is: c:/PJ/play/test/lib/t3.rb
File is: c:/PJ/play/test/lib/t3.rb
0…3 => asd

On 8/27/06, Henry S. [email protected] wrote:

Thank you, guys for trying to fix the code. Sure, I had 1001 way to fix
it and I did.
The reason for the post was to inform community about the case. For me
with a long dinosaur’s tail of various languages it is unexpectable yet,
however I could understand the logic behind it.

Is it a bug or feature, I do not know. At least it was something, people
should know :wink:

It was a bug in your code. You used [0…value] when you should have
used (0…value).

Cheers,
Max

I don’t want to rain on your parade, especially because I can’t
figure out why you’re having a parade. I could understand a newbie
being puzzled about this code (because he wrote [0 … length] where
he should used 0 … length) and posting it so someone could explain
why it works the way it does, but you say that’s not your situation.
Could you be more explicit about what amuses, delights, intrigues, or
otherwise motivates you to bring this to our attention?

Regards, Morton

Max M. wrote:

On 8/27/06, Henry S. [email protected] wrote:

Thank you, guys for trying to fix the code. Sure, I had 1001 way to fix
it and I did.
The reason for the post was to inform community about the case. For me
with a long dinosaur’s tail of various languages it is unexpectable yet,
however I could understand the logic behind it.

Is it a bug or feature, I do not know. At least it was something, people
should know :wink:

It was a bug in your code. You used [0…value] when you should have
used (0…value).

Cheers,
Max
Why,
The Programming Ruby suggests using for for Array. Unfortunately I
don’t have the book with me. I will tell you the page. And it is logical
to use it for array.
Cheers,
Henry

Morton G. wrote:

I don’t want to rain on your parade, especially because I can’t
figure out why you’re having a parade. I could understand a newbie
being puzzled about this code (because he wrote [0 … length] where
he should used 0 … length) and posting it so someone could explain
why it works the way it does, but you say that’s not your situation.
Could you be more explicit about what amuses, delights, intrigues, or
otherwise motivates you to bring this to our attention?

Regards, Morton

Well,
I bring it to your attention because:
It mentioned in Programming Ruby, that for works with array. They gave
the example of song array. All languages, which I am familiar with work
the same way. They

  • take an item from Array,
  • execute the block,
  • and then take another item

So as [0 … len] is a new Array, I expected the same behaviour.
But it was not so obvious. It took the whole array and executes the
statement ones. I would expect this behaviour if the code were

for i = [0 … len]

So, my question was to persons, who realy UNDERSTAND Ruby internal
logic, what was it, a bug or undocumented (or may be documented, but I
just missed it) feature?

Regards,
Henry

So as [0 … len] is a new Array, I expected the same behaviour.
But it was not so obvious. It took the whole array and executes the
statement ones.

[0…len] is Array. Which holds only one Range object:

a = [1…5]
=> [1…5]

a.class
=> Array

a.length
=> 1

a[0].class
=> Range

Regards,
Rimantas

On Sep 2, 2006, at 4:51 PM, Henry S. wrote:

So as [0 … len] is a new Array,

It’s a new array of size 1 though.

0…len is a single object
what you wrote was
x = 0…len

for i in [x]

Ruby is not perl, … does not construct lists.

I expected the same behaviour.
But it was not so obvious. It took the whole array and executes the
statement ones. I would expect this behaviour if the code were

for i = [0 … len]

So, my question was to persons, who realy UNDERSTAND Ruby internal
logic, what was it, a bug or undocumented (or may be documented, but I
just missed it) feature?

It’s neither a bug or a feature. You just didn’t grasp the syntax.

Logan C. wrote:

0…len is a single object
what you wrote was
x = 0…len

for i in [x]

Ruby is not perl, … does not construct lists.

Thank you very much, Logan C…

That was the open eyes explanation, I wanted to get.
The case is closed.

Rimantas L. wrote:

[0…len] is Array. Which holds only one Range object:

While I was writing, I got another message, thank you, Rimantas