从YAML创建嵌套对象以通过Ruby中的方法调用访问属性 [英] Create nested object from YAML to access attributes via method calls in Ruby

查看:149
本文介绍了从YAML创建嵌套对象以通过Ruby中的方法调用访问属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对红宝石完全陌生. 我必须解析一个YAML文件来构造一个对象

I am completely new to ruby. I have to parse a YAML file to construct an object

YAML文件

projects:
  - name: Project1
    developers:
      - name: Dev1
        certifications:
          - name: cert1
      - name: Dev2
        certifications:
          - name: cert2
  - name: Project2
    developers:
      - name: Dev1
        certifications:
          - name: cert3
      - name: Dev2
        certifications:
          - name: cert4

我想从此YAML创建一个对象,为此我在Ruby中编写了以下代码

I want to create an object from this YAML for which I wrote the following code in Ruby

require 'yaml'
object = YAML.load(File.read('./file.yaml'))

我可以使用[]成功访问该对象的属性 例如

I can successfully access the attributes of this object with [] For e.g.

puts object[projects].first[developers].last[certifications].first[name]
# prints ABC

但是,我想通过方法调用来访问属性

However, I want to access the attributes via method calls

例如

puts object.projects.first.developers.last.certifications.first.name
# should print ABC

有什么方法可以构造这样的对象,该对象的属性可以通过上述(点)方式进行访问? 我已经阅读了 OpenStruct hashugar . 我也想避免使用第三方宝石

Is there any way to construct such an object whose attributes can be accessed in the (dots) way mentioned above? I have read about OpenStruct and hashugar. I also want to avoid usage of third party gems

推荐答案

如果您只是在进行实验,则有一种快速而肮脏的方法:

If you are just experimenting, there is a quick and dirty way to do this:

class Hash
  def method_missing(name, *args)
    send(:[], name.to_s, *args)
  end
end

我不会在生产代码中使用它,因为method_missing和猴子补丁通常都是解决问题的方法.

I wouldn't use that in production code though, since both method_missing and monkey-patching are usually recipes for trouble down the road.

更好的解决方案是递归遍历数据结构,并用openstruct代替散列.

A better solution is to recursively traverse the data-structure and replace hashes with openstructs.

require 'ostruct'
def to_ostruct(object)
  case object
  when Hash
    OpenStruct.new(Hash[object.map {|k, v| [k, to_ostruct(v)] }])
  when Array
    object.map {|x| to_ostruct(x) }
  else
    object
  end
end

puts to_ostruct(object).projects.first.developers.last.certifications.first.name

请注意,如果您经常做这两种方法,那么这两种方法都可能存在性能问题-如果您的应用程序对时间敏感,请确保对其进行基准测试!不过,这可能与您无关.

Note that there are potentially performance issues with either approach if you are doing them a lot - if your application is time-sensitive make sure you benchmark them! This probably isn't relevant to you though.

这篇关于从YAML创建嵌套对象以通过Ruby中的方法调用访问属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆