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

Ser*_*ize 11 ruby 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)

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

vby*_*yno 8

我用类似的东西

hash = { a: 2, b: 3 }

Struct.new(*hash.keys).new(*hash.values).freeze
Run Code Online (Sandbox Code Playgroud)

获取一个不可变的对象,该对象会NoMethodError在调用意外方法时引发


dbe*_*hur 7

当您设置新成员时,OpenStruct在对象上定义单例访问器方法,因此您可以使用它respond_to?来查看该成员是否有效.实际上你可能只是捕获任何未使用method_missing定义的方法并抛出错误,除非它是一个setter方法名称,在这种情况下你将它传递给super.

class WhinyOpenStruct < OpenStruct
  def method_missing(meth, *args)
    raise NoMemberError, "no #{meth} member set yet" unless meth.to_s.end_with?('=')
    super
  end
end
Run Code Online (Sandbox Code Playgroud)


dja*_*ski 7

如果您需要严格的哈希,只需:

class StrictHash < Hash
  alias [] fetch
end
Run Code Online (Sandbox Code Playgroud)

它按预期工作:

hash = StrictHash[foo: "bar"]

hash[:foo]
# => "bar"

hash[:qux]
# stricthash.rb:7:in `fetch': key not found: :qux (KeyError)
#         from stricthash.rb:7:in `<main>'
Run Code Online (Sandbox Code Playgroud)

  • 我在寻找的是“点访问”,而不是哈希访问。+1优雅。 (2认同)

Ser*_*ize 1

我采用了这个解决方案,它完全满足我的需要:

class Request < Hash
  class RequestError < StandardError; end
  class MissingAttributeError < RequestError; end

  def initialize(hash)
    hash.each do |key, value|
      self[key] = value
    end
  end

  def [](key)
    unless self.include?(key)
      raise MissingAttributeError.new("Attribute '#{key}' not found in request")
    end

    super
  end
end
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用“fetch”方法而不是在此处覆盖“[]”。http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-fetch (2认同)