Ruby find and replace, RSpec friendly!

There are a few existing solutions for folks who want to replace some text in a file. You can just use sed, by dropping out to the command line:

1
2
3
def replace(filename, pattern, string)
  `sed -i 's/#{pattern}/#{string}/g' #{filename}`
end

And Rodney Carvalho of Internaut posted a script that will do it.

But if you’re looking for something that you can include in your specs with proper mocking, without leaving Ruby, here’s an extension to Ruby’s core File object that I cobbled together from Rodney’s example. Put this in file.rb in your lib/ folder and load it in your environment.rb:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class File
  def replace(pattern, string)
    full_path = File.expand_path path
    return if !File.file?(full_path)
 
    reopen(full_path, 'r')
    lines = readlines
 
    changes = false
    lines.each do |line|
      changes = true if line.gsub!(pattern, string)
    end
 
    if changes
      reopen(full_path, 'w')
      lines.each do |line|
        write(line)
      end
      close
    end
  end
end

It lets you do fun things like this in your specs:

1
2
3
4
5
6
7
8
9
10
describe Inauguration do
  it "should replace Bush with Obama" do
    fake_file = mock_object(File)
    fake_file.should_receive(:replace).with(/George W\. Bush/, "Barack Obama")
    File.should_receive(:new).with("presidents_of_the_us.txt").and_return(fake_file)
 
    event = Inauguration.new
    event.prep
  end
end

Pretty fun!

Tags: , ,

One Response to “Ruby find and replace, RSpec friendly!”

  1. Buscar y reemplazar desde Ruby « Código atado con alambre Says:

    [...] la rueda fue buscar un script similar. Lo más parecido que encontré fue en la página “Erik on Rails“. Si bien no era exactamente lo mismo, tenía una clase que se podía aprovechar. Gracias [...]

Leave a Reply