Sha256: 9779d094b9eb392ddc9e355cc9cb17db26a67211bbcfef767c7576b09df9395e

Contents?: true

Size: 1.5 KB

Versions: 3

Compression:

Stored size: 1.5 KB

Contents

# frozen_string_literal: true

require_relative 'schema'

module Upgrow
  # A read-only Object. An Immutable Object is initialized with its attributes
  # and subsequent state changes are not permitted.
  class ImmutableObject
    @schema = Schema.new

    class << self
      attr_accessor :schema

      # Defines an attribute in the Immutable Object Schema.
      #
      # @param name [Symbol] the name of the attribute.
      def attribute(name)
        schema.attribute(name)
      end

      private

      def inherited(subclass)
        super
        subclass.schema = @schema.dup
      end
    end

    attr_reader :attributes

    # Initializes a new Immutable Object with the given member values.
    #
    # @param attributes [Hash<Symbol, Object>] the list of values for each
    #   attribute of the Immutable Object.
    #
    # @raise [ArgumentError] if the given argument is not an attribute.
    def initialize(**attributes)
      absent_attributes = attributes.keys - self.class.schema.attribute_names

      if absent_attributes.any?
        raise ArgumentError, "Unknown attribute #{absent_attributes}"
      end

      @attributes = self.class.schema.attribute_names.to_h do |name|
        [name, attributes[name]]
      end.freeze

      freeze
    end

    private

    def method_missing(name, *args, &block)
      super unless attributes.include?(name)
      attributes.fetch(name)
    end

    def respond_to_missing?(name, _include_private = false)
      attributes.include?(name) || super
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
upgrow-0.0.5 lib/upgrow/immutable_object.rb
upgrow-0.0.4 lib/upgrow/immutable_object.rb
upgrow-0.0.3 lib/upgrow/immutable_object.rb