Sha256: 462d155a91edf9b756ceb68dffb5430d142ffe318e41b22982b5b2f2046beaca

Contents?: true

Size: 1.59 KB

Versions: 1

Compression:

Stored size: 1.59 KB

Contents

# frozen_string_literal: true
module Upgrow
  # A read-only Object. An Immutable Object is initialized with its attributes
  # and subsequent state changes are not permitted.
  class ImmutableObject
    @attribute_names = []

    class << self
      attr_reader :attribute_names

      # Specify an attribute for the Immutable Object. This enables the object
      # to be instantiated with the attribute, as well as creates an attribute
      # reader for it.
      #
      # @param name [Symbol] the name of the attribute.
      def attribute(name)
        @attribute_names << name
        attr_reader(name)
      end

      private

      def inherited(subclass)
        super
        subclass.instance_variable_set(:@attribute_names, @attribute_names.dup)
      end
    end

    # Initializes a new Immutable Object with the given member values.
    #
    # @param args [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(**args)
      absent_attributes = args.keys - self.class.attribute_names

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

      args.each do |name, value|
        instance_variable_set("@#{name}", value)
      end

      freeze
    end

    # The collection of attributes and their values.
    #
    # @return [Hash<Symbol, Object>] the collection of attributes and their
    #   values.
    def attributes
      self.class.attribute_names.to_h { |name| [name, public_send(name)] }
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
upgrow-0.0.2 lib/upgrow/immutable_object.rb