class EcoRake module Default module Const class << self def included(base) super base.extend EcoRake::Base::SymbolResolver base.extend ClassMethods end end module ClassMethods # Creates (overridable) method(s) that link to an expected constant with same name (in capitals). # @note this creates one method on the class and one on instances thereof. # @param required [Boolean] whether an exception should be raised if the constant does not exist # when the created method is called. # @param override [Boolean] whether an exception should NOT be raised if the method exists. # @param default [Variant] whether if this defaults to some value (won't raise NameError). def attr_const(*attrs, required: false, override: false, default: :not_used) attrs.each do |attr| attr = attr.to_s.freeze unless override msg = "#{__method__} does not allow method override. Offending attr: #{attr}" raise ArgumentError, "#{msg} (class method)" if methods.include?(attr) raise ArgumentError, "#{msg} (instance method)" if instance_methods.include?(attr) end define_singleton_method attr do value = resolve_const(attr) value = default if value.nil? && default != :not_used msg = "Missing const '#{attr.to_s.upcase}' in #{self}" raise NameError, msg if value.nil? && required yield(value) if block_given? value end define_method attr do |&block| self.class.send(attr, &block) end end end end end end end