Sha256: ce89d7b8efe8b49c7aacbbd561330a47dc6dacb688241d6cef5f4f73214125e2

Contents?: true

Size: 1.24 KB

Versions: 1

Compression:

Stored size: 1.24 KB

Contents

module Structure
  def self.included(base)
    base
      .extend(ClassMethods)
      .instance_variable_set(:@attribute_names, [])
  end

  def attributes
    self.class.attribute_names.reduce({}) { |ret, name|
      ret.update(name => self.send(name))
    }
  end

  def ==(other)
    attributes == other.attributes
  end

  def inspect
    "#<#{self.class} #{
      attributes
        .map { |key, val|
          if val.is_a?(Array) && val.size > 3
            "#{key}=[#{val.take(3).map(&:inspect).join(', ')}...]"
          else
            "#{key}=#{val.inspect}"
          end
        }
        .join(', ')
    }>"
  end

  alias_method :to_h, :attributes
  alias_method :eql?, :==
  alias_method :to_s, :inspect

  module ClassMethods
    attr_reader :attribute_names

    def to_struct
      return Struct.const_get(name, false) if Struct.const_defined?(name, false)

      Struct.new(name, *attribute_names) do
        def initialize(data = {})
          data.each { |key, val| self.send("#{key}=", val) }
        end
      end
    end

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

    def attribute(name, &blk)
      define_method(name, &blk)
      @attribute_names << name
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
structure-0.27.4 structure.rb