Strange, I tried the example from Jonathan Kohl, and it worked fine.

The idea in Ruby is that variables hold references to objects not the
objects themselves similar to Java. If you've worked in c/c++ this will make
more sense, Ruby, Java and some other languages hide the ugliness of this
under the covers. So when you create a variable and assign it to something,
it's holding a pointer to the actual object. When you then assign that to
another variable, you've now got two variables pointed to the same object in
memory.

a = 'foo'     # create a variable named a that points to an object somewhere
in memory
b = a         # now create b which will point to that same object in memory,
in this case a string object
puts a.object_id
=> object_id whatever
puts b.object_id
=> the same object_id since they both point to the same object in memory

Enumerating through a collection of some sort like an Array, makes it a bit
more confusing. If you end up returning strings, for example, then those are
new objects which won't then hold reference to the original objects in your
collection. Hopefully that makes some sense. :)

-Charley


On 3/5/07, Chris McMahon <[EMAIL PROTECTED]> wrote:

On 3/5/07, vijay <[EMAIL PROTECTED]> wrote:
> Thank you Zeljko Filipin.  That was an useful and an interesting '.pdf'.
>
> Thanks,
> Vijay.

For those interested in both history and the vagaries of OO
programming, the original issue was a problem I stumbled across and
mentioned on the list for people reviewing Brian's book.  It's an
interesting issue, and a good thing to be aware of, if you aren't
already.  For me, it comes up when I work with databases, since what
comes back from Ruby ODBC is almost always an AoA, and that's where I
got into trouble...

#########################################
require 'test/unit'
class TOY_CASE<Test::Unit::TestCase

def test_toy_test

aoa = [[1,2,3],[4,5,6]]

aoa.each do |arr|
       arr.each do |item|
               item = item.to_s
               end
               assert_equal(["1","2","3"],arr)
end

end #def
end #class
#####################################
1) Failure:
test_toy_test(TOY_CASE)
   [bar.rb:12:in `test_toy_test'
    bar.rb:8:in `each'
    bar.rb:8:in `test_toy_test']:
<["1", "2", "3"]> expected but was
<[1, 2, 3]>.

1 tests, 1 assertions, 1 failures, 0 errors
>Exit code: 1

I had to go to the comp.lang.ruby list for an answer.  Even my local
Ruby guru didn't see the problem immediately.

Apparently inside an "each" loop you're only working on a copy of the
item, not the item itself, so to_s isn't actually working on the real
items in the array.

To make this work, you have to use "map":

aoa.each do |arr|
       arr.map! do |item|
               item = item.to_s
               end


Jonathan Kohl mentions an opposite but similar weirdness:

a = %w[a b c]
b = a
b = %w[x y z]
p a
=>
x y z
p b
=>
x y z
when what was expected was this:
p a
=>
["a", "b", "c"]
_______________________________________________
Wtr-general mailing list
Wtr-general@rubyforge.org
http://rubyforge.org/mailman/listinfo/wtr-general

_______________________________________________
Wtr-general mailing list
Wtr-general@rubyforge.org
http://rubyforge.org/mailman/listinfo/wtr-general

Reply via email to