Skip to content

Instantly share code, notes, and snippets.

@verticonaut
Last active December 19, 2015 02:28
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 verticonaut/5882880 to your computer and use it in GitHub Desktop.
Save verticonaut/5882880 to your computer and use it in GitHub Desktop.
Read and write in property style. Sample: ps = PropertyStruct.new; p['a1.a2.a3']=3 ps['a1'] = #<PropertyStruct:...> ps['a1.a2.a3'] = 3
class PropertyStruct
def initialize(nil_safe = true)
@nil_safe = !!nil_safe
@data = {}
end
def [](attribute)
result = @data
attributes = build_attribute_path(attribute)
attributes.each do |attr|
break if result.nil? && nil_safe?
result = read_object_value(result, attr)
end
result
end
def []=(attribute, value)
attributes = build_attribute_path(attribute)
if (attributes.length == 1)
@data[attribute] = value
return self
end
reader_attributes = attributes[0..-2]
writer_attribute = attributes[-1]
value_holder = self
reader_attributes.each do |attr|
result = read_object_value(value_holder, attr)
if result.nil? && value_holder.kind_of?(PropertyStruct)
result = PropertyStruct.new
value_holder[attr] = result
end
value_holder = result
end
write_object_value(value_holder, writer_attribute, value)
value
end
def nil_safe?
@nil_safe
end
private
def build_attribute_path(attribute)
attribute_path = clean_attribute_path(attribute)
attribute_path.split('.')
end
def clean_attribute_path(attribute)
attribute || ''
end
def read_object_value(object, attribute)
(object.kind_of?(Hash) || object.kind_of?(PropertyStruct)) ? object[attribute] : object.send(attribute)
end
def write_object_value(object, attribute, value)
(object.kind_of?(Hash) || object.kind_of?(PropertyStruct)) ? object[attribute] = value : object.send("#{attribute}=", value)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment