module ClassAttribute def self.included(base) base.extend ClassMethods end module ClassMethods # Based on `class_attribute` from Rails, without the options we don't use. # https://github.com/rails/rails/blob/main/activesupport/lib/active_support/core_ext/class/attribute.rb def tiny_class_attribute(name, default: nil) class_methods, methods = [], [] methods << <<~RUBY def #{name} defined?(@#{name}) ? @#{name} : self.class.#{name} end RUBY class_methods << <<~RUBY def #{name}=(value) define_method(:#{name}) { value } if singleton_class? define_singleton_method(:#{name}) { value } value end RUBY methods << <<~RUBY attr_writer :#{name} RUBY location = caller_locations(1, 1).first class_eval(["class << self", *class_methods, "end", *methods].join(";").tr("\n", ";"), location.path, location.lineno) public_send(:"#{name}=", default) end end end