Techioz Blog

yaml ファイルを逆シリアル化しようとすると、Psych::DisallowedClass が表示されます

概要

def start_game
        game = true
        loop do
            print "number of chances remaining: #{@chances} \n"
            print "#{@dash.join('')} \n"
            puts "type your letters to play(or type 'save' to save the game at any point)"
            check_letter = gets.chomp.downcase
        
            if check_letter == 'save'
                save_file
            elsif @secret_word.include?(check_letter)
                array_of_guess_word =  @secret_word.split('')
                arr2 = array_of_guess_word.each_index.select {|x| array_of_guess_word[x] == check_letter}
                arr2.each do |idx|
                    @dash[idx] = check_letter 
                end
            else  
                @guessed_letter << check_letter
            end
            
            print "Letters not inlcuded: #{@guessed_letter} \n\n"
            print "Yes! the word was: #{@secret_word} \n You won congratulations #{@name}" if @dash.eql?(array_of_guess_word)
            break if @dash.eql?(array_of_guess_word)|| @chances == 0
            @chances -= 1
        end
    end

     def load_file
       if !Dir.exist?('./saved_games/')
        loop do 
         puts '\nNo saved games!'
         break if user_input == '1'
        end
       else
        loaded_game =
         File.open("./saved_games/#{load_file_name}.yml", 'r') do |file|
            YAML.load(file)
            end
            loaded_game.start_game
        end
    end

    def load_file_name
        saved_games = Dir.glob('saved_games/*').map {|game| game.split('/').last.split('.yml').first}
        file_count = saved_games.count 
        loop do 
            puts "Enter a number to load the game: "
            saved_games.each_with_index {|game , idx| puts "#{idx + 1} , #{game}"}
            file_number = gets.chomp.strip
            if /\A[0-9]+\Z/.match?(file_number) &&  file_number.to_i <= file_count
            return saved_games[file_number.to_i - 1]
            end
        puts "\nInvalid input.\n\n"
        end
    end 

ファイルをロードしようとすると、psych::DisallowedClass というエラーが表示されます。 yaml コードを逆シリアル化できません

どこで間違ったのか正確に知りたいです。コードで使用したインスタンス変数が原因だと思います。連載初心者です

解決策

デフォルトでは、Psych (Ruby が YAML を処理するために使用するライブラリ) は、セキュリティ上の理由から、限定されたクラスのリスト (TrueClass、FalseClass、NilClass、Integer、Float、String、Array、Hash) のみを逆シリアル化できます。

他のクラス (例ではカスタム Hangman クラスなど) を YAML ファイルから逆シリアル化できるようにしたい場合は、それらのクラスを明示的に許可する必要があります。

YAML.load_file(file_name, permitted_classes: [Hangman])

次のようにload_fileメソッドを変更することをお勧めします。

def load_file
  if Dir.exist?('./saved_games/')
    file_name = "./saved_games/#{load_file_name}.yml"

    loaded_game = YAML.load_file(file_name, permitted_classes: [Hangman])
    loaded_game.start_game
  else
    loop do 
      puts "\nNo saved games!"
      break if user_input == '1'
    end
  end
end