Sha256: 7b5aff2b1109cb2d2aa011c1a1cb5c8b14d8141d08504c344442d9cc20c92412

Contents?: true

Size: 1.43 KB

Versions: 1

Compression:

Stored size: 1.43 KB

Contents

require "kwattr/version"

module KWAttr

  def kwattr(*attrs, **opts)
    names = [*attrs, *opts.keys]
    attr_reader(*names)
    prepend Initializer
    extend Heritable
    required, defaults = kwattrs
    attrs.each { |attr| required << attr unless required.include?(attr) }
    defaults.merge!(opts)
    names
  end

  def kwattrs
    @kwattrs ||= [[], {}]
  end

  module Heritable
    def inherited(subclass)
      required, defaults = kwattrs
      subclass.kwattr(*required, **defaults)
    end

    alias_method :included, :inherited
  end

  module Initializer
    def initialize(*args, **kwargs)
      required, defaults = self.class.kwattrs
      required = required.dup
      defaults.merge(kwargs).each_pair do |key, value|
        next unless required.delete(key) || defaults.key?(key)
        kwargs.delete(key)
        instance_variable_set "@#{key}", value
      end
      unless required.empty?
        raise ArgumentError,
          "missing keyword#{'s' if required.size > 1}: #{required.join(', ')}"
      end
      if method(:initialize).super_method.arity == args.size && !kwargs.empty?
        raise ArgumentError,
          "unknown keyword#{'s' if kwargs.size > 1}: #{kwargs.keys.join(', ')}"
      end
      args << kwargs unless kwargs.empty?
      super(*args)
    end
  end

end

public def kwattr(*args)
  raise TypeError, "wrong type #{self.class} (expected Module)" unless Module === self
  extend KWAttr
  kwattr(*args)
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
kwattr-0.2.0 lib/kwattr.rb