Ruby - 使用YAML解析一个Hash字符串 - 如果hash输入raw并强制转换为字符串而不是作为字符串输入,则会出错

时间:2015-06-24 20:15:35

标签: ruby git hash yaml

我有一个我创建的gem,它将Git包装为一个键:值存储(字典/散列)。来源是here

在引用的过程中它的工作方式如下:

  1. 运行包含键和值参数的函数set
  2. 使用git散列这些,在散列
  3. 处有关键点
  4. 如果此操作成功,则返回密钥,并将其添加到全局字典“holing keys and hashes”
  5. 现在,如果我打电话给

    db.set('key', {some: 'value'})
    # => 'key'
    

    然后尝试检索此内容,

    db.get('key')
    Psych::SyntaxError: (<unknown>): did not find expected node content while parsing a flow node at line 1 column 2
    from /home/bobby/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/psych.rb:370:in `parse'
    from /home/bobby/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/psych.rb:370:in `parse_stream'
    from /home/bobby/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/psych.rb:318:in `parse'
    from /home/bobby/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/psych.rb:245:in `load'
    from /home/bobby/.rvm/gems/ruby-2.2.1/gems/gkv-0.2.1/lib/gkv/database.rb:21:in `get'
    from (irb):6
    from /home/bobby/.rvm/rubies/ruby-2.2.1/bin/irb:11:in `<main>'
    

    现在,如果我将密钥设置为相同的字典,但是将其设置为字符串:

    db.set('key', "{some: 'value'}")
    # => 'key'
    db.get('key')
    # => {"key"=>"value"} 
    db.get('key').class
    => Hash
    

    执行git操作'并将它们包装到kv商店源的操作是:

    ...
        def get(key)
          if $ITEMS.keys.include? key
            YAML.load(Gkv::GitFunctions.cat_file($ITEMS[key].last))
          else
            raise KeyError
          end
        end
    
        def set(key, value)
          update_items(key, value.to_s)
          key
        end
    ...
    

    此处引用的get_items函数的来源是:

    ...    
      def update_items(key, value)
          if $ITEMS.keys.include? key
            history = $ITEMS[key]
            history << Gkv::GitFunctions.hash_object(value.to_s)
            $ITEMS[key] = history
          else
            $ITEMS[key] = [Gkv::GitFunctions.hash_object(value.to_s)]
          end
        end
      end
    ...
    

    hash_objectcat_object简单包装git hash-objectgit cat-file在将输入写入tmpfile,git add,然后删除tempfile的方法中

    我真的不知道为什么这会用字符串而不是真正的字典。如果您使用旧的hashrocket语法,则会导致完全相同的错误:

    db.set('a', {:key => 'value'})
    => "a" 
    db.get('a')
    # => Psych::SyntaxError: (<unknown>): did not find expected node content while parsing a flow node at line 1 column 2
    from /home/bobby/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/psych.rb:370:in `parse'
    from /home/bobby/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/psych.rb:370:in `parse_stream'
    from /home/bobby/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/psych.rb:318:in `parse'
    from /home/bobby/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/psych.rb:245:in `load'
    from /home/bobby/.rvm/gems/ruby-2.2.1/gems/gkv-0.2.1/lib/gkv/database.rb:21:in `get'
    from (irb):6
    from /home/bobby/.rvm/rubies/ruby-2.2.1/bin/irb:11:in `<main>'
    

    有什么想法吗?

1 个答案:

答案 0 :(得分:2)

get方法中,您拨打YAML.load,但在您设置的方法中,您使用的是.to_s。这意味着YAML解析器正在尝试读取任意字符串,就像它是YAML一样。对于对称YAML.dump应该在set方法中使用。

我已经创建了带有更改的拉取请求。