我有一个看起来像这样的文件:
[noahc:~/projects/wordsquares] master(+87/-50)* ± cat wordlist/test_word_list.txt
card
apple
joe
bird
card
dart
area
rear
birdbird
after
boat
swim
north
abbe
byes
beep
如果我打开一个irb会话,我可以这样做:
2.0.0p247 :001 > file = File.open('./wordlist/test_word_list.txt', 'r')
=> #<File:./wordlist/test_word_list.txt>
2.0.0p247 :002 > file.readlines
=> ["card\n", "apple\n", "joe\n", "bird\n", "card\n", "dart\n", "area\n", "rear\n", "birdbird\n", "after\n", "boat\n", "swim\n", "north\n", "abbe\n", "byes\n", "beep \n", "\n"]
但是,现在我有一个名为WordSquareGenerator的类:
class WordSquareGenerator
require 'pry'
require 'pry-nav'
require './lib/word_list_builder.rb'
def initialize(n, file_location)
@size_of_square = n
@file = load_file(file_location)
@word_stem_hash = WordListBuilder.new(n, @file).word_stem_hash
@word_list = nil
end
def word_square_word_list
binding.pry
@file.each do |w|
binding.pry
@word_list ? break : solve_for_word_list([word])
end
binding.pry
end
def is_list_valid?(list)
(0..@size_of_square - 1).each do |n|
(0..@size_of_square - 2).each do |m|
return false if list[n][m] != list [m][n]
end
end
@generated_list = list unless @generated_list
end
def solve_for_word_list(word_array)
if word_array.length == 4
@word_list = word_array
elsif @word_list
else
next_words = @word_stem_hash[word_array.map{|w| w[word_array.length]}.join]
next_words.each do |word|
solve_for_word_list(word_array + [word])
end
end
end
private
def load_file(file_location)
File.open(file_location, 'r')
end
end
当我运行word_square_word_list
方法并点击第一个binding.pry
时,我可以这样做:
2.0.0 (#<WordSquareGenerator:0x007ff3f91c16b0>):0 > @file.readlines
=> []
我为readlines
得到一个空数组。怎么可能我得到两个不同的结果做同样的事情,除了一个在那个班级而另一个不在?
答案 0 :(得分:1)
在阅读以下内容之前尝试运行:
@file.seek 0
您可能已经阅读了这些行,并且在再次阅读之前必须先找回文件的开头。
示例IRB会话:
irb(main):001:0> f = File.new 'test.txt' # already existing file
=> #<File:test.txt>
irb(main):002:0> f.readlines
=> ["this", "is", "a", "test"]
irb(main):003:0> f.readlines
=> []
irb(main):004:0> f.seek 0
=> 0
irb(main):005:0> f.readlines
=> ["this", "is", "a", "test"]
你甚至可以把它变成一种方法:
def readlines
@file.seek 0
@file.readlines
end
另外,请务必关闭文件(@file.close
)!你应该只在尽可能短的时间内保持开放状态。你绝对不应该让它对整个程序开放。如果您不想担心这一点,只需将行存储在变量中,而不是保留文件:
@lines = File.open(file_location) {|f|
f.readlines
}
# you could also use the shortcut form
# @lines = File.open(file_location, &:readlines)
答案 1 :(得分:1)
在WordListBuilder
,您可能已经在阅读该文件,当该操作返回WordSquareGenerator
时,该文件已经到了结束,并且没有其他内容可供阅读。首先,不要做你现在正在做的事情,即打开文件,因为这会泄漏文件句柄(你没有在任何地方关闭它),而其他人读取句柄会导致你的代码失败。
以下是你如何做到的:
class WordSquareGenerator
require 'pry'
require 'pry-nav'
require './lib/word_list_builder.rb'
def initialize(n, file_location)
@size_of_square = n
@file_location = file_location
@word_stem_hash = WordListBuilder.new(n, file_location).word_stem_hash
@word_list = nil
end
def word_square_word_list
binding.pry
IO.foreach(@file_location) do |word|
binding.pry
@word_list ? break : solve_for_word_list([word])
end
binding.pry
end
def is_list_valid?(list)
(0..@size_of_square - 1).each do |n|
(0..@size_of_square - 2).each do |m|
return false if list[n][m] != list [m][n]
end
end
@generated_list = list unless @generated_list
end
def solve_for_word_list(word_array)
if word_array.length == 4
@word_list = word_array
elsif @word_list
else
next_words = @word_stem_hash[word_array.map{|w| w[word_array.length]}.join]
next_words.each do |word|
solve_for_word_list(word_array + [word])
end
end
end
end
您还需要更新WordListBuilder
才能执行相同操作。这也有为您自动关闭文件句柄的优点,因此您不必自己关闭文件句柄。