nil:NilClass MD5 程序中没有方法错误

nil:NilClass NoMethodError in MD5 program

我正在创建一个工具,将密码转换为 YAML 文件中的 MD5 哈希值,而 运行 我的程序出现错误:

md5.rb:20:in `encrypt_md5': undefined method `[]=' for nil:NilClass (NoMethodError)
        from main.rb:12:in `main'
        from main.rb:40:in `<main>'

来自这个方法:

def encrypt_md5
    hash = load_file
    hash[:users][:"#{prompt('Enter username')}"] = 
        {password: prompt("Enter password")}
    save_file(hash)
    exit unless again?('encrypt md5')
end
#Digest::MD5 hasn't been implemented yet

我不完全确定是什么导致了 nil:NilClass NoMethodError,有人可以向我解释这意味着什么,并告诉我我需要更改哪些内容才能使其正常工作..

Main.rb 来源:

require_relative 'md5.rb'

def main
     puts <<-END.gsub(/^\s*>/, '')
                >
                >To load information type "L" to quit system type "Q"
                >
            END
    input = gets.chomp.upcase
    case input
    when "L"
        encrypt_md5
    when "Q"
        exit_system
    else
        exit_lock
    end
end

def exit_system
    puts "Exiting..."
    exit
end

def exit_lock #Not finished, will lock user out of program
    puts "Locked out, please contact system administrator"
    exit
end

def again? #Not complete
    puts "Encrypt more?"
    input = gets.chomp
    return input =~ /yes/i
end

def prompt( message )
    puts message
    gets.chomp
end
main

md5.rb 来源:

require 'yaml'
require 'digest'

private

    def load_file
        File.exist?('info.yml') ? YAML.load_file('info.yml') : {passwords: {}}
    end

    def read_file
        File.read('info.yml')
    end

    def save_file
        File.open('info.yml', 'w') { |s| s.write('info.yml')}
    end

    def encrypt_md5
        hash = load_file
        hash[:users][:"#{prompt('Enter username')}"] = 
            {password: prompt("Enter password")}
        save_file(hash)
        exit unless again?('encrypt md5')
    end

错误大概在这里:

hash = load_file
hash[:users][:"#{prompt('Enter username')}"] = 
  { password: prompt("Enter password") }

您正在 hash[:users] 上调用 []= 方法,但 hash[:users]nil。由于您没有 post info.yml 的内容,我只能猜测您有一个像这样的 YAML 文件:

users:
  some_user:
    password: foobar
  another_user:
    password: abcxyz
  # ...

当您对该文件执行 YAML.load_file 时,您会得到此哈希值:

hash = {
  "users" => {
    "some_user" => { "password" => "foobar" },
    "another_user" => { "password" => "abcxyz" },
    # ...
  }
}

有了这个,hash[:users] 就是 nil 因为没有 :users 键,只有 "users" 键。虽然您可以跳过一些步骤将您的键变成符号,但在任何地方都使用字符串键会容易得多:

hash = load_file
hash["users"][prompt('Enter username')] =
    { "password" => prompt("Enter password") }

P.S。您的代码还有一些问题,特别是这里:

def save_file
    File.open('info.yml', 'w') { |s| s.write('info.yml')}
end

首先,您调用了 save_file(hash),但是您的 save_file 方法没有接受任何参数。这将引发一个 ArgumentError。其次,此方法中的代码所做的是打开文件 info.yml,然后将字符串 "info.yml" 写入该文件。你可能想要的是这样的:

def save_file(hash)
    File.open('info.yml', 'w') {|f| f.write(hash.to_yaml) }
end