ゲームの状態をシリアル化および逆シリアル化するために、この 2 つの関数があります。無事に動作しました。しかし、それは非常に乱雑で乱雑に感じます。これを行うためのより良いアプローチはありますか?
2 つの異なるクラス変数があり、1 つは Main クラスから、3 つはguess クラスの親である Game クラスからシリアル化する必要があります。以下のメソッドは Main クラスから呼び出されます。
def save_game(obj)
saved_data = {
score: obj.score,
secret_word: obj.new_guess.secret_word,
running_guess: obj.new_guess.running_guess,
not_in_word: obj.new_guess.not_in_word
}.to_json
save_file(saved_data)
end
def load_game(obj)
saved_data = JSON.load_file('saved/saved_game.json')
obj.score = saved_data['score']
obj.new_guess.secret_word, = saved_data['secret_word']
obj.new_guess.running_guess = saved_data['running_guess']
obj.new_guess.not_in_word = saved_data['not_in_word']
display_secret_hidden(obj.new_guess.running_guess)
display_not_included_letters(obj.new_guess.not_in_word)
play_rounds
end
私はこれを理解しようとしていますが、別の解決策を見つけることができますが、これまでのところ別の方法でこれを行うことができません。
それが Ruby の新しい Data Object の 1 つであれ、お母さんが昔作ったような昔ながらの Struct であれ、各要素をさまざまな場所でオンザフライでシリアル化しようとするよりも、ある種のデータ構造のインスタンス変数を渡す方が良いでしょう。
JSON、YAML、または Marshal のようなバイナリ形式にシリアル化する場合でも、コードをよりクリーンにする方法があります。 Marshal と YAML はオブジェクトのシリアル化をより適切に実行します。 JSON は、明示的な手順を踏まない限り、その点でもう少し制限があります。そこで、Marshal を使用して、serializd オブジェクトを簡単に復活させる方法をデモンストレーションします。
次の例では、@file と @save_data のアクセス可能な属性を使用して、ゲームの保存を Games クラスにラップします。次のことを考慮してください。
class Game
attr_accessor :file, :save_data
SaveData =
Struct.new *%i[score secret_word running_guess not_in_word]
def initialize(filename="game_save.bin", **kwargs)
@file = filename
@save_data = SaveData.new
@save_data.members.map { @save_data[_1] = kwargs[_1] }
end
def save
File.open(@file, ?w) { Marshal.dump @save_data, _1 }
end
def load
@save_data = Marshal.load File.read(file)
end
end
if __FILE__ == $0
# create a new game and populate some data.
game = Game.new score: 1, foo: 2, not_in_word: 3
# save the game to a file, then clobber the file
# and display the now-empty Struct.
game.save
game.save_data = Game::SaveData.new
game.save_data
# load and display the previous save
game.load
end
Struct を使用すると、受け渡すことができるデータ オブジェクトが得られるため、この目的には最適です。 Struct オブジェクトとグロブ化されたキーワード引数の分解を組み合わせることで、何も失うことなくコードが大幅に簡素化され、ドライアップされます。