# Strange thing w/ array.map

**URL:** <https://www.ruby-forum.com/t/strange-thing-w-array-map/83329>\
**Category:** Rails\
**Created:** [January 25, 2007, 8:01am UTC](https://www.ruby-forum.com/t/strange-thing-w-array-map/83329 "2007-01-25T08:01:46Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![clemrock](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/c57346/32.png) [@clemrock](https://www.ruby-forum.com/u/clemrock)\
**Post date:** [January 25, 2007, 8:01am UTC](https://www.ruby-forum.com/t/strange-thing-w-array-map/83329/1 "2007-01-25T08:01:46Z")

</div>

Hello,

```
I'm writing a method that builds rss and atom feeds and I've noticed

```

something strange when I try updating the content array by using a map.

I’m new to ruby and must confess that I don’t know how array maps work  
so well.

I am formatting some of the rss content array by updating it’s contents  
w/ a map like so:

```auto
@entities = Space.find :all

@new_entities = @entities.map do |entity|
  open_closed = entity.complete? ? "[x] " : "[] "
  entity.title = open_closed + entity.title
  entity.title += (' due on ' + local_date_time(entity.due_on)) if
entity.due_on
  entity.title += " (#{entity.status_title})"
end if @entities
```

then when I try to use the @new\_entities array in the feed, I get an  
error

```auto
for entity in @new_entities #-->>error!
  xml.item do
    xml.title(entity.title)
    xml.description(entity.description)
    xml.pubDate(entity.date.strftime("%a, %d %b %Y %H:%M:%S %z"))
    xml.link("http://www.recentrambles.com/pragmatic/view/" +
entity.id.to_s)
    xml.guid("http://www.recentrambles.com/pragmatic/view/" +
entity.id.to_s)
  end
end
```

but, if I use the original @entities array it works perfectly

```auto
for entity in @entities #-->>works!
  xml.item do
    xml.title(entity.title)
    xml.description(entity.description)
    xml.pubDate(entity.date.strftime("%a, %d %b %Y %H:%M:%S %z"))
    xml.link("http://www.recentrambles.com/pragmatic/view/" +
entity.id.to_s)
    xml.guid("http://www.recentrambles.com/pragmatic/view/" +
entity.id.to_s)
  end
end
```

How, exactly, is that @entities array getting updated by the map?

Thanks for your help!

---

<div class="post-metadata">

**Author:** ![clemrock](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/c57346/32.png) [@clemrock](https://www.ruby-forum.com/u/clemrock)\
**Post date:** [January 25, 2007, 4:10pm UTC](https://www.ruby-forum.com/t/strange-thing-w-array-map/83329/2 "2007-01-25T16:10:31Z")

</div>

2 things are going on here

1. i don’t believe you are getting back what you think you are getting  
back from .map
2. the entity you are working with in your block is the actual entity,  
not a copy. so you are basically overwriting your original array of  
entities

.map returns a new array based on whatever it is you do in within the  
block

[1,2,3].map { |x| x\*3 } #=\> [3,6,9]

in your case the last statement in the block is

entity.title += " (#{entity.status\_title})"

so your block is going to return whatever that evaluates to, not the  
entity object you are expecting.

in addition, your block is actually overwriting all the values of the  
@entities objects you are passing in. if you were to compare the  
titles of the @entities objects before and then after .map is called,  
you’re going to see that they are different.

ex:

class Thing  
attr\_accessor :foo  
end

a = Thing.new  
a.foo = “abc”  
b = Thing.new  
b.foo = “xyz”

x = [a,b].map { |c| c.foo += " modified" }  
a.foo # =\> “abc modified”  
b.foo # =\> “xyz modified”  
x = [“abc modified”, “xyz modified”] # you expected this to be an  
array of Thing objects

if you do want to overwrite the attributes of your objects, just use  
.each

@entities.each do |entity|  
…  
end

---

<div class="post-metadata">

**Author:** ![clemrock](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/c57346/32.png) [@clemrock](https://www.ruby-forum.com/u/clemrock)\
**Post date:** [January 25, 2007, 8:39pm UTC](https://www.ruby-forum.com/t/strange-thing-w-array-map/83329/3 "2007-01-25T20:39:44Z")

</div>

Chris,

Thanks for your help - this is great.

Ruby does things I never expect - in the best of ways.

Cheers!

Chris H. wrote:

> 2 things are going on here
> 
> 1. i don’t believe you are getting back what you think you are getting  
> back from .map
> 2. the entity you are working with in your block is the actual entity,  
> not a copy. so you are basically overwriting your original array of  
> entities
> 
> .map returns a new array based on whatever it is you do in within the  
> block
> 
> [1,2,3].map { |x| x\*3 } #=\> [3,6,9]
> 
> in your case the last statement in the block is
> 
> entity.title += " (#{entity.status\_title})"
> 
> so your block is going to return whatever that evaluates to, not the  
> entity object you are expecting.
> 
> in addition, your block is actually overwriting all the values of the  
> @entities objects you are passing in. if you were to compare the  
> titles of the @entities objects before and then after .map is called,  
> you’re going to see that they are different.
> 
> ex:
> 
> class Thing  
> attr\_accessor :foo  
> end
> 
> a = Thing.new  
> a.foo = “abc”  
> b = Thing.new  
> b.foo = “xyz”
> 
> x = [a,b].map { |c| c.foo += " modified" }  
> a.foo # =\> “abc modified”  
> b.foo # =\> “xyz modified”  
> x = [“abc modified”, “xyz modified”] # you expected this to be an  
> array of Thing objects
> 
> if you do want to overwrite the attributes of your objects, just use  
> .each
> 
> @entities.each do |entity|  
> …  
> end
