Alle mercoled22 agosto 2007, Dan George ha scritto:
> I recently started to take an interest in Ruby programming and with
> the help of some people and by reading Learn to program by Chris Pine
> I made myself a little program that has come to a halt because I don't
> know if or how I can use an external file where I store the strings I
> want to search and replace in text type files.
>
> This is what I have so far:
>
> txt_files = Dir.glob('**/*.txt').each do |path|
> puts path
> txts = path.to_s
>   file = File.open(txts).readlines.each { |line|
>     if line.match(/PROMOS:/)
>       then line.gsub!(/PROMO1=[A-Za-z0-9]+/, 'PROMO1=some_text')
>     end }
>   file2=File.open(txts, "w")
>   file2.write( file )
> end
>
> What I want is to be able to use an external file where I store the
> values I want to search and replace with "line.gsub!" eg.: "/PROMOn=[A-
> Za-z0-9]+/, 'PROMOn=some_other_text'".
> I will need to use RubyScript2Exe because I'm not sure that on some
> other machines I will have ruby installed and it's easier to just put
> the strings I want to search and replace in an external file that is
> located in the same folder as the script or on a predefined path.
>
> Any ideas, hints, improvements and critiques are highly welcome.

First some comments about your code:
* path is already a string, so calling to_s on it does nothing.
* You can replace the File.open(txts).readlines part with 
File.readlines(txts), which is (in my opinion) clearer and doesn't force you 
to remember to close the file (which by the way, you don't do).
* When you write to file2, you can use the block form of File.open, which 
takes care of closing the file for you.

Here's how what I'd have written:

Dir.glob('**/*.txt').each do |path|
  lines = File.readlines(path)
  if line.match(/PROMOS:/)
    lines.map!{|l| l.gsub(/PROMO1=[A-Za-z0-9]+/, 'PROMO1=some_text') 
  end
  File.open(path, 'w'){|f| f.write lines}
end

As you can see, I've also replaced the each/gsub! combination with map!/gsub, 
which, in my opinion makes clearer what you're doing (changing the contents 
of the array).

As for storing the search/replacement pairs on a file, I'd use YAML. It's 
included in the standard library, so there shouldn't be problems with 
RubyScript2Exe. You can get information on yaml for ruby at 
http://yaml4r.sourceforge.net/ (look in particular at the cookbook and doc 
sections). A simple example could be this:

'PROMO1=[A-za-z0-9]+': 'PROMO1=some_text'
'PROMO2=[A-za-z0-9]+': 'PROMO1=some_other_text'
...

When read into ruby using YAML.load, this would return the following hash:

{
 'PROMO1=[A-za-z0-9]+' => 'PROMO1=some_text',
 'PROMO2=[A-za-z0-9]+' => 'PROMO1=some_other_text'
}

You could then create regexps using Regexp.new. (Actually, you can also store 
the regexps directly in the yaml file, prefixing them with the 
string !ruby/regexp, but I think the file is easier to read/write this way).

I hope this helps.

Stefano