Skip to content

Instantly share code, notes, and snippets.

@aquabu
Created December 2, 2011 03:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aquabu/1421555 to your computer and use it in GitHub Desktop.
Save aquabu/1421555 to your computer and use it in GitHub Desktop.
NestedStruct
# evolved from http://stackoverflow.com/questions/4911807/cannot-access-id-field-of-openstruct-instance
class NestedStruct
def initialize( hash= {})
hash.each{ |key, value| add_field(key,value) }
end
def add_field( attribute_name, value=nil )
(class << self; self; end).class_eval do
attr_accessor attribute_name
end
value = NestedStruct.new(value) if value.class == Hash
self.send(attribute_name.to_s + "=", value)
end
def []=( name, value )
add_field(name,value)
end
end
describe NestedStruct do
before do
@dog = NestedStruct.new
end
it "can be initialized with a nested hash" do
nested_struct = NestedStruct.new({:foo => :bar, :a => {:b => "nested value"}})
nested_struct.foo.should == :bar
nested_struct.a.b.should == "nested value"
end
it "can do multi-level attribute nesting" do
nested_struct = NestedStruct.new({:a => {:b => {:c => "nested value"}}})
nested_struct.a.b.c.should == "nested value"
end
it "can be created without pre-defining the struct keys" do
@dog.class.should == NestedStruct
end
it "can define struct keys after the fact with []" do
@dog[:bark]= "woof"
@dog.bark.should == "woof"
end
it "can set an #id attribute" do
@dog[:id] = "abc123"
@dog.id.should == "abc123"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment