Preserving Leading Zeros Using sprintf


#1

From http://www.rubycentral.com/ref/ref_c_array.html#collect_oh:

“Invokes block once for each element of arr, replacing the element with
the value returned by block.”

Okay, so I attempt to execute the following code:

a=3
b=8
[a,b].collect! { |c| c = sprintf(’%02d’, c) }
puts a # prints out 3 and not 03

However, this code:

a=3
b=8
(a,b) = [a,b].collect! { |c| c = sprintf(’%02d’, c) }
puts a # prints out 03

Why is that?

If it’s of any use, this is ruby 1.8.4 (2005-12-24) [i386-cygwin].

Thanks for demystification.


#2

On 5/26/06, Jeremy S. removed_email_address@domain.invalid wrote:

a=3
b=8
[a,b].collect! { |c| c = sprintf(’%02d’, c) }
puts a # prints out 3 and not 03

You’ve been bit by the “variables == objects” mentality. When you
perform your #collect!, each element of the receiver of #collect! is
replaced by the result of the yield. See this:

a = 3
b = 8
c = [a, b]
c.collect! { |x| x = sprintf(’%02d’, x) }
puts c[0] # prints ‘03’

So when #collect! operates on the first element, it’s essentially as
such:

c[0] = sprintf(’%02d’, c[0])

This puts a new object in that slot of the array; it doesn’t alter
the object that was previously in that slot. The variable a still
refers to the old object, not the new one.

Jacob F.