Search code examples
rubyfilesize

Size Reading and Writing to File and conditional statements


Beginner learning Ruby. Was doing an exercise on reading and writing to file.

name_number = {

}

File.open("book.txt", 'a') do |file| 
  name_number.each do |name, number| 
    file.write ("- #{name} #{number}\n")
  end
  file.close
end

File.open("book.txt", "r") do |file|
  if file.size < 1
    puts "There are no people in the book."
  end

  File.open("book.txt", "r") do |file| 
    puts file.read
  end
end

So it outputs "There are no people in the book." when the file is empty.

SO if we add some people...

name_number = {
  "Bill" => 87987,
  "Kevin" => 78912
}

File.open("book.txt", 'a') do |file| 
  name_number.each do |name, number| 
    file.write ("- #{name} #{number}\n")
  end
  file.close
end

I was trying to figure out how to get it to say

"There is one person" for 1 and "There are some people" for anything over 1.

I thinking I need an elsif statement something like this, (but obviously this isn't working, but maybe you can see what I'm thinking of trying to achieve?).

File.open("book.txt", "r") do |file|
  if file.size < 1
    puts "There are no people in the book."
  elsif file.size == 1
    puts "There is an entry in the book."
  elsif file.size == 2
    puts "There are two entries in the book"  
  end

  File.open("book.txt", "r") do |file|
    puts file.read
  end
end

I'm definitely missing something. I was wondering if anyone could point me in the right direction?


Solution

  • To obtain the number of lines in the file you need to read it. If possible, you want to avoid reading the file more than once.

    Assuming the file is not excessively large, you could gulp it into an array, using IO::readlines:

     arr = File.readlines("book.txt")     
     puts case arr.size
     when 0
        "There are no people in the book."
     when 1 
        "There is one person in the book"
     when 2
        "There are two people in the book"
     else
        "There are some entries in the book"
     end  
     puts arr
    

    Alternatively, you could gulp it into a string, using IO::read:

     str = File.read("book.txt")     
     puts case str.count("\n")
     when 0
        "There are no people in the book."
     when 1 
        "There is one person in the book"
     when 2
        "There are two people in the book"
     else
        "There are some entries in the book"
     end  
     puts str
    

    If the file is so large that you need to read it one line at a time you can use IO::foreach. This does require two passes through the file, however.

     puts case File.foreach("book.txt").count
     when 0
        "There are no people in the book."
     when 1 
        "There is one person in the book"
     when 2
        "There are two people in the book"
     else
        "There are some entries in the book"
     end  
     File.foreach("book.txt") { |line| puts line }