Search code examples
rubyopenstruct

Raise exception when accessing attributes that doesn't exist in OpenStruct


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.


Solution

  • I went with this solution which does exactly what I need:

    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