标签: openstruct

我何时应该使用OpenStruct而不是Hash?

我喜欢"任意属性的定义",我认为ruby中的OpenStruct有时比使用散列更清晰,但我很好奇是否有其他特定的优点或用例使OpenStruct成为比单纯使用更好的选择哈希.

ruby ruby-1.9.3 openstruct

27
推荐指数
2
解决办法
9059
查看次数

访问OpenStruct中不存在的属性时引发异常

我试图找出如何使它成为一个OpenStruct的子类(或任何类的东西)或哈希,如果我尝试访问尚未设置的属性将引发自定义异常.我无法得到define_methodmethod_missing做到这一点,所以我无能应该如何在Ruby中进行.

这是一个例子:

class Request < OpenStruct...

request = Request.new

begin
  request.non_existent_attr
rescue CustomError...
Run Code Online (Sandbox Code Playgroud)

我可以想象它必须是这样的:

class Hash
  # if trying to access key:
  # 1) key exists, return key
  # 2) key doesn't exist, raise exception
end
Run Code Online (Sandbox Code Playgroud)

编辑:存在的属性不应引发异常.我正在寻找的功能是,我可以自由访问属性,如果它不存在我的自定义异常将被引发.

ruby openstruct

11
推荐指数
4
解决办法
3143
查看次数

我可以扩展Ruby类以动态地表现得像OpenStruct吗?

我有一个包含模块的Ruby类.我希望include类的行为类似于OpenStruct.如何在不明确继承OpenStruct的情况下实现这一目标?

class Book
  include MyModule
end

module MyModule
  def self.included(klass)
    # Make including class behave like OpenStruct
  end
end
Run Code Online (Sandbox Code Playgroud)

代替

class Book < OpenStruct
  include MyModule
end
Run Code Online (Sandbox Code Playgroud)

ruby module metaprogramming mixins openstruct

7
推荐指数
1
解决办法
4504
查看次数

从YAML创建嵌套对象以通过Ruby中的方法调用访问属性

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

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
Run Code Online (Sandbox Code Playgroud)

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

require 'yaml'
object = YAML.load(File.read('./file.yaml'))
Run Code Online (Sandbox Code Playgroud)

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

puts object[projects].first[developers].last[certifications].first[name]
# prints ABC
Run Code Online (Sandbox Code Playgroud)

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

例如

puts object.projects.first.developers.last.certifications.first.name
# should print ABC
Run Code Online (Sandbox Code Playgroud)

有什么方法可以构造可以通过上述(点)方式访问其属性的对象?我已经读过有关OpenStructhashugar的文章。我也想避免使用第三方宝石

parsing yaml openstruct

5
推荐指数
2
解决办法
3152
查看次数

构造嵌套的 OpenStruct 对象

我必须模仿 Google API 响应并创建一个可通过.如下方式遍历的 2 级深层数据结构:

=> user.names.first_name
Run Code Online (Sandbox Code Playgroud)

鲍勃

有没有比这更聪明/更好的方法:

 user = OpenStruct.new(names: OpenStruct.new(first_name: 'Bob'))
Run Code Online (Sandbox Code Playgroud)

ruby openstruct

5
推荐指数
1
解决办法
2952
查看次数

如何将递归/嵌套的 OpenStruct 对象转换为哈希

我有一个 OpenStruct 对象,需要转换为 JSON 数据。

样本哈希(来自 RSPEC 助手):

def test_order
 {
   "id": 505311428702,
   "email": "test@gmail.com",
   "closed_at": "",
   "discount_codes": {
      "id": 507328175,
      "text": "test"
   }
 }
end
Run Code Online (Sandbox Code Playgroud)

我正在使用以下函数进行递归:

def to_recursive_ostruct(hash)
  OpenStruct.new(hash.each_with_object({}) do |(key, val), memo|
    memo[key] = val.is_a?(Hash) ? to_recursive_ostruct(val) : val
  end)
end
Run Code Online (Sandbox Code Playgroud)

对于前 to_recursive_ostruct(test_order),将返回:

<OpenStruct id=505311428702, email="test@gmail.com", closed_at="", ...>
Run Code Online (Sandbox Code Playgroud)

转换后,使用OpenStructObject.marshal_dump

{
:id=>505311428702, :email=>"test@gmail.com", :closed_at=>"", 

discount_codes=>#<OpenStruct id=507328175, text= "test">}
}
Run Code Online (Sandbox Code Playgroud)

OpenStructObject.marshal_dump在第一级给了我正确的数据,

我还希望转换嵌套数据。

我真正需要的是:

{:id=>505311428702, :email=>"test@gmail.com", :closed_at=>"", :discount_codes=>{:id=>507328175, :text=> "test"} }
Run Code Online (Sandbox Code Playgroud)

请帮忙,提前致谢。

ruby json ruby-on-rails openstruct

5
推荐指数
1
解决办法
3380
查看次数

OpenStruct.new存储属性但不检索它

在创建一个新的Ruby OpenStruct对象之后,我能够存储属性但不能检索它们(我得到一个空行而是返回nil):

obj = OpenStruct.new # => #<OpenStruct>
obj.x = 10
obj.y = 20
obj                  # => #<OpenStruct x=10, y=20>
obj.x                # => 10
obj.y                #  
                     # => nil
Run Code Online (Sandbox Code Playgroud)

如果我尝试使用不同的名称存储其他属性,一切都按预期工作.这个问题似乎只有在我存储一个名为的属性时才会发生y.我使用以下版本:

ruby 1.9.2p320 (2012-04-20 revision 35421) [i686-linux]

有没有人知道发生了什么?

ruby null openstruct

4
推荐指数
1
解决办法
312
查看次数

在OpenStruct中使用marshal_load

如何使用OpenStruct的marshal_load实用程序?它似乎没有按预期工作.

文档提供了这个示例,但它似乎不起作用.

require 'ostruct'

event = OpenStruct.new
hash = { 'time' => Time.now, 'title' => 'Birthday Party' }
event.marshal_load(hash)
event.title # => nil
Run Code Online (Sandbox Code Playgroud)

如果不是这样,我如何将哈希加载到OpenStruct(不使用构造函数)?

对于上下文:我正在从YAML文件加载哈希并将其加载到OpenStruct子类的现有实例中.

ruby openstruct

3
推荐指数
1
解决办法
415
查看次数

Ruby 2.3.1的OpenStruct问题

在Ruby 2.1.5和2.2.4中,创建一个新的收集器会返回正确的结果.

require 'ostruct'
module ResourceResponses
  class Collector < OpenStruct
    def initialize
      super
      @table = Hash.new {|h,k| h[k] = Response.new }
    end
  end

  class Response
    attr_reader :publish_formats, :publish_block, :blocks, :block_order
    def initialize
      @publish_formats = []
      @blocks = {}
      @block_order = []
    end
  end  
end

 > Collector.new
 => #<ResourceResponses::Collector>
 Collector.new.responses
 => #<ResourceResponses::Response:0x007fb3f409ae98 @block_order=[], @blocks=  {}, @publish_formats=[]>
Run Code Online (Sandbox Code Playgroud)

当我升级到Ruby 2.3.1时,它开始返回nil而不是.

> Collector.new
=> #<ResourceResponses::Collector>
> Collector.new.responses
=> nil
Run Code Online (Sandbox Code Playgroud)

我已经做了很多关于OpenStruct如何在2.3中快10倍的阅读但是我没有看到会破坏收集器和响应之间关系的改变.非常感谢任何帮助.Rails的版本是4.2.7.1.

ruby ruby-on-rails openstruct ruby-2.3.1

2
推荐指数
1
解决办法
335
查看次数

使用 JSON.parse 解析 OpenStruct 或哈希

我试图解析这样一个简单的 JSON:

JSON.parse({"pong": "ok"})
Run Code Online (Sandbox Code Playgroud)

它失败了

2.4.0 :014 > JSON.parse({"pong": "ok"})
TypeError: no implicit conversion of Hash into String
    from (irb):14
Run Code Online (Sandbox Code Playgroud)

这里有什么问题?为什么要转换为 String ?

另一个尝试,这次使用OpenStruct

2.4.0 :001 > pong = OpenStruct.new(pong: 'OK')
 => #<OpenStruct pong="OK"> 
2.4.0 :002 > JSON.parse(pong)
TypeError: no implicit conversion of OpenStruct into String
    from (irb):2
Run Code Online (Sandbox Code Playgroud)

相同 ?谢谢

ruby json hashmap openstruct

1
推荐指数
1
解决办法
1700
查看次数

如何以编程方式向对象添加属性?

我有一个哈希数组,我宁愿把它变成一个对象数组,其中的属性以编程方式添加到这些对象中.

我现在正试试这个

obj = OpenStruct.new

resulthash["users"].collect { |u|
  u.each do |k,v|
    obj.send("#{k}=#{v}");
  end
}
Run Code Online (Sandbox Code Playgroud)

回顾一下我正在尝试做的事

obj.foo = "bar"
obj.hello = "world"
Run Code Online (Sandbox Code Playgroud)

但是以编程方式,例如对于数组/哈希看起来喜欢这个

{"users"=>[{"foo"=>"bar","hello"=>"world"}]}
Run Code Online (Sandbox Code Playgroud)

ruby openstruct

0
推荐指数
1
解决办法
573
查看次数