From: Tom Cloyd Date: 2008-06-16T18:53:47+09:00 Subject: Re: how to stop gsub from returning nil Thank you all for your kind help. Very much appreciated! I've basically got my little HTML to textile program working well enough to use. I really didn't have much time to do it, and your help saved my bacon. Comments below... Robert Klemme wrote: > 2008/6/16 Tom Cloyd : > >> I'm trying to use gsub to do a number of transformations in an array of >> strings. I find that when a particular transformation does NOT happen, >> because the searched-for substring is not there, gsub returns nil. This >> effectively ruins my output. I don't want nothing. I want the string that's >> being processed, returned with or without any transformations. Is there any >> alternative to testing for a return of nil before calling gsub, so as to >> avoid the wiping out of my string? I've looked for something to use other >> than String::gsub, and have not found anything. >> > > You first need to decide whether you want to do all your > transformations in place (i.e. on the original strings in the Array) > or whether you need a copy of all strings - with or without changes. > > I ended up doing them in place. Couldn't figure a clean way to make copies, then feed them back into the implicit loop. >> Code: >> >> filein = open( "{whatever}" ) >> fi = filein.readlines >> delta = [ ["

", ''], ["", ''] ] >> results = fi.collect do |x| >> delta.each do |y| >> debugger x.gsub!(y[0], y[1]) >> end >> end >> > > It's not clear what you intend to do with results, but I assume for > the moment that you need copies. In that case you probably should not > use String#gsub! but String#gsub (i.e. the version which leaves the > original untouched). > My current code ("fi" is an input textfile - an array of strings): fi.collect do |x| delta.each do |y| # <= this is as I specified before, but much larger if nil!=x.gsub!(y[0], y[1]) then # <= this makes no obvious difference in processing time x.gsub!(y[0], y[1]) end end fileout.write x end > Few other remarks: > > - You do not use the block form of file opening and thus you leave the > file descriptor open which is bad. > Erg. Got me. > - You can read a complete file as Array via File.readlines("whatever") > > - You can read a complete file as String via File.read("whatever") > I used the first, but wasn't clear about the last. Thanks. > - a Hash seems more appropriate for delta because it nicely expresses > the key value relationship between search criteria and replacement > string and also prevents accidental duplicates. Downside is that you > loose order if that is important for you. > Yeah, and that downside would be fatal. Order matters. Array it must be. > - Reading the file as single String might be more efficient because in > that case you only need one gsub per replacement expression > Oh. Now that's slick. Many thanks. > So, here's probably what I'd do > > delta = { %r{}i => '' } > > c = File.read "whatever.html" > delta.each do |rx, repl| > c.gsub! rx, repl > end > > puts c > Well, I need to study that. Amazing terse. But, then that's the miracle of Ruby, isn't it. Almost poetry. Thanks again! t. -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Tom Cloyd, MS MA, LMHC Private practice Psychotherapist Bellingham, Washington, U.S.A: (360) 920-1226 << tc@tomcloyd.com >> (email) << TomCloyd.com >> (website & psychotherapy weblog) << sleightmind.wordpress.com >> (mental health issues weblog) << directpathdesign.com >> (web site design & consultation) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~