# Why doesn't "to\_s" DWIM?

**URL:** <https://www.ruby-forum.com/t/why-doesnt-to-s-dwim/55638>\
**Category:** Ruby\
**Created:** [March 22, 2006, 5:18pm UTC](https://www.ruby-forum.com/t/why-doesnt-to-s-dwim/55638 "2006-03-22T17:18:54Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Chris\_McMahon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/74df32/32.png) [@Chris\_McMahon](https://www.ruby-forum.com/u/Chris_McMahon)\
**Post date:** [March 22, 2006, 5:18pm UTC](https://www.ruby-forum.com/t/why-doesnt-to-s-dwim/55638/1 "2006-03-22T17:18:54Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Chris\_McMahon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/74df32/32.png) [@Chris\_McMahon](https://www.ruby-forum.com/u/Chris_McMahon)\
**Post date:** [March 22, 2006, 5:25pm UTC](https://www.ruby-forum.com/t/why-doesnt-to-s-dwim/55638/2 "2006-03-22T17:25:28Z")

</div>

Hi –

On Thu, 23 Mar 2006, Chris McMahon wrote:

> ##########################################  
> Inside the inner each block, you’re just doing a local (re)assignment  
> to “item”. There’s no connection to the object that used to be in  
> item, except that that object happens to be part of the rhs.

You can achieve what you want with this:

aaa.each do |arr|  
arr.map! do |item|  
item.to\_s  
end  
end

That will go through each inner array and replace the current item  
with what’s in the block (namely, item.to\_s).

David

–  
David A. Black (removed\_email\_address@domain.invalid)  
Ruby Power and Light, LLC ([http://www.rubypowerandlight.com](http://www.rubypowerandlight.com))

“Ruby for Rails” chapters now available  
from Manning Early Access Program! [Ruby for Rails](http://www.manning.com/books/black)

---

<div class="post-metadata">

**Author:** ![Chris\_McMahon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/74df32/32.png) [@Chris\_McMahon](https://www.ruby-forum.com/u/Chris_McMahon)\
**Post date:** [March 22, 2006, 5:28pm UTC](https://www.ruby-forum.com/t/why-doesnt-to-s-dwim/55638/3 "2006-03-22T17:28:12Z")

</div>

On Thu, 2006-03-23 at 01:18 +0900, Chris McMahon wrote:

> 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”].

---

<div class="post-metadata">

**Author:** ![Chris\_McMahon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/74df32/32.png) [@Chris\_McMahon](https://www.ruby-forum.com/u/Chris_McMahon)\
**Post date:** [March 22, 2006, 5:29pm UTC](https://www.ruby-forum.com/t/why-doesnt-to-s-dwim/55638/4 "2006-03-22T17:29:19Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![Chris\_McMahon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/74df32/32.png) [@Chris\_McMahon](https://www.ruby-forum.com/u/Chris_McMahon)\
**Post date:** [March 22, 2006, 7:14pm UTC](https://www.ruby-forum.com/t/why-doesnt-to-s-dwim/55638/5 "2006-03-22T19:14:01Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Chris\_McMahon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/74df32/32.png) [@Chris\_McMahon](https://www.ruby-forum.com/u/Chris_McMahon)\
**Post date:** [March 22, 2006, 5:27pm UTC](https://www.ruby-forum.com/t/why-doesnt-to-s-dwim/55638/6 "2006-03-22T17:27:21Z")

</div>

You might want to look at Array#map

arr.map do |item|  
item.to\_s  
end

---

<div class="post-metadata">

**Author:** ![Chris\_McMahon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/74df32/32.png) [@Chris\_McMahon](https://www.ruby-forum.com/u/Chris_McMahon)\
**Post date:** [March 22, 2006, 9:29pm UTC](https://www.ruby-forum.com/t/why-doesnt-to-s-dwim/55638/7 "2006-03-22T21:29:01Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Chris\_McMahon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/74df32/32.png) [@Chris\_McMahon](https://www.ruby-forum.com/u/Chris_McMahon)\
**Post date:** [March 22, 2006, 11:10pm UTC](https://www.ruby-forum.com/t/why-doesnt-to-s-dwim/55638/8 "2006-03-22T23:10:52Z")

</div>

On Thu, 2006-03-23 at 05:28 +0900, benny wrote:

> > > end #def
> 
> 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’.

---

<div class="post-metadata">

**Author:** ![Chris\_McMahon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/74df32/32.png) [@Chris\_McMahon](https://www.ruby-forum.com/u/Chris_McMahon)\
**Post date:** [March 22, 2006, 9:48pm UTC](https://www.ruby-forum.com/t/why-doesnt-to-s-dwim/55638/9 "2006-03-22T21:48:58Z")

</div>

benny wrote:

> 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
