0

アプリケーションで使用されるオプションをダンプおよびロードするために、Ruby (1.9.3) で YAML を使用しています。

ファイルのパスは、アプリのメインの実行可能ファイルによって読み込まれる constants.rb ファイルの定数に格納されます。オプションは、ハッシュから直接継承する Options クラスとしてロードされます (クラス Options < Hash)。

オプション ファイルに保存されている YAML を読み込もうとすると、SystemStackError: stack too deep が発生します (workspace.rb:80 からの irb またはコマンド ラインから to_ruby.rb:306 から)。

以下にクラスのコードを置きます。コメントいただければ幸いです。ありがとう

class Options < Hash
  attr_reader :path, :default_content

  def initialize
    @path = LOG_DIR + '/options.yml'
    @default_content = { auto: true, cbz: true, is_set_up: false }

    if File.exists?( @path )
      self.merge!( YAML.load( File.read( @path ) ) )
    else
      load_default
    end
  end

  def update( key, value )
    if self.has_key?( key )
      self[key] = value
      File.open( @path, 'w' ).write( YAML.dump( self ) )
    else
      puts 'That key does not exist'
    end
  end

  def load_default
    # load default options
    self.merge!( @default_content )
  end
end

Options.new

ロードしようとしている yaml は次のとおりです。

--- !ruby/hash:Options
:auto: true
:cbz: true
:is_set_up: true
4

1 に答える 1

0

これを削除します:

--- !ruby/hash:Options

これを残す:

:auto: true
:cbz: true
:is_set_up: true

その行は、Options クラスのシリアル化されたインスタンスであり、Options クラスのイニシャライザに自身のインスタンスをロードさせることは、スタック爆発のレシピです。

これで動作するはずです:

def update( key, value )
  if self.has_key?( key )
    self[key] = value
    File.open( @path, 'w' ) do |f|
      f.write( to_h.to_yaml )
    end
  else
    puts 'That key does not exist'
  end
end

to_h.to_yamlハッシュを YAML として書き出します。また、ブロック形式を使用すると、ブロックFile.openの最後でファイルが確実に閉じられます。

于 2013-09-01T15:12:35.343 に答える