AttributeStruct
AttributeStruct is a DSL helper library. It provides support for programmatic generation of complex data structures.
How it works
Under the hood, AttributeStruct makes use of Ruby's BasicObject
class and the
#method_missing
method to bring a clean and concise way of generating data
structures. Deeply nested Hashes can be built using method chaining, block
structures, or both. Evaluation of a structure is performed top down, allowing
access to previously set data values within the structure during evaluation.
Examples
Setting values
Method chaining
require 'attribute_struct'
AttributeStruct.new do
this.is.a.deeply.nested.hash true
end.dump!
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"nested"=>{"hash"=>true}}}}}}
Block nesting
require 'attribute_struct'
AttributeStruct.new do
this do
is do
a do
deeply do
nested do
hash true
end
end
end
end
end
end.dump!
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"nested"=>{"hash"=>true}}}}}}
Mixed block nesting and method chaining
require 'attribute_struct'
AttributeStruct.new do
this.is.a do
deeply.nested do
hash true
end
end
end.dump!
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"nested"=>{"hash"=>true}}}}}}
Structure re-entry
Block re-entry
require 'attribute_struct'
AttributeStruct.new do
this.is.a do
deeply.nested do
hash true
end
deeply do
nested.other_hash true
end
end
end.dump!
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"nested"=>{"hash"=>true,"other_hash"=>true}}}}}}
Method re-entry
require 'attribute_struct'
AttributeStruct.new do
this.is.a do
deeply.nested do
hash true
end
end
this.is.a.deeply.nested.other_hash true
end.dump!
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"nested"=>{"hash"=>true,"other_hash"=>true}}}}}}
Data removal
require 'attribute_struct'
AttributeStruct.new do
this.is.a do
deeply.nested do
hash true
end
end
this.is.a.deeply.nested.other_hash true
this.is.a.deeply.nested.delete!(:hash)
end.dump!
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"nested"=>{"other_hash"=>true}}}}}}
Data Access
Current data
require 'attribute_struct'
AttributeStruct.new do
this.is.a do
deeply.nested do
hash 'my_value'
end
end
this.is.a.deeply.nested do
other_hash data![:hash]
end
end.dump!
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"nested"=>{"hash"=>"my_value","other_hash"=>"my_value"}}}}}}
Current data keys
require 'attribute_struct'
AttributeStruct.new do
this.is.a do
deeply.nested do
hash 'my_value'
end
end
this.is.a.deeply.nested do
other_hash keys!
end
end.dump!
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"nested"=>{"hash"=>"my_value","other_hash"=>["hash"]}}}}}}
Hierarchy access
Parent structure
require 'attribute_struct'
AttributeStruct.new do
this.is.a do
deeply do
state 'sunny'
nested do
hash parent!.state
end
end
end
end.dump!
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"state"=>"sunny", "nested"=>{"hash"=>"sunny"}}}}}}
Root structure
require 'attribute_struct'
AttributeStruct.new do
this.is.a do
deeply do
state 'sunny'
nested do
hash root!.this.is.a.deeply.state
end
end
end
end.dump!
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"state"=>"sunny", "nested"=>{"hash"=>"sunny"}}}}}}
Camel case
Camel case keys
require 'attribute_struct'
AttributeStruct.new do
self._camel_keys = true
this.is.a.deeply.nested_camel.hash true
end.dump!
# => {"This"=>{"Is"=>{"A"=>{"Deeply"=>{"NestedCamel"=>{"Hash"=>true}}}}}}
Camel case with lead lower
require 'attribute_struct'
AttributeStruct.new do
self._camel_keys = true
self._camel_style = :no_leading
this.is.a.deeply.nested_camel.hash true
end.dump!
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"nestedCamel"=>{"hash"=>true}}}}}}
Disable camel on individual key
require 'attribute_struct'
AttributeStruct.new do
self._camel_keys = true
this.is.a.deeply.nested_camel.hash true
this.set!('horse'.no_hump!, true)
end.dump!
# => {"This"=>{"Is"=>{"A"=>{"Deeply"=>{"NestedCamel"=>{"Hash"=>true}}}}},"horse" => true}
Augmented AttributeStruct
An augmented version of the AttributeStruct is available that includes
the Kernel
module to provide many common methods. This can reduce the
usability of the struct by defining methods that may collide with desired
key entries. It is important to be aware of this when using the augmented
version. To create an augmented version:
require 'attribute_struct'
AttributeStruct::Augmented.new do
rand_value rand
end.dump!
# => {"rand_value"=>0.7983473046826768}
Kernel methods can also be injected into raw AttributeStruct instance. Again, caution must be used to prevent unintended collisions:
require 'attribute_struct'
AttributeStruct.new do
kernelify!
rand_value rand
end.dump!
# => {"rand_value"=>0.24500702285393017}
In the wild
Libraries utilizing AttributeStruct:
- SparkleFormation: http://www.sparkleformation.io
- Bogo Config: https://github.com/spox/bogo-config