【问题标题】:Ruby - Parsing a string of a Hash using YAML - Error if hash entered raw and coerced to string rather than entered as stringRuby - 使用 YAML 解析哈希字符串 - 如果哈希输入原始并强制转换为字符串而不是作为字符串输入,则会出错
【发布时间】:2015-09-11 05:17:30
【问题描述】:

我创建了一个 gem,它将 Git 包装为 key:value 存储(字典/哈希)。来源是here

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

  1. 运行包含键和值参数的函数set
  2. 用 git 对这些进行散列,在散列处有关键点
  3. 如果此操作成功,则返回密钥并将其添加到全局字典中,并保存密钥和哈希

现在,如果我调用类似的东西

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 adding 它,然后擦除临时文件。

我真的不知道为什么这适用于字符串而不是真正的字典。如果你也使用旧的 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>'

有什么想法吗?

【问题讨论】:

    标签: ruby git hash yaml


    【解决方案1】:

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

    我已经创建了一个包含更改的拉取请求。

    【讨论】:

      猜你喜欢
      • 2015-04-02
      • 2013-02-04
      • 2014-07-10
      • 2017-03-06
      • 2018-03-09
      • 1970-01-01
      • 1970-01-01
      • 2010-11-05
      • 1970-01-01
      相关资源
      最近更新 更多