Skip to content

Instantly share code, notes, and snippets.

@jvmvik
Created April 1, 2021 19:31
Show Gist options
  • Save jvmvik/a450024c5981bd994547cc84a27a01c9 to your computer and use it in GitHub Desktop.
Save jvmvik/a450024c5981bd994547cc84a27a01c9 to your computer and use it in GitHub Desktop.
Ruby - Monkey patch the basic hash and array for more productivity
# Monkey patch Ruby Array class
#
class Array
def each_with_last
size = self.size
each_with_index do |e, index|
yield(e, (index == size-1))
end
end
def deep_copy()
new_array = []
self.each do |item|
new_array << item.dup
end
return new_array
end
end
# Monkey patch for Hash
#
# - Merge recursively
# - Sorting
# - Deep freeze
#
class Hash
# Sort hash
#
def sort(hash = self)
if hash.class == Hash
h = Hash.new
hash.keys.map(&:to_s).sort.each do |k|
h[k] = hash[k]
if h[k].class == Hash
h[k] = h[k].sort
elsif h[k].class == Array
h[k].each_with_index do |e, i|
next if e.class != Hash
h[k][i] = e.sort
end
end
end
return h
end
return hash
end
# copy nested hash into another hash
# reason: clone operation do not consider nested object
#
def copy(hash, base = self)
base.each do |key, v|
if v.is_a?(Hash)
hash[key] = Hash.new unless hash[key]
copy(hash[key], v)
else
hash[key] = v
end
end
return hash
end
# deep clone
# @return [Hash] hash which true clone
def deep_clone
h = {}
copy(h)
return h
end
# freeze recursively
#
def recursive_freeze
base = self
base.keys.each do |key|
if base[key].is_a?(Hash)
base[key].recursive_freeze
else
base[key].freeze
end
end
base.freeze
end
# usage:
# mxp['port']['device'].each_port do |port_number, port_string, dev_list|
def each_port
self.each do |key, value|
next unless key =~ /^p(\d)$/
yield($1.to_i, key, value)
end
end
# Recursive merge of two hash
# The primary hash is modified by this merge
#
def recursive_merge(hash = nil)
return self unless hash.is_a?(Hash)
base = self
hash.each do |key, v|
if base[key].is_a?(Hash) && hash[key].is_a?(Hash)
base[key].recursive_merge(hash[key].dup)
elsif hash[key].is_a?(Hash)
base[key]= hash[key].dup
else
base[key]= hash[key]
end
end
base
end
# Recursive update all keys with new value
# The hash can be composed of hashs and arrays
def recursive_update(key, new_value, hash=self)
# replace value
if hash.respond_to?(:key?) && hash.key?(key)
hash[key] = new_value
end
# recurse through hash structure
hash.values.each do |v|
if v.class == Hash
v.recursive_update(key, new_value)
elsif v.class == Array
v.each do |e|
if e.class == Hash
e.recursive_update(key, new_value)
end
end
end
end
end
# Freeze recursively
#
def deep_freeze
base = self
base.keys.each do |key|
if base[key].is_a?(Hash)
base[key].deep_freeze
else
base[key].freeze
end
end
base.freeze
end
def deep_freeze!
deep_freeze
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment