class Module

  # Create an tester attribute. This creates two methods for
  # each given variable name. One is used to test
  # the attribute and the other is used to set or toggle it.
  #
  #   attr_tester :a
  #
  # is equivalent to
  #
  #   def a?
  #     @a ? true : @a
  #   end
  #
  #   def a!(switch=Exception)
  #     if switch == Exception
  #       @a = !@a
  #     else
  #       @a = switch ? true : @a
  #       self
  #     end
  #   end
  #
  def attr_tester(*args)
    make = {}
    args.each { |a|
      make["#{a}?".to_sym] = %{
        def #{a}?(true_value=true)
          @#{a} ? true_value : @#{a}
        end
      }
      make["#{a}!".to_sym] = %{
        def #{a}!(switch=Exception)
          if switch == Exception
            @#{a} = !@#{a}
          else
            @#{a} = switch ? true : @#{a}
            self
          end
        end
      }
    }
    module_eval make.values.join("\n")

    return make.keys
  end

end



#  _____         _
# |_   _|__  ___| |_
#   | |/ _ \/ __| __|
#   | |  __/\__ \ |_
#   |_|\___||___/\__|
#
=begin test
  require 'test/unit'

  class TestAttrTester < Test::Unit::TestCase
    class X
      attr_tester :a
    end

    def test_attr_tester_exclimation
      x = X.new
      assert_equal(nil, x.a?)
      x.a!
      assert_equal(true, x.a?)
      x.a!
      assert_equal(false, x.a?)
    end

    def test_attr_tester_return
      x = X.new
      x.a!
      assert_equal(true, x.a?)
      x.a!("whatever")
      assert_equal(true, x.a?)
    end
  end
=end

