这是我保存到文件以便以后读取的哈希。
my_hash = {-1 => 20, -2 => 30, -3 => 40}
File.open("my_file.txt", "w") { |f| f.write my_hash }
#how it looks opening the text file
{-1 => 20, -2 => 30, -3 => 40}
当我去阅读它时,问题出在哪里。 (以下代码与顶部分开)
my_hash = File.foreach("my_file.txt") { |f| print f }
p my_hash
#=> {-1 => 20, -2 => 30, -3 => 40}nil
nil
弄乱了我的其余代码......不知道如何摆脱if。为了清楚起见,其余代码......
back_up_hash = {-1 => 20}
if my_hash.nil?
my_hash = back_up_hash
end
那个小nil
总是让my_hash等于back_up_hash。我需要.nil?
以防万一文件没有散列,否则问题会被进一步推下来。
我也尝试过阅读(啜饮?它是一个小文件)这样的文件....
my_hash = File.read("my_file.txt") { |f| print f }
p my_hash
=> "{-1 => 20, -2 => 30, -3 => 40}"
# not sure how to get it out of string form...and I have searched for it.
答案 0 :(得分:3)
答案 1 :(得分:1)
将简单数据结构保存到文件的正确方法是序列化它们。在这种特殊情况下,使用 JSON 可能是一个不错的选择:
# save hash to file:
f.write MultiJson.dump(my_hash)
# load it back:
p MultiJson.load(file_contents)
请记住,JSON只能序列化简单的内置数据类型(字符串,数字,数组,哈希等)。如果没有额外的工作,您将无法以这种方式序列化和反序列化自定义对象。
如果您没有MultiJson
,请尝试使用JSON
。
答案 2 :(得分:0)
如果要在内容为{-1 => 20, -2 => 30, -3 => 40}
的磁盘上获取文件并从中创建哈希,则需要:
hash_str = File.read('my_file.txt')
my_hash = eval(hash_str) # Treat a string like Ruby code and evaluate it
# or, as a one-liner
my_hash = eval(File.read('my_file.txt'))
您正在做的是读取文件并将其打印到屏幕上,一次一行。 'print'命令不会转换数据,foreach
方法不会将它产生的数据映射到任何结果中。这就是为nil
获得my_hash
的原因。
正如我在评论中建议的那样,如果你有一个Ruby对象(比如Hash)并且你需要将它保存到磁盘并在以后加载它,你可能想要使用Marshal
模块(内置于Ruby中) ):
$ irb
irb(main):001:0> h = {-1 => 20, -2 => 30, -3 => 40}
#=> {-1=>20, -2=>30, -3=>40}
irb(main):002:0> File.open('test.marshal','wb'){ |f| Marshal.dump(h, f) }
#=> #<File:test.marshal (closed)>
$ irb # later, a new irb session with no knowledge of h
irb(main):001:0> h = File.open('test.marshal'){ |f| Marshal.load(f) }
#=> {-1=>20, -2=>30, -3=>40}
答案 3 :(得分:0)
我用这两种简单的方法取得了成功:
def create_json_copy
File.open("db/json_records/stuff.json","w") do |f|
f.write("#{@existing_data.to_json}")
end
end
def read_json_copy
@json = JSON.parse(File.read("db/json_records/stuff.json")).as_json.with_indifferent_access
@json.each do |identifier,record|
existing_record = Something.find_by(some_column: identifier)
if !existing_record
Something.create!(record.except(:id).except(:created_at).except(:updated_at))
end
end
end
注意:@existing_data
是一个组织为{ some_identifier: record_objet, ... }
的Ruby Hash。在将其写入文件之前,我先调用.to_json,然后在阅读JSON.parse
时,它后跟.as_json
,with_indifferent_access
在这里真的不需要,所以你可以把它当作只要替换excepts
内的符号。