I don't think Solution.new is returning nil in your example, it's returning a new instance of solution (foo in your example)
Your main issue is that read_file is returning the value of File.foreach, which is always nil.
For starters, update your read_file method to return the array itself:
class Solution
def read_file
array = []
lines = []
File.foreach('test.txt') do |line|
lines << Line.new(line)
end
array << lines
array
end
end
solution = Solution.new
solution.read_file
# outputs:
# [#<Line:0x007fab92163b50 @content="This Is A Line\n">, #<Line:0x007fab92161be8 @content="Line 2\n">, #<Line:0x007fab92160d88 @content="Line3">]
If you want to return an array of arrays split each line by whitespace:
class Solution
def read_file
lines = []
File.foreach('test.txt') do |line|
words = []
line.strip.split(/\s+/).each do |word|
words << word
end
lines << Line.new(words)
end
lines
end
end
The key line of code here is: line.strip.split(/\s+/) which first strips leading and trailing whitespace from the string, then converts it to an array by splitting the string based on whitespace (the /s+/ regex matches one or more blank characters).
Some other suggestions:
Pass the filename as an argument to read_file you can set a default argument if you want to:
class Solution
def read_file(filename = 'test.txt')
array = []
File.foreach(filename) do |line|
array << Line.new(line)
end
array
end
end
Finally, for a much more elegant solution, you can use map, and simply call .split to return a nested array. The Line class isn't really doing much in this case.
class Solution
def read_file
File.foreach('test.txt').map do |line|
line.strip.split(/\s+/)
end
end
end
This will simply return an array of arrays, where the inner array contains the words for each line.
returnkeyword, or if it reaches it, the value of the last expression in the method.