> -----Original Message----- > From: list-bounce / example.com > [mailto:list-bounce / example.com] On Behalf Of Jeff Pritchard > Sent: Wednesday, June 28, 2006 8:52 AM > To: ruby-talk ML > Subject: Re: string manipulation > > I really like Alex's solution to this. As a newbie, I always attempt > these "easy" things just to help me learn more of the > language. I've not been programming ruby for long, so these nasty oneliners amuse me greatly, as well. > My solution involved reversing the string as Alex did, and > then trying > to use "each_with_index" on it to iterate through the > characters. The biggest problem I had with the String#each or String#each_with_index approach is that you don't get a string out of it at the end, you get an array. This means you need to operate directly on the string inside your block, which may or may not be pretty. > Also, my first thought on a solution for this was to simply > walk along > the string and insert dashes where appropriate. Why isn't there a > "String#insert(where,str)" method? Inserting substrings into strings > seems like such a common thing to do. As someone else pointed out, String#insert does exist. For the given string you can do: [2,7,12,17].inject("123456789123456789") {|string, index| string.insert(index,'-')} Which is quite nice, and shows off inject, which is AWESOME. Sadly, to call it a real oneliner you'd need to construct that initial array, which I was unable to do in a manner I consider fit for print. Another way to attack the same thing, though, would be with Range#step: (2..str.length-1).step(5) {|index| str.insert(index,'-')} Which is also not ugly, but check the way it handles cases that have different lengths to the OP's string - the /..../ double reverse, the regexp and the 'insert at index' approaches all behave different ways; not all of which are likely "correct". > Can someone offer some clarification? I think you should look again at Paul Battley's approach, which is (IMVHO) actually the most readable and elegant approach, once you take out the redundant passive grouping (as done here): str.gsub(/^\d{2}|\d{4}(?=.)/, '\0-') Once deconstructed, it's looking for start followed by two numbers, OR any four numbers, provided they are followed by another character (you could also write (?!$) for not end-of-line). If it finds one of those it appends a dash. Personally, I could look at this solution and say what it is supposed to do without running it (and without bending my brain). Only the explicit inject example above rings my readability meter as loudly. > thanks, > jp Cheers, ben