Struct && OpenStruct

一、需求

最近在做数据同步的应用,需要弄一个配置文件app.yml来进行应用的设置,例如:

work_type: target
config:
  name: bj-projects
  tables:
    - projects.employees
    - info.cities

读取出来很简单:

yml_file = 'config/app.yml'
configs = ActiveSupport::HashWithIndifferentAccess.new(YAML.load(IO.read(yml_file)))

# => {"work_type"=>"target", "config"=>{"name"=>"bj-projects", "tables"=>["projects.employees", "info.cities"]}}

使用的时候是这样的调用方式:

configs[:work_type], configs[:source][:config]

这种Hash的方式觉得很别扭,为什么不可以用这样的方式呢?

Config.work_type, Config.source

于是便发现了Struct和OpenStruct对象。

二、Struct类

Struct在 Ruby 中是用纯 C语言来实现的, 用于快速声明一个 Class, 例如:

dog = Struct.new("Dog", :name, :age)
fred = dog.new("fred", 5)
fred.age=6
printf "name:%s age:%d", fred.name, fred.age

等于你可以用Struct来迅速定义一个具有固定的属性的对象,在我的需求里面可以这样来解决:

configs = Struct.new('Config', :work_type, :source)
Config = configs.new(....)

感觉还是有点繁琐,不那么智能,而且对于没有一开始指定的属性,就不能使用了,例如:

Config.name  #会报错

三、OpenStruct类

于是今天的主角OpenStruct需要亮相了。

An OpenStruct is a data structure, similar to a Hash, that allows the definition of arbitrary attributes with their accompanying values. This is accomplished by using Ruby’s metaprogramming to define methods on the class itself.

OpenStruct是一个类似于Hash的数据结构,它可以允许定义任意的具有赋值的属性。

require 'ostruct'

person = OpenStruct.new
person.name    = "John Smith"
person.age     = 70
person.pension = 300

puts person.name     # -> "John Smith"
puts person.age      # -> 70
puts person.address  # -> nil

很神奇的地方,就是你可以随意指定它的属性,一旦赋值这个属性方法就存在了。

另外一个很方便的定义方法,即通过Hash来进行定义:

australia = OpenStruct.new(:country => "Australia", :population => 20_000_000)
p australia   # -> <OpenStruct country="Australia" population=20000000>

直接把Hash中的键值转换为类的属性。这就是我们需要的方法了。

yml_file = 'config/app.yml'
configs = ActiveSupport::HashWithIndifferentAccess.new(YAML.load(IO.read(yml_file)))
Config = OpenStruct.new(configs)

Config.work_type # => target
Config.source # => {name: ....}
# 然后还可以随意自行添加方法
Config.name  = Config.source['name']
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,768评论 0 9
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,923评论 18 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,765评论 18 399
  • 123.继承 一个类可以从另外一个类继承方法,属性和其他特征。当一个类继承另外一个类时, 继承类叫子类, 被继承的...
    无沣阅读 1,430评论 2 4
  • 1、请分别写出568A、568B的线序,并指出那几条走网络信号,如果走电话信号会用到其中几条? 解答:568A:白...
    Sudoke阅读 14,295评论 4 27