[newbie] in place file editing and ! meaning

Hi all,

I’m brand new to ruby, and I’m looking for a way to open a file, read
its content and modify it. I’ve seen that I can open a file in read
write mode, but I can’t figure out how it works. If I want to replace
all occurences of ‘search’ by ‘replace’, for instance, what do I have to
do?

Searching for an answer to this question, I’ve found scripts using gsub!
What is this exclamation mark?

Thanks in advance for your help!

Xavier

On Jul 17, 2006, at 9:19 PM, Xavier H. wrote:

gsub!
What is this exclamation mark?

Thanks in advance for your help!

Xavier


Posted via http://www.ruby-forum.com/.

The ! (pronounced bang usually) means that a method is a “dangerous”
version of a method with the same name. In this particular case it
means that it’s the inplace version of gsub (global substitution).

I take it you are referring to ruby code such as:

FOLDER = “#{ENV[‘HOME’]}/Desktop/” # or whatever folder you want
INFILE = “input.txt”
OUTFILE = “output.txt”

old = File.read(FOLDER + INFILE) # read file in as one big string
old.gsub!(/\bsearch\b/, “replace”) # do in-place substitution
File.open(FOLDER + OUTFILE, “w”) {|new| new.write(old)} # write
modified text out to disk.

This code does not open “input.txt” in RW mode nor modify it in
place. For one thing, gsub! only works on strings not file objects.
For another, I’m too nervous to do that kind of thing. Of course, if
INFILE == OUTFILE, it would overwrite “input.txt”.

In general, it is a naming convention that a method ending in !
signifies that the method does in-place (destructive) modification to
the receiver. I first ran into this convention when studying scheme
back in the 1980s. I don’t know if has any history beyond that.
Schemers would read gsub! as GEE-SUB-BANG. I’m new to ruby, too, so
I’m not sure if rubyists read it the same way.

Regards, Morton

Logan C. wrote:

The ! (pronounced bang usually) means that a method is a “dangerous”
version of a method with the same name. In this particular case it
means that it’s the inplace version of gsub (global substitution).

OK, thanks for the information and the pronounciation tip.

But I still don’t know how to edit a file while reading it. I’ve made
further googling on the subject, and the only solutions I find are:

  • “read all, manipulate, write all”, which doesn’t seem very good with
    huge files
  • use -i options with ruby command line, but this seems to work only
    with files passed on the command line, which isn’t my case.

So, could somebody tell me if it’s possible to update a file in ruby
(except these two solutions)?

On Jul 17, 2006, at 7:31 PM, Xavier H. wrote:

  • “read all, manipulate, write all”, which doesn’t seem very good with
    huge files
  • use -i options with ruby command line, but this seems to work only
    with files passed on the command line, which isn’t my case.

So, could somebody tell me if it’s possible to update a file in ruby
(except these two solutions)?

do you want something like this?

cg5:~ >cat a
abcdefghijklm
cg5:~ >cat a.rb
f = File.new(“a”, “r+”)
while f.read(1) !~ /d/
end
f.write(“ZZZ”)
cg5:~ >ruby a.rb
cg5:~ >cat a
abcdZZZhijklm
cg5:~ >

– Elliot T.

On Jul 17, 2006, at 10:31 PM, Xavier H. wrote:

  • “read all, manipulate, write all”, which doesn’t seem very good with
    huge files
  • use -i options with ruby command line, but this seems to work only
    with files passed on the command line, which isn’t my case.

So, could somebody tell me if it’s possible to update a file in ruby
(except these two solutions)?


Posted via http://www.ruby-forum.com/.

To do in place editing, basically you just do it. The problem is
doing it correctly. One way is to use fixed-size chunks:

CHUNK_SIZE = 1024
File.open(“somefile”, “r+”) do |f|
loop do
pos = f.tell
s = f.read(CHUNK_SIZE)
break if s.nil? # We’ve read and transformed the file
s.gsub!(/a/, ‘b’)
f.seek(pos, IO::SEEK_SET)
f.write(s)
end
end

The problem with this method is if the substitued string is longer or
shorter than the read string it’ll mess it up and you’ll have to
shift the rest of the file around. Another way (and how I believe
ruby’s command line switch -i works) is to write the modified version
to a temporary file, and then remove the original version, replacing
it with the modified version. A third, relatively idiot proof method
is to use the mmap extension. This is awesome, but is not gonna be
portable outside of a *nix. (And introduces another dependency).

How big is huge? Nowadays, I think the “read all, manipulate, write
all” technique is probably the best for text files up to many megabytes.

Regards, Morton

Xavier H. [email protected] writes:

I’m brand new to ruby, and I’m looking for a way to open a file, read
its content and modify it. I’ve seen that I can open a file in read
write mode, but I can’t figure out how it works. If I want to replace
all occurences of ‘search’ by ‘replace’, for instance, what do I have to
do?

In general, you need to read in the file (usually line by line) and
write out a new copy with the changes you want. Editing in place is
only possible if the replacement string is exactly the same length as
the original.

Searching for an answer to this question, I’ve found scripts using gsub!
What is this exclamation mark?

It means it changes the object it operates on, rather than returning a
changed copy.

-Doug

Many thanks all of you! What an incredibly active community ruby has,
I’m impressed. And the tell and seek methods are exactly what I was
looking for (even if I agree the read, manipulate, write is much easier
to write and can address most problems).

Thanks again, and I feel like I’ll soon become a ruby afficionado :slight_smile:

On Jul 18, 2006, at 1:26 AM, [email protected] wrote:

changed copy.

In this case that’s true, but in general, ! means a “dangerous” method
with a non-dangerous counterpart. (See Logan’s answer.)

What are some examples of method names with ! used to indicate some
dangerous thing other than a destructive method?

– Elliot T.

Hi –

On Tue, 18 Jul 2006, Douglas McNaught wrote:

Searching for an answer to this question, I’ve found scripts using gsub!
What is this exclamation mark?

It means it changes the object it operates on, rather than returning a
changed copy.

In this case that’s true, but in general, ! means a “dangerous” method
with a non-dangerous counterpart. (See Logan’s answer.)

David

On Tue, Jul 18, 2006 at 06:36:46PM +0900, Elliot T. wrote:

In this case that’s true, but in general, ! means a “dangerous” method
with a non-dangerous counterpart. (See Logan’s answer.)

What are some examples of method names with ! used to indicate some
dangerous thing other than a destructive method?

Kernel#exit!

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs