Re: strange thing w/ array.map

Chris Hall
Thu, 25 Jan 2007 15:09:43 -0000

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

On 1/25/07, Clem Rock
<rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org>
wrote:
>
> 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:
>
> [code]
> @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
> [/code]
>
> then when I try to use the @new_entities array in the feed, I get an
> error
>
> [code]
> 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
> [/code]
>
> but, if I use the original @entities array it works perfectly
> [code]
> 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
> [/code]
>
>
> How, exactly, is that @entities array getting updated by the map?
>
> Thanks for your help!
>
> --
> Posted via http://www.ruby-forum.com/.
>
> >
>