0

I want to write a simple program, that writes console input to file with name i entered.

file_name = ARGV[0]
of = File.open(file_name, 'w')

while a = gets.chomp
  puts a
  of.puts a
end

# ruby write_script.rb file_name.txt

returns: main: undefined method chomp for nil:NilClass (NoMethodError)

update:

file_name = ARGV[0]
File.open(file_name, 'w') do |file|
  while (a = gets)
    print a
    file.write a
  end
end

After executing this code - program terminates at start and empty file creates.

What is the right way to do it?

5 Answers 5

2

I think, the problem lies in the fact, that puts does some stuff behind the scenes. Specifically, if there is a file name as a command line argument, gets reads the next line from that file (see these docs Ruby docs, Kernel:gets).

So, if a one line script:

puts gets

...gets called with CLI arguments like this ruby onelinescript.rb some_file.txt, it will print the first line of some_file.txt.

The problem in your case, I think, is that you open the file from the CLI argument list first for writing and then implicitly try to open it for reading with gets, which doesn't work. To fix that, you should explicitly state the IO object you call gets on:

file_name = ARGV[0]
of = File.open(file_name, 'w')

while a = STDIN.gets.chomp
  puts a
  of.puts a
end

P. S. In case I am wrong, please don't hesitate to point that out.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, it seems to be true
1

The following code works for me :

begin
  File.open(ARGV.shift, 'w') do |f|
    while a = gets.chomp
      p a
      break if a == 'exit'
      f.puts a
    end
  end
rescue SignalException
  puts
  puts "#Completed#"
  exit
end

It should be noted that I'm using ARG.shift instead of ARG[0] because when using the latter gets will access whatever is in ARG before moving on the STDIN. ARG.shift removes the original argument.

3 Comments

Beatiful solution and just i had problem with ctr-c. Thank you)
That's normal since by interrupting you are throwing an error. If you want a clean finish even when using ctr-c you need to catch that error . I've updated the above code to catch it.
To finish cleanly on OS X or *nix, ctrl-d.
0

You misspelled chomp as chop in your code.

Comments

0

The method here is chomp, which strips a string (taken from stdin by gets()) from the trailing newline character \n.

Comments

0

Code:

file_name = ARGV[0]
of = File.open(file_name, 'w')

while a = STDIN.gets
  print a
  of.write a
end
of.close

Your problem is that gets returns nil when you get to the end of stdin.

5 Comments

Sorry , my iPhone totally makes it impossible to format code properly, I'm not sure why.
Thanks for answer, but i tried this by myself, after executing that code with ruby write_script.rb file_name.txt the program terminates and empty file file_name.txt creates
Note: you must close the file at the end of the program! Best to use the block form of File.open (see my answer).
Oops! I added a call to of.close. That will probably fix the problem.
I also changed my answer to use STDIN.gets. Thanks jst!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.