【问题标题】:Ruby Script: undefined method `symbolize_keys' error loading YAML filesRuby 脚本:加载 YAML 文件的未定义方法“symbolize_keys”错误
【发布时间】:2018-08-16 19:58:23
【问题描述】:

我有一个用于 yaml 合并的 ruby​​ 脚本,如下所示

#!/usr/bin/env ruby

require 'yaml'

raise "wrong number of parameters" unless ARGV.length == 2

y1 = YAML.load_file(ARGV[0]).symbolize_keys
y2 = YAML.load_file(ARGV[1]).symbolize_keys
puts y1.merge!(y2).to_yaml

当我执行它时:

./test.rb ./src/api/config/config1.yml ./src/api/config/config2.yml

我遇到以下错误:

./test.rb:5:in `<main>': undefined method `symbolize_keys' for {"root"=>{"cloud.n2"=>{"accessKey"=>"I5VAJUYNR4AAKIZDH777"}}}:Hash (NoMethodError)

【问题讨论】:

  • 你有安装 Rails 吗?
  • symbolize_keys 来自 Rails 中的 activesupport。您还需要requireactivesupport。

标签: ruby scripting yaml


【解决方案1】:

Hash#symbolize_keys 方法来自activesupport gem (activesupport/lib/active_support/core_ext/hash/keys.rb)。

为了使用它,您需要在脚本中添加以下行:

require "active_support"

【讨论】:

    【解决方案2】:

    虽然其他答案/cmets 是正确的,但为此要求所有 ActiveSupport 似乎有点过头了。而是使用:

    require 'active_support/core_ext/hash/keys' 
    

    或者,如果您可以控制 yml 文件,那么只需在其中制作键符号并避免任何转换。例如

    require 'yaml'
    yml = <<YML
    :root:
      :cloud.n2:
        :accessKey: "I5VAJUYNR4AAKIZDH777"
    YML
    YAML.load(yml)
    #=> {:root=>{:"cloud.n2"=>{:accessKey=>"I5VAJUYNR4AAKIZDH777"}}}
    

    【讨论】:

      【解决方案3】:

      这并不能真正回答您的问题,但 Ruby 2.5.0 引入了Hash#transform_keys (release notes),它也可用于表示键,并且位于核心 Ruby 中。

      {'a' => 1, 'b' => 2}.transform_keys(&:to_sym)
      #=> {:a=>1, :b=>2}
      

      还有一个 bang 版本,它改变哈希而不是创建一个新的。

      【讨论】:

        【解决方案4】:

        正如其他人已经指出的那样,symbolize_keys 是一个ActiveSupport 方法。如果您没有使用ActiveSupport,和/或在不包含transform_keys 的 Ruby 2.5 之前的版本上,您可以自己定义它。

        class Hash
        
          def transform_keys
            return enum_for(:transform_keys) unless block_given?
            result = self.class.new
            each_key do |key|
              result[yield(key)] = self[key]
            end
            result
          end
        
          def transform_keys!
            return enum_for(:transform_keys!) unless block_given?
            keys.each do |key|
              self[yield(key)] = delete(key)
            end
            self
          end
        
          def symbolize_keys
            transform_keys{ |key| key.to_sym rescue key }
          end
        
          def symbolize_keys!
            transform_keys!{ |key| key.to_sym rescue key }
          end
        end
        

        这并不是说您的脚本可能不需要 Rails 或 ActiveSupport 的其他依赖项。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-16
          • 1970-01-01
          相关资源
          最近更新 更多