From: Dave Thomas Date: 2000-11-23T07:50:09+09:00 Subject: [ruby-talk:6534] Re: Question about the behavior of write attributes in blocks "Christoph Rippel" writes: > Thank you for explanation - the output of "x".inspect() is > > >>"x" > > which made me assume that Strings are implemented as singletons (which > doesn't make much sense in the presence of a replace() method). > > I was hoping to be able to write > *********** > x = [1,2,3] > x.each { |i| i+= 1 } You could write this as [1,2,3].collect! {|i| i+1} # => [2, 3, 4] This replaces each value with the result of the block. > but there is no such method for Fixnum and the only way I can think about > writing such a method always involves the use of the ``=()''-operator - > which means I am effectively stuck. The String Class seems to be one of the > few build in classes sporting a replace() method so I can write There's a reason for this. Let's go back to Strings a = "cat" # => "cat" b = a # => "cat" a[0] = "b" b # => "bat" We changed 'a', but 'b' got the value too. Why? Because both a and b reference the same string object. Now, let's look at what would happen if Fixnum had the same behavior: ## not real code ## a = 1 # => 1 b = a # => 1 b.increment # => 2 a # => 2 So we've just changed the value of '1' throughout the system. This would be "a bad thing". So, Fixnums have value semantics, not reference semantics. Variables hold the value, not a reference to the value. That's why your first example doesn't work: [1,2,3].each { |i| i += 1 } The variable 'i' receives successive Fixnum values, not references. Changes to the value stored in the variable therefore don't affect numbers globally. > This is only a stop-cap measure since I really want to manipulate > Arrays (or binary trees) of Fixnum or more general any Object. Your collection can provide a #collect! method to change the values. Regards Dave