2

I'm in the process of learning Ruby and reading through Chris Pine's book. I'm learning how to read (and write) files, and came upon this example:

require 'yaml' test_array = ['Give Quiche A Chance', 'Mutants Out!', 'Chameleonic Life-Forms, No Thanks'] test_string = test_array.to_yaml filename = 'whatever.txt' File.open filename, 'w' do |f| f.write test_string end read_string = File.read filename read_array = YAML::load read_string puts(read_string == test_string) puts(read_array == test_array ) 

The point of the example was to teach me about YAML, but my question is, if you can read a file with:

File.read filename 

Can you write to a file in a similar way?:

File.write filename test_string 

Sorry if it's a dumb question. I was just curious why it's written the way it was and if it had to be written that way.

4
  • 1
    What happened when you tried? Commented Mar 19, 2014 at 23:28
  • 1
    Yes,,,possible ruby-doc.org/core-2.1.0/IO.html#method-c-write .. File.write(filename,test_string).. Commented Mar 19, 2014 at 23:35
  • Nate W., I am not at my personal computer right now and can't download ruby or a text editor to this machine. I'll give it a shot when I get home and see what happens. Commented Mar 20, 2014 at 0:18
  • Arup Rakshit, thank you! Commented Mar 20, 2014 at 0:18

3 Answers 3

1

Can you write to a file in a similar way?

Actually, yes. And it's pretty much exactly as you guessed:

File.write 'whatever.txt', test_array.to_yaml 

I think it is amazing how intuitive Ruby can be.

See IO.write for more details. Note that IO.binwrite is also available, along with IO.read and IO.binread.

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

5 Comments

Thanks Matheus! And you're right, Ruby is insanely intuitive. And I'm glad to hear that my guess what mostly right. Any theory as to why the author, Chris Pine, decided to write it the way he did as opposed to the way you did?
@BoG, I don't know for sure. He might not have been aware of the File.write method. Nothing in the example code warrants using the block form; he's not sharing the file handle, it is possible to pass the opening mode to File.write and the block is just returning the result of File#write. They are pretty much equivalent, but the block form is unecessarily verbose in this case.
I'm going to assume it was for ease of reading or something. Or, as you suggested, maybe he didn't know about File.write. Thanks for the follow up.
while I've got you here, maybe you can help me with something else I'm struggling to understand. read_array = YAML::load read_string The double colons - ::. Is that used because the load method is not a part of the YAML module? Meaning that you couldn't write YAML.load read_string. Edit Please excuse the lack of formatting. I tried to format it, but I guess you can't in the comments.
@BoG, YAML::load and YAML.load will do the same thing and are pretty much equivalent in this context. The difference between them is that the scope resolution operator (::) will also resolve constant names, while the dot operator (.) always means method call. If you have further questions, you should search StackOverflow or ask a new question.
0

The Ruby File class will give you new and open but it inherits from the IO class so you get the read and write methods too.

I think the right way to write into a file is the following:

File.open(yourfile, 'w') { |file| file.write("your text") } 

To brake this line down:

  • We first open the file setting the access mode ('w' to overwrite, 'a' to append, etc.)

  • We then actually write into the file

8 Comments

Thanks for the detailed answer, Luke. The way you wrote it is close to the way it was written in the example. I was wondering if the do...end - the {...} in your example - and the code-block in between is even necessary. For example, can't you just write: File.write yourfile 'w' It seems like you're saying that's not correct.
Well you can't write in a file using File.write yourfile 'w'. Here is the irb output for such a statment: >> File.write 'test.txt', "Hi there" NoMethodError: undefined method 'write' for File:Class You first need to open the file to access the stream and write in it. You can try yourself in irb.
@LukeS, what do you mean it doesn't work? File.write 'file', 'data', mode: 'a' works here and in a couple sites I used to test.
@LukeS Sorry, I wrote down my example incorrectly. File.write 'yourfile', string ---> Instead of File.write yourfile 'w'.
My answer gives you the good practice, one line way to write to a file. Note that .open is a synonym for ::new File.open
|
0

You can read or write to a file by specifying the mode you access it through. The Ruby File class is a subclass of IO.

The File class open or new methods take a path and a mode as arguments: File.open('path', 'mode') alternatively: File.new('path','mode')

Example: to write to an existing file somefile = File.open('./dir/subdirectory/file.txt', 'w') ##some code to write to file, eg: array_of_links.each {|link| somefile.puts link } somefile.close

See the source documentation as suggested above for more details, or similar question here: How to write to file in Ruby?

1 Comment

Thanks Kyle. It seems to me that the File class would inhereit the write method from IO. So I think it would be possible to write it File.write "whatever.txt", text, too. Matheus, above, confirms that.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.