From: Carlo Teubner Date: 2002-04-14T22:00:35+09:00 Subject: Re: RCR: key value mapping for sprintf/% Hi, [snip] > I wrote a substitute method for String#% which treats a Hash argument > as described above. It seems to be working fine, and I even posted > it to the RAA ("TextFormatTemplate"). [snip] Wow, what a cool idea. Dissecting your code, I found some very minor things I would have done slightly differently. Annotations below. class String alias old_sf % def %(vars) # [1] re = /%\((\w*?)\)([-#0\s+']*\d*(?:\.\d*)?[bcdeEfgGiosxXu])/ # [2] case vars when Hash gsub(re) { |m| if vars[$1].nil? # [3], [4] m # [5] else "%#$2" % vars[$1] # [4] end } else old_sf vars end end end Annotations: [1] Why the default value, {}? Normally, String#% complains if you give it too many or too little arguments (or none at all). I think this behaviour should be kept. [2] I changed (\([\w]*?\)) to \((\w*?)\). That way, the parentheses won't become part of $1. [3] I removed the begin..rescue construct, because I think that an ArgumentError thrown by old_sf should just be passed on to the caller. Or did you think of other kinds of exceptions? [4] Thanks to [2], we don't need to remove the parentheses from $1 and can directly use $1. [5] if vars[$1].nil?, then vars.default will also be nil. Sorry for the nitpicking... probably I am even wrong in some places. But I found your code so intriguing that I had to play around with it a bit :) -Carlo