Ruby - 使用 YAML 解析哈希的字符串 - 如果哈希输入原始并强制转换为字符串而不是作为字符串输入则出错
Ruby - Parsing a string of a Hash using YAML - Error if hash entered raw and coerced to string rather than entered as string
我创建了一个 gem,将 Git 包装为 key:value 商店 (dictionary/hash)。来源是 here.
它在引用的过程中的工作方式如下:
- 运行 函数
set
包含一个键和一个值参数
- 用 git 散列这些,在散列中有关键点
- return 如果此操作成功并且它被添加到全局字典中的键和散列
现在,如果我调用类似
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_object
和 cat_object
简单包装 git hash-object
和 git cat-file
方法将输入写入 tmpfile,git add
ing 它,然后擦除临时文件。
我真的不知道为什么这适用于字符串而不适用于真正的字典。如果您也使用旧的 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>'
有什么想法吗?
在您的 get
方法中您调用 YAML.load
,但在您的设置方法中您使用 .to_s
。这意味着 YAML 解析器正在尝试读取任意字符串,就好像它是 YAML 一样。为了对称性,YAML.dump
应该在 set
方法中使用。
我已经创建了包含更改的拉取请求。
我创建了一个 gem,将 Git 包装为 key:value 商店 (dictionary/hash)。来源是 here.
它在引用的过程中的工作方式如下:
- 运行 函数
set
包含一个键和一个值参数 - 用 git 散列这些,在散列中有关键点
- return 如果此操作成功并且它被添加到全局字典中的键和散列
现在,如果我调用类似
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_object
和 cat_object
简单包装 git hash-object
和 git cat-file
方法将输入写入 tmpfile,git add
ing 它,然后擦除临时文件。
我真的不知道为什么这适用于字符串而不适用于真正的字典。如果您也使用旧的 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>'
有什么想法吗?
在您的 get
方法中您调用 YAML.load
,但在您的设置方法中您使用 .to_s
。这意味着 YAML 解析器正在尝试读取任意字符串,就好像它是 YAML 一样。为了对称性,YAML.dump
应该在 set
方法中使用。
我已经创建了包含更改的拉取请求。