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:

···

--
Posted via http://www.ruby-forum.com/.

Henry Savr <hsavr@yahoo.com> 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 Savr 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

Henry Savr wrote:

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

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

<code>
#! /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
</code>

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

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

Regards, Morton

···

On Aug 24, 2006, at 12:57 PM, Henry Savr wrote:

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:

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

···

On 8/25/06, William James <w_a_x_man@yahoo.com> wrote:

Henry Savr 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

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.

···

On 8/24/06, Morton Goldberg <m_goldberg@ameritech.net> wrote:

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.

<code>
#! /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
</code>

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

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

--
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/

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

···

--
Posted via http://www.ruby-forum.com/.

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

···

On Aug 25, 2006, at 1:32 PM, Rick DeNatale wrote:

On 8/24/06, Morton Goldberg <m_goldberg@ameritech.net> wrote:

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.

<code>
#! /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
</code>

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

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

···

--
Posted via http://www.ruby-forum.com/.

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

Cheers,
Max

···

On 8/27/06, Henry Savr <hsavr@yahoo.com> 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:

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

···

On Aug 28, 2006, at 1:26 PM, Henry Savr wrote:

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

--
Posted via http://www.ruby-forum.com/.

Max Muermann wrote:

···

On 8/27/06, Henry Savr <hsavr@yahoo.com> 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

--
Posted via http://www.ruby-forum.com/.

Morton Goldberg 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

···

--
Posted via http://www.ruby-forum.com/.

Morton Goldberg 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,

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.

···

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

Regards,
Henry

--
Posted via http://www.ruby-forum.com/.

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

···

--
http://rimantas.com/

Logan Capaldo 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 Capaldo.

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

···

--
Posted via http://www.ruby-forum.com/.

Rimantas Liubertas wrote:

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

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

···

--
Posted via http://www.ruby-forum.com/.