ruby搞yaml(附赠一个方法)

作者:周星 发布:2017-10-07

       在 Rails 中,配置文件大多都为 yml 格式,同 xml、json 一样,yml 是一种文件格式,它以缩进来表示层级关系,博主认为其可读性要强于 xml 和 json,我们在写一些脚本时经常会用到它,今天我们来分享一下 ruby 如何生成 yaml、解析 yml 等常见操作。

       ruby 内置了一个库 YAML,直接引入它即可,有了它处理 yaml 文件就非常容易了。如下示例文件:test.yml

# test.yml
person:
  first_name: "x"
  last_name: "z"
address:
  province: "sichuan"
  street: "dayuan"

解析 test.yml:

# encoding: utf-8
require 'yaml' 
#先解析 test.yml为一个hash (load_file 或者 使用 IO)
puts YAML.load_file("./test.yml") 
puts YAML.load(File.open("./test.yml"))

# 把 yaml 转化成字符串
YAML.load("--- foo") #=> "foo"

# 直接创建一个 yaml
YAML.dump("foo")     # => "--- foo\n...\n"
{ :a => 'b'}.to_yaml  # => "---\na b\n"

友情提示:不要随便 load yaml 文件,因为里面可能含有的恶意代码。

YAML::Store 可以把对象保存到 yaml 文件里:

require 'yaml/store'

Person = Struct.new :first_name, :last_name

people = [Person.new("Bob", "Smith"), Person.new("Mary", "Johnson")]

store = YAML::Store.new "test.yml"

store.transaction do
  store["people"] = people
  store["greeting"] = { "hello" => "world" }
end

解析上面代码生成的 test.yml,需要事先在 ruby 程序声明 Person 类,否则会报错找不到 module 或 class Person

赠送一段代码,将 Array 或 Hash 转化为 Object(递归),代码参考了 rails_config 源码

#!/usr/bin/ruby
require 'ostruct'

arr = [["a", 2], ["b", 4]]
hash = {a: "b", c: "d"}

def to_obj(h)
  s = OpenStruct.new
  h.each do |k, v|
    k = k.to_s if !k.respond_to?(:to_sym) && k.respond_to?(:to_s)
    s.new_ostruct_member(k)

    if v.is_a?(Hash)
      v = v["type"] == "hash" ? v["contents"] : to_obj(v)
    elsif v.is_a?(Array)
      v = v.collect { |e| e.instance_of?(Hash) ? to_obj(e) : e }
    end

    s.send("#{k}=".to_sym, v)
  end
  s
end

puts to_obj(arr).a
puts to_obj(hash).a

支付宝扫码赞助博主


评论(0)