如何从 ruby 中的文件中 read/write 哈希?

How to read/write a hash from a file in ruby?

我想将国家/地区的数据存储在一个文件中并读取该数据。我试图将它写在 filename.yml 文件中,但我无法分别获取每个哈希来执行特定操作。看看我尝试了什么

    require 'yaml'
    
    def addData
        puts 'Enter country name :'
        name = gets.chop.to_s
        puts 'Enter population in billion :'
        population = gets.chop.to_s
        puts 'Enter GDP in lakh crore USD:'
        gdp = gets.chop.to_s
        puts 'Enter army strength:'
        army_strength = gets.chop.to_s
        puts 'Enter state of country:'
        state = gets.chop.to_s
    
        country = Hash.new
        country = { "name" => name , "population" => population , "gdp" => gdp , "army_strength" => army_strength , "state" => state }
        
        arr_country.push(country)
        # Writing to the file 
        File.open('filename.yml','a') { |f| YAML.dump(country, f) }
    end
    
    def readData
    
        File.open('filename.yml') { 
            |f|.each {
            arr = YAML.load(f)
                if arr
                    puts arr
                    puts arr.class
                end
            }
        }
    end
    
    while true
        puts '1. Write','2. Read','3.Exit'
        opt = gets.chop.to_i
        if (opt>2)
            return
        end
    
        case opt
        when 1
            addData
        when 2
            readData    
        end
    end

但它不起作用,最好的方法是什么?

f.each没有意义。 f 是文件对象,each 处理每一行并尝试将每一行解释为单独的 YAML 表达式。但是,您的整个文件由一个 YAML 表达式组成。

你可以这样做:

country = YAML.load(File.read('filename.yaml'))

除了上面提到的小错误外,使用 YAML 中的 load_stream 函数可能比 load

更成功
def readData
  File.open('filename.yml') do |f|
    arr = YAML.load_stream(f)
    if arr
      puts arr
      puts arr.class
    end
  end
end

虽然我不会这样做,但它允许您从任何来源附加到文件,只要它与 YAML 保持兼容。

我的偏好是使用数据库。

在我的系统上(运行 通过 rubocop)生成的完整代码是:

require 'yaml'

def add_data
  puts 'Enter country name :'
  name = gets.chop.to_s
  puts 'Enter population in billion :'
  population = gets.chop.to_s
  puts 'Enter GDP in lakh crore USD:'
  gdp = gets.chop.to_s
  puts 'Enter army strength:'
  army_strength = gets.chop.to_s
  puts 'Enter state of country:'
  state = gets.chop.to_s

  country = {}
  country = { 'name' => name, 'population' => population, 'gdp' => gdp, 'army_strength' => army_strength, 'state' => state }

  # Writing to the file
  File.open('filename.yml', 'a') { |f| YAML.dump(country, f) }
end

def read_data
  arr = []
  File.open('filename.yml') do |f|
    arr = YAML.load_stream(f)
  end
  return unless arr

  puts arr
  puts arr.class
end

loop do
  puts '1. Write', '2. Read', '3.Exit'
  opt = gets.chop.to_i
  break if opt > 2

  case opt
  when 1
    add_data
  when 2
    read_data
  end
end