class Module

  private

  # In a module definition you can include a call to
  # included_in_class_callbacks(base) at the end of the
  # self.included(base) callback. Any modules that your module includes
  # will receive an included_in_class callback when your module is
  # included in a class. Useful if the sub-module wants to do something
  # like alias_method_chain on the class.
  def included_in_class_callbacks(base)
    if base.is_a?(Class)
      included_modules.each { |m| m.try.included_in_class(base) }
    end
  end

  # Creates a class attribute reader that will delegate to the superclass
  # if not defined on self. Default values can be a Proc object that takes the class as a parameter.
  def inheriting_cattr_reader(*names)
    names_with_defaults = (names.pop if names.last.is_a?(Hash)) || {}

    (names + names_with_defaults.keys).each do |name|
      ivar_name = "@#{name}"
      block = names_with_defaults[name]
      self.send(self.class == Module ? :define_method : :meta_def, name) do
        if instance_variable_defined? ivar_name
          instance_variable_get(ivar_name)
        else
          superclass.respond_to?(name) && superclass.send(name) ||
          block && begin
            result = block.is_a?(Proc) ? block.call(self) : block
            instance_variable_set(ivar_name, result) if result
          end
        end
      end
    end
  end

  def inheriting_cattr_accessor(*names)
    names_with_defaults = (names.pop if names.last.is_a?(Hash)) || {}

    names_with_defaults.keys.each do |name|
      attr_writer name
      inheriting_cattr_reader names_with_defaults.slice(name)
    end
    names.each do |name|
      attr_writer name
      inheriting_cattr_reader name
    end
  end


  # creates a #foo= and #foo? pair, with optional default values, e.g.
  # bool_attr_accessor :happy => true
  def bool_attr_accessor(*args)
    options = (args.pop if args.last.is_a?(Hash)) || {}

    (args + options.keys).each {|n| class_eval "def #{n}=(x); @#{n} = x; end" }

    args.each {|n| class_eval "def #{n}?; @#{n}; end" }

    options.keys.each do |n|
      class_eval %(def #{n}?
                     if !defined? @#{n}
                       @#{n} = #{options[n] ? 'true' : 'false'}
                     else
                       @#{n}
                     end
                   end)
      set_field_type(n => TrueClass) if respond_to?(:set_field_type)
    end
  end

  def alias_class_method_chain(method, feature)
    meta_eval do
      alias_method_chain method, feature
    end
  end

end


# classy_module lets you extract code from classes into modules, but
# still write it the same way
module Kernel

  def classy_module(mod=Module.new, &b)
    mod.meta_def :included do |base|
      base.class_eval &b
    end
    mod
  end

end

class Object

  def is_one_of?(*args)
    args.any? {|a| is_a?(a) }
  end

end
