[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

why doesn't "to_s" DWIM?

Chris McMahon

3/22/2006 4:16:00 PM


How come to_s doesn't work here?

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

8 Answers

dblack

3/22/2006 4:24:00 PM

0

Farrel Lifson

3/22/2006 4:25:00 PM

0

You might want to look at Array#map

arr.map do |item|
item.to_s
end

On 3/22/06, Chris McMahon <christopher.mcmahon@gmail.com> wrote:
>
> How come to_s doesn't work here?
>
> ####################################
> 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
> ##########################################
>
>
>


Ross Bamford

3/22/2006 4:26:00 PM

0

On Thu, 2006-03-23 at 01:18 +0900, Chris McMahon wrote:
> How come to_s doesn't work here?
>
> ####################################
> 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
> ##########################################

Each just iterates the items, and the 'items' argument to the block is a
new local variable - changing it has no lasting effect. Try map instead
(here I use map! to change this array, rather than creating a new one):

##########################################
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.map! do |item|
item.to_s
end
end

assert_equal [["1","2","3"],["4","5","6"]], aoa
end #def
end #class
##########################################

Notice too I changed the way your assertion works, since it would fail
on the second array if tested against ["1","2","3"].

--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk



Peter Hickman

3/22/2006 4:27:00 PM

0

I'm not really sure what you are expecting to happen here. aoa.each will
product two results, first [1,2,3] and then [4,5,6]. And you expect the
assert_equal to pass both times?



Chris McMahon

3/22/2006 6:12:00 PM

0

Thanks, I knew it had to be something like that.

benny

3/22/2006 8:26:00 PM

0

>> 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
>> ##########################################
>
> Each just iterates the items, and the 'items' argument to the block is a
> new local variable - changing it has no lasting effect.
but remember:

a = ["haha", "hihi", "hoho"]
a.each { |i| i.gsub!("h", "l") }
p a

and even

a = ["2","3", "4"]
a.each { |i| i.replace("#{i} times") }
p a

in fact variables only point to the objects. so you might use them to modify
the object they are currently pointing to. if you got strings, you may
modify them (instead of creating new ones). but unfortunately that won't
work for numbers, since they are no real objects, but - how do we call
them? - first level objects?

benny


> Try map instead
> (here I use map! to change this array, rather than creating a new one):
>
> ##########################################
> 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.map! do |item|
> item.to_s
> end
> end
>
> assert_equal [["1","2","3"],["4","5","6"]], aoa
> end #def
> end #class
> ##########################################
>
> Notice too I changed the way your assertion works, since it would fail
> on the second array if tested against ["1","2","3"].
>

benny

3/22/2006 8:44:00 PM

0

benny wrote:

>
> a = ["2","3", "4"]
> a.each { |i| i.replace("#{i} times") }
> p a
>
> in fact variables only point to the objects. so you might use them to
> modify the object they are currently pointing to. if you got strings, you
> may modify them (instead of creating new ones). but unfortunately that
> won't
> work for numbers, since they are no real objects, but - how do we call
> them? - first level objects?
so this would work also:

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

aoa.each do |arr|
arr.each_index do |i|
arr[i] = arr[i].to_s
end
end

p aoa

>
> benny
>
>

Ross Bamford

3/22/2006 10:11:00 PM

0

On Thu, 2006-03-23 at 05:28 +0900, benny wrote:
> >> 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
> >> ##########################################
> >
> > Each just iterates the items, and the 'items' argument to the block is a
> > new local variable - changing it has no lasting effect.
> but remember:
>
> a = ["haha", "hihi", "hoho"]
> a.each { |i| i.gsub!("h", "l") }
> p a
>
> and even
>
> a = ["2","3", "4"]
> a.each { |i| i.replace("#{i} times") }
> p a
>
> in fact variables only point to the objects. so you might use them to modify
> the object they are currently pointing to. if you got strings, you may
> modify them (instead of creating new ones). but unfortunately that won't
> work for numbers, since they are no real objects, but - how do we call
> them? - first level objects?
>

True, this is why the updated code I and others posted mostly retained
the outer 'each', and used map! on each inner array.

I think the term for Fixnums, nil, true and false is 'immediate values'.

--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk