I'm trying to figure out how to make it so that a subclass of OpenStruct (or any class for that matter), or hash, will raise a custom exception if I try to access an attribute that hasn't been set. I couldn't get define_method
and method_missing
to do this so I'm clueless how it should be done in Ruby.
Here's an example:
class Request < OpenStruct...
request = Request.new
begin
request.non_existent_attr
rescue CustomError...
I could imagine it would have to be something like this:
class Hash
# if trying to access key:
# 1) key exists, return key
# 2) key doesn't exist, raise exception
end
Edit: Attributes that exist shouldn't raise an exception. The functionality I'm looking for is so that I can just access attributes freely and if it happens not to exist my custom exception will be raised.
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 objects are useful when you need something to fit a certain method call interface (i.e. send in a duck-typed object responding to #name and #value ), or when you want to encapsulate the implementation details, but also want to avoid over-engineering the solution.
What is a Struct in Ruby? A struct is a built-in Ruby class, it's used to create new classes which produce value objects. A value object is used to store related attributes together.
I use something like
hash = { a: 2, b: 3 }
Struct.new(*hash.keys).new(*hash.values).freeze
to get an immutable object which will raise NoMethodError
in case unexpected method is invoked
If you need a strict hash, simply:
class StrictHash < Hash
alias [] fetch
end
It works as expected:
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>'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With