Utils::Attributes

## Overview

A set of attributes.

It internally stores the data as a Hash.

All the operations covert keys to strings.
This strategy avoids memory attacks due to Symbol abuses when parsing
untrusted input.

At the same time, this allows to get/set data with the original key or
with the string representation. See the examples below.

## API

### #initialize

It recursively converts keys to strings.

```ruby
require 'lotus/utils/attributes'

attributes = Lotus::Utils::Attributes.new(a: 1, b: { 2 => [3, 4] } })
attributes.to_h # => { "a" => 1, "b" => { "2" => [3, 4] } }
```

### #get 

It converts the given attribute name to a string and then read the value.

```ruby
require 'lotus/utils/attributes'

attributes = Lotus::Utils::Attributes.new(a: 1, 'b' => 2, 23 => 'foo')

attributes.get(:a)  # => 1
attributes.get('a') # => 1

attributes.get(:b)  # => 2
attributes.get('b') # => 2

attributes.get(23)   # => "foo"
attributes.get('23') # => "foo"

attributes.get(:unknown)  # => nil
attributes.get('unknown') # => nil
```

### #set 

It converts the given attribute name to a string and then store the value

```ruby
require 'lotus/utils/attributes'

attributes = Lotus::Utils::Attributes.new

attributes.set(:a, 1)
attributes.get(:a)  # => 1
attributes.get('a') # => 1

attributes.set('b', 2)
attributes.get(:b)  # => 2
attributes.get('b') # => 2

attributes.set(23, 'foo')
attributes.get(23)   # => "foo"
attributes.get('23') # => "foo"
```

References:
  * [Lotus::Entity](https://github.com/lotus/model/pull/101#issuecomment-64196926)
  * [Lotus::Validations::Attributes](https://github.com/lotus/validations/blob/master/lib/lotus/validations/attributes.rb#L9-L10)

Benchmark:
  * https://gist.github.com/jodosha/a35b8e6d25e5d3742d0e
s/"/'