Refactoring for efficiency (non-breaking-changes)

* Compose a `Hash` rather than extending `OpenStruct` (this simplified a
  number of things)
* Dynamically define reader/writer methods on write
* Use `method_missing` to handle dot-notation