Skip to content

Instantly share code, notes, and snippets.

@miyucy
Created September 6, 2010 12:16
Show Gist options
  • Select an option

  • Save miyucy/566968 to your computer and use it in GitHub Desktop.

Select an option

Save miyucy/566968 to your computer and use it in GitHub Desktop.
require 'ostruct'
class OpenStruct
DEPTH = 5
def self.deep(data, depth=0, &blck)
return data if depth > DEPTH
return data unless data.class == Hash
hash = {}
data.each do |key, value|
key = blck.call(key) if block_given?
case value
when Hash
hash[key] = OpenStruct.deep(value, depth + 1, &blck)
when Array
hash[key] = value.map{ |element| OpenStruct.deep(element, depth + 1, &blck) }
else
hash[key] = value
end
end
OpenStruct.new(hash)
end
end
if __FILE__ == $PROGRAM_NAME
require 'pp'
data = {
:data => 0,
:depth1 => {
:data => 1,
:depth2 => {
:data => 2,
:depth3 => {
:data => 3,
:depth4 => {
:data => 4,
:depth5 => {
:data => 5,
:depth6 => {
:data => 6,
},
},
},
},
},
},
}
value = OpenStruct.deep(data)
value.data
# => 0
value.depth1.data
# => 1
value.depth1.depth2.data
# => 2
value.depth1.depth2.depth3.data
# => 3
value.depth1.depth2.depth3.depth4.data
# => 4
value.depth1.depth2.depth3.depth4.depth5.data
# => 5
value.depth1.depth2.depth3.depth4.depth5.depth6[:data]
# => 6
value = OpenStruct.deep(data) do |key|
key.to_s.upcase
end
value.DATA
# => 0
value.DEPTH1.DATA
# => 1
value.DEPTH1.DEPTH2.DATA
# => 2
value.DEPTH1.DEPTH2.DEPTH3.DATA
# => 3
value.DEPTH1.DEPTH2.DEPTH3.DEPTH4.DATA
# => 4
value.DEPTH1.DEPTH2.DEPTH3.DEPTH4.DEPTH5.DATA
# => 5
value.DEPTH1.DEPTH2.DEPTH3.DEPTH4.DEPTH5.DEPTH6[:data]
# => 6
data = {
:ary => [ 1,
{
:data => 1,
:ary => [1,2,3,],
},
3, ],
:data => 0
}
value = OpenStruct.deep(data)
value.data
# => 0
value.ary[0]
# => 1
value.ary[2]
# => 3
value.ary[1]
# => #<OpenStruct ...>
value.ary[1].data
# => 1
value.ary[1].ary
# => [1, 2, 3]
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment