From: Josh Cheek Date: 2011-08-10T04:20:27+09:00 Subject: Re: *WHY* does this not work? --90e6ba61375c3cc69904aa176e39 Content-Type: text/plain; charset=ISO-8859-1 On Tue, Aug 9, 2011 at 1:52 PM, serialhex wrote: > ok, so code: > > str = 'foo' > => "foo" > str.each_char do |c| > c = 'x' > end > => "foo" > > WHY does str == 'foo' still?? i would expect it to be 'xxx'! this makes no > sense, and is *QUITE* annoying... i end up having to do things like this: > > There are two reasons. 1) `c` is a variable. When you say `c = 'x'`, you are updating the object that the variable c is pointing to, not invoking some sort of setter on the string you are iterating over (which _is_ what you are doing in the array example when you invoke the #[]= method). 2) Even if you were able to actually change the string, ie using `c.replace 'x'` rather than `c = x`, it wouldn't matter, because the char that `c` is pointing to is a completely different string than `str`. I don't know what you're trying to do, so I can't suggest a better solution, but there is a way to do what you are asking using `String#gsub!` str = "abc" str.gsub!(/./) { |char| 'x' } str # => "xxx" > ... i CAN'T do things like that for a string because it dsn't seem to do > that, but for an array i'd have to: > > ary = ['f', 'o', 'o'] > => ["f", "o", "o"] > ary.each_index do |i| > ary[i] = 'x' > end > => ["x", "x", "x"] > > GAH!!! least surprise?? least surprise my FOOT!!! even if there was a > *.each! method to do that i would be fine, *that* would be ok, none of this > 'get the index and then do what you need to do and *THEN* set the stupid > block variable.... GRRRRRR!!!! > > Try `Array#map!` ary = ['f', 'o', 'o'] ary.map! { |char| 'x' } ary # => ["x", "x", "x"] --90e6ba61375c3cc69904aa176e39--