require 'facets/core/hash/normalize_keys'

class Hash

  # Converts all keys in the Hash to Symbols, returning a new Hash.
  # With a +filter+, limits conversion to only a certain selection of keys.
  #
  #   foo = { :name=>'Gavin', 'wife'=>:Lisa }
  #   foo.symbolize_keys    #=>  { :name=>"Gavin", :wife=>:Lisa }
  #   foo.inspect           #=>  { "name" =>"Gavin", "wife"=>:Lisa }
  #
  #--
  # Adapted from Gavin Sinclair's graceous work #symbolify_keys.
  #++
  def symbolize_keys( &filter )
    if filter
      normalize_keys{ |k| filter[k] ? k.to_sym : nil }
    else
      normalize_keys{ |k| k.to_sym }
    end
  end

  alias_method( :keys_to_sym, :symbolize_keys )

  #--
  # # Rails has these aliases too, but they are not very good for
  # # gerenal use, IMHO. But perhaps someone can convince me otherwise.
  # alias_method( :to_options,  :symbolize_keys )
  #++

  # Synonym for Hash#symbolize_keys, but modifies the receiver in place and returns it.
  # With a +filter+ parameter, limits conversion to only a certain selection of keys.
  #
  #   foo = { 'name'=>'Gavin', 'wife'=>:Lisa }
  #   foo.symbolize_keys!    #=>  { :name=>"Gavin", :wife=>:Lisa }
  #   foo.inspect            #=>  { :name=>"Gavin", :wife=>:Lisa }
  #
  #--
  # Adapted from Gavin Sinclair's graceous work #symbolify_keys!
  #++
  def symbolize_keys!( &filter )
    if filter
      normalize_keys!{ |k| filter[k] ? k.to_sym : nil }
    else
      normalize_keys!{ |k| k.to_sym }
    end

  end

  alias_method( :keys_to_sym!, :symbolize_keys! )

  #--
  # # Rails has these aliases too, but they are not very good for
  # # gerenal use, IMHO. But perhaps someone can convince me otherwise.
  # alias_method( :to_options!, :symbolize_keys! )
  #++

end


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

  require 'test/unit'

  class TCHash < Test::Unit::TestCase

    def test_keys_to_sym
      foo = { 'a'=>1, 'b'=>2 }
      assert_equal( { :a=>1, :b=>2 }, foo.symbolize_keys )
      assert_equal( { "a" =>1, "b"=>2 }, foo )
    end

    def test_keys_to_sym!
      foo = { 'a'=>1, 'b'=>2 }
      assert_equal( { :a=>1, :b=>2 }, foo.symbolize_keys! )
      assert_equal( { :a=>1, :b=>2 }, foo  )
    end

  end

=end
