
class Object

  # Takes a hash and creates (singleton) attr_readers for each key.
  #
  #   with_reader { :x => 1, :y => 2 }
  #   @x       #=> 1
  #   @y       #=> 2
  #   self.x   #=> 1
  #   self.y   #=> 2
  #
  def with_reader(h)
    (class << self ; self ; end).send( :attr_reader, *h.keys )
    h.each { |k,v| instance_variable_set("@#{k}", v) }
  end

  # Takes a hash and creates (singleton) attr_writers for each key.
  #
  #   with_writer { :x => 1, :y => 2 }
  #   @x           #=> 1
  #   @y           #=> 2
  #   self.x = 3
  #   self.y = 4
  #   @x           #=> 3
  #   @y           #=> 4
  #
  def with_writer(h)
    (class << self ; self ; end).send( :attr_writer, *h.keys )
    h.each { |k,v| instance_variable_set("@#{k}", v) }
  end

  # Takes a hash and creates (singleton) attr_accessors
  # for each key.
  #
  #   with_accessor { :x => 1, :y => 2 }
  #   @x          #=> 1
  #   @y          #=> 2
  #   self.x = 3
  #   self.y = 4
  #   self.x      #=> 3
  #   self.y      #=> 4
  #
  def with_accessor(h)
    (class << self ; self ; end).send( :attr_accessor, *h.keys )
    h.each { |k,v| instance_variable_set("@#{k}", v) }
  end

end


#  _____         _
# |_   _|__  ___| |_
#   | |/ _ \/ __| __|
#   | |  __/\__ \ |_
#   |_|\___||___/\__|
#
=begin test

  require 'test/unit'

  class TCKernel < Test::Unit::TestCase
    # fixture for #with_reader, #with_writer and #with_accessor
    class TestWith
      def initialize
        with_reader :foo => "FOO"
        with_writer :bar => "BAR"
        with_accessor :baz => "BAZ"
      end
      def get_bar
        @bar
      end
    end

    def test_with_reader
      assert_nothing_raised { @t = TestWith.new }
      assert_equal("FOO", @t.foo)
    end

    def test_with_writer
      assert_nothing_raised { @t = TestWith.new }
      assert_equal("BAR", @t.get_bar)
      @t.bar = "BAR2"
      assert_equal("BAR2", @t.get_bar)
    end

    def test_with_accessor
      assert_nothing_raised { @t = TestWith.new }
      assert_equal("BAZ", @t.baz)
      @t.baz = "BAZ2"
      assert_equal("BAZ2", @t.baz)
    end
  end

=end
