module Kernel

  # Alias a method defined in the metaclass (ie. singleton class).
  #
  #   def X.y?; "y?" ; end
  #   X.meta_alias "ynot?", "y?"
  #   X.ynot?  #=> y?
  #
  #  CREDIT: Trans

  def meta_alias(*args)
    meta_class do
      alias_method(*args)
    end
  end

  # Evaluate code in a metaclass. This is equivalent to
  # 'meta_class.instance_eval'.
  #
  #  CREDIT: WhyTheLuckyStiff

  def meta_eval(str=nil, &blk)
    if str
      meta_class.instance_eval(str)
    else
      meta_class.instance_eval(&blk)
    end
  end

  # Add method to a meta-class --i.e. a singleton method.
  #
  #   class X; end
  #   X.meta_def(:x){"x"}
  #   X.x  #=> "x"
  #
  #  CREDIT: WhyTheLuckyStiff

  def meta_def( name, &block )
    meta_class do
      define_method( name, &block )
    end
  end

  # Easy access to an object's "special" class,
  # otherwise known as it's metaclass or singleton class.

  def meta_class(&block)
    if block_given?
      (class << self; self; end).class_eval(&block)
    else
      (class << self; self; end)
    end
  end

  alias_method :metaclass, :meta_class

  # Access to an object's "special" class, otherwise
  # known as it's eigenclass or metaclass, etc.
  #
  # One day these names must be reconciled!

  def singleton
    (class << self; self; end)
  end

  def singleton_class
    (class << self; self; end)
  end

  # During this trying time when no one can get their
  # techie catchwords to stick to the refrigerator no
  # matter how hard they slap it # with the enchanted
  # magnetic spatula, it’s good to know that the
  # contrived phrases really do fly, graceful and
  # unclasped and bearing north toward chilled shrimp.
  # I know what my Hallowe’en pumpkin is going to say.
  #
  #                       -- why the lucky stiff
  #
  #   CREDIT: WhyTheLuckyStiff

  def eigenclass
    (class << self; self; end)
  end

  #  # Easy access to an object qua class, otherwise
  #  # known as the object's metaclass or singleton class.
  #  #
  #  # Yes, another one.
  #  #
  #  #   CREDIT: Trans
  #
  #  def qua_class(&block)
  #    if block_given?
  #      (class << self; self; end).class_eval(&block)
  #    else
  #      (class << self; self; end)
  #    end
  #  end
end


class Module

  # Defines an instance method within a class.
  #
  #   CREDIT: WhyTheLuckyStiff

  def class_def name, &blk
    class_eval { define_method name, &blk }
  end

  protected :attr
  protected :attr_reader
  protected :attr_writer
  protected :attr_accessor
  protected :remove_method
  protected :undef_method

end

class String

  # Append an "@" to the beginning of a string
  # to make a instance variable name. This also replaces
  # non-valid characters with underscores.

  def variablize
    "@#{self}".gsub(/\W/, '_').to_sym
  end

end

class Symbol

  # Append an "@" to the beginning of a symbol
  # to make a instance variable name. This also replaces
  # non-valid characters with underscores.

  def variablize
    "@#{self}".gsub(/\W/, '_').to_sym
  end

end

