From: "Mauricio Fernández" Date: 2003-06-12T23:01:46+09:00 Subject: Re: does each work on a copy? On Thu, Jun 12, 2003 at 10:46:45PM +0900, Rasputin wrote: > SPACE = 1 > > a = Array.new(5) > b = Array.new(5, SPACE) > > a.each { |el| > el = SPACE > } You are *not* modifying the elements inside a. a.each { |el| works like the following: a.each { el = corresponding_element_from_a If you assign to el you'll only change the reference (ie. what the local is pointing to), not the underlying object. However the following would work a.each_with_index { |el,i| a[i] = SPACE } (it is ugly and inefficient, though) > puts "a = #{a.join("-")}" > puts "b = #{b.join("-")}" > > ----------------8<---------------- > > I'd expect to have a first output line similar to the second,but I get: > > rasputin@shrike rasputin$ ruby /tmp/q > a = ---- > b = 1-1-1-1-1 > rasputin@shrike rasputin$ > > Now, is this because each is returning a copy of the element? It is giving you a *reference* to the element. Consider: >> a = %w{BLA FOO BAZ} => ["BLA", "FOO", "BAZ"] >> a.each{ |x| x.downcase! } => ["bla", "foo", "baz"] >> a => ["bla", "foo", "baz"] > It's the most plausible explanation > (because if I replace a.each with a.collect! it works as I expected) > but if so I'm surprised it hasn't bitten me on the ass before. collect! works because the value of 'el = SPACE' is SPACE, and collect takes the value of the block in each iteration. -- _ _ | |__ __ _| |_ ___ _ __ ___ __ _ _ __ | '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ | |_) | (_| | |_\__ \ | | | | | (_| | | | | |_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_| Running Debian GNU/Linux Sid (unstable) batsman dot geo at yahoo dot com You will not censor me through bug terrorism. -- James Troup