I have created a simple class to handle opening, reading, and closing a file. In addition, I would like to run a regex on its contents to find a 4 digit date. However, when I run my code I get the following error:
file_class.rb:17:in `find_date': undefined method `match' for nil:NilClass (NoMethodError)
from file_class.rb:24:in `<main>'
This error only occurs if I run the read_file
method before it, which simply puts the file contents. I am not sure why doing so would result in such an error.
Below is my code:
class MyFile
attr_reader :handle
def initialize(filename)
@handle = File.open(filename)
end
def read_file
puts @handle.gets
end
def finished
@handle.close
end
def find_date
matching = @handle.gets.match(/\d{4}/)
puts matching[0]
end
end
f = MyFile.new('text.txt')
f.read_file
f.find_date
f.finished
Thanks for the help.
I'm guessing your file had a single line of contents.
When you call gets
on an open file handle, the handle returns the line it is currently looking at and moves its "cursor" down to the next line. After you've read the last line, gets
will return nil
.
Your class would be better (for a few reasons) if you read the file once and cache the contents, rather than caching the handle and attempting to read several times:
class MyFile
attr_reader :contents
def initialize(filename)
File.open(filename) do |f|
@contents = f.read
end
end
def find_date
matching = @contents.match(/\d{4}/)
puts matching[0]
end
end
This approach is better because:
File#read
instead of File#gets
).attr_accessor
makes contents
available to calling code without you needing to write your own methods. This is good because it's quicker to write and, much more importantly, it's clearer to read.Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments