[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

···

--
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).

···

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

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

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

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

···

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

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

Xavier Hanin <xhanin@yahoo.fr> 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

Logan Capaldo 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)?

···

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

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

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
Ruby for Rails => RUBY FOR RAILS (reviewed on
                                     Slashdot, 7/12/2006!)
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
dblack@wobblini.net => me

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 Temple

···

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

Logan Capaldo 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)?

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).

···

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

Logan Capaldo 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)?

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

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

···

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

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.

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

-- Elliot Temple

···

On Jul 18, 2006, at 1:26 AM, dblack@wobblini.net wrote:

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.)

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:

···

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

Kernel#exit!

···

On Tue, Jul 18, 2006 at 06:36:46PM +0900, Elliot Temple 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?

--
Mauricio Fernandez - http://eigenclass.org - singular Ruby