require "attr_extras/version" require "attr_extras/attr_initialize" require "attr_extras/attr_value" require "attr_extras/attr_query" require "attr_extras/attr_implement" require "attr_extras/utils" module AttrExtras # To avoid masking coding errors, we don't inherit from StandardError (which would be implicitly rescued). Forgetting to define a requisite method isn't just some runtime error. class MethodNotImplementedError < Exception; end def self.mixin self::Mixin end # Separate module so that mixing in the methods doesn't also mix in constants: # http://thepugautomatic.com/2014/02/private-api/ module Mixin def attr_initialize(*names, &block) AttrInitialize.new(self, names, block).apply end def attr_private(*names) # Need this to avoid "private attribute?" warnings when running # the full test suite; not sure why exactly. public attr_reader(*names) private(*names) end def attr_value(*names) AttrValue.new(self, *names).apply end def pattr_initialize(*names, &block) attr_initialize(*names, &block) attr_private(*Utils.flat_names(names)) end alias_method :attr_private_initialize, :pattr_initialize def vattr_initialize(*names, &block) attr_initialize(*names, &block) attr_value(*Utils.flat_names(names)) end alias_method :attr_value_initialize, :vattr_initialize def rattr_initialize(*names, &block) attr_initialize(*names, &block) attr_reader(*Utils.flat_names(names)) end alias_method :attr_reader_initialize, :rattr_initialize def aattr_initialize(*names, &block) attr_initialize(*names, &block) attr_accessor(*Utils.flat_names(names)) end alias_method :attr_accessor_initialize, :aattr_initialize def static_facade(method_name_or_names, *names) Array(method_name_or_names).each do |method_name| define_singleton_method(method_name) do |*values, &block| new(*values).public_send(method_name, &block) end end pattr_initialize(*names) end def method_object(*names) static_facade :call, *names end def attr_query(*names) AttrQuery.define_with_suffix(self, "", *names) end def attr_id_query(*names) AttrQuery.define_with_suffix(self, "_id", *names) end def attr_implement(*names) AttrImplement.new(self, names).apply end def cattr_implement(*names) AttrImplement.new(self.singleton_class, names).apply end end end