From: Leif Eriksen Date: 2008-01-31T09:37:53+09:00 Subject: Idiomatic way to copy parameters ? Some background - bear with me So I'm writing my first little library (module) in ruby, for a play-project in rails. The library is for color management related functions, and its first method is to provide a color 'gradient', which I use for images where the colors smoothly change from a to b in as many steps as I require for example, to get from html rgb color #010101 to #444444 in 5 'steps', we would do ColorManagement.gradient(#010101, #444444, 5) # will used named params in version 2! and it would return ["#010101", "#0e0e0e", "#1b1b1b", "#282828", "#353535", "#444444"] The method supports leading '0x' chars as well, and prepends the leading chars (if any) to the entries in the result array. And this is all cool, until I did this start = '#010101' finish = '#444444' ColorGradient.gradient(start, finish , 5) pp start "#{start}" pp "finish #{finish }" and I see this "start 010101" "finish 444444" The '#''s are gone. Internally the library is stripping these off to make splitting into RGB channels easier, and it does the stripping like this def self.gradient(hex_start="000000", hex_end="FFFFFF", steps=256) [hex_start,hex_end].each do |hex| hex.sub!(/^(0[xX]|#)/) do |match| match = '' # remove any leading # or Ox So the strings that are passed in are permanently munged by the sub! . OK I get that, and to solve it I did this def self.gradient(param_start="000000", param_end="FFFFFF", steps=256) #make local copies of parameters hex_start = String.new(param_start) hex_end = String.new(param_end) [hex_start,hex_end].each do |hex| hex.sub!(/^(0[xX]|#)/) do |match| ... So in effect I copy the parameter strings into local vars, to avoid munging what the user passes me and annoying them. But is this the ruby way ? Is this the idiomatic way to avoid side-effects on objects passed in as parameters ? Cheers Leif