Skip to content

Instantly share code, notes, and snippets.

@Rhoxio
Last active May 16, 2025 18:37
Show Gist options
  • Save Rhoxio/7f14d77944f0e95988d35ad19b9e9d44 to your computer and use it in GitHub Desktop.
Save Rhoxio/7f14d77944f0e95988d35ad19b9e9d44 to your computer and use it in GitHub Desktop.
ActiveSupport-like overrides for plain Ruby
# LAST UPDATED ON: MAY 16, 2025
# Changed: Found an old String colorize method from ages ago.
# deep_symbolize_keys
class Hash
def deep_symbolize_keys
each_with_object({}) do |(key, value), result|
sym_key = key.respond_to?(:to_sym) ? key.to_sym : key
result[sym_key] = case value
when Hash then value.deep_symbolize_keys
when Array then value.map { |v| v.is_a?(Hash) ? v.deep_symbolize_keys : v }
else value
end
end
end
end
# deep_stringify_keys
class Hash
def deep_stringify_keys
each_with_object({}) do |(key, value), result|
str_key = key.to_s
result[str_key] = case value
when Hash then value.deep_stringify_keys
when Array then value.map { |v| v.is_a?(Hash) ? v.deep_stringify_keys : v }
else value
end
end
end
end
# blank?, present?
class Object
def blank?
respond_to?(:empty?) ? !!empty? : !self
end
def present?
!blank?
end
end
class NilClass; def blank?; true; end; end
class FalseClass; def blank?; true; end; end
class TrueClass; def blank?; false; end; end
class Array; def blank?; empty?; end; end
class Hash; def blank?; empty?; end; end
class String
def blank?
strip.empty?
end
end
# Deep merge
class Hash
def deep_merge(other_hash)
merge(other_hash) do |key, this_val, other_val|
if this_val.is_a?(Hash) && other_val.is_a?(Hash)
this_val.deep_merge(other_val)
else
other_val
end
end
end
end
# time utils, denominations: seconds, minuted, hours, days
class Numeric
def seconds; self; end
def minutes; self * 60; end
def hours; self * 60 * 60; end
def days; self * 60 * 60 * 24; end
end
# titleize, camelize
class String
def underscore
gsub(/::/, '/')
.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
.gsub(/([a-z\d])([A-Z])/,'\1_\2')
.tr("-", "_")
.downcase
end
def camelize(uppercase_first_letter = true)
str = split('_').map(&:capitalize).join
uppercase_first_letter ? str : str[0].downcase + str[1..]
end
end
# try, mainly used to make rspec tests be able to infer context more readily.
class Object
def try(method_name = nil, *args, &block)
if method_name.nil? && block
block.call(self)
elsif respond_to?(method_name)
public_send(method_name, *args, &block)
end
end
end
class NilClass
def try(*)
nil
end
end
# Hash.slice
class Hash
def slice(*keys)
keys.each_with_object({}) do |key, result|
result[key] = self[key] if key?(key)
end
end
end
# Hash.except
class Hash
def except(*keys)
reject { |key, _| keys.include?(key) }
end
end
# colorize String for shell output
class String
COLORS = {
black: 30, red: 31, green: 32, yellow: 33,
blue: 34, magenta: 35, cyan: 36, white: 37,
gray: 90,
on_black: 40, on_red: 41, on_green: 42,
on_yellow: 43, on_blue: 44, on_magenta:45,
on_cyan: 46, on_white: 47
}.freeze
STYLES = {
bold: 1,
italic: 3,
underline: 4,
blink: 5,
inverse: 7,
strikethrough: 9
}.freeze
def colorize(*effects)
codes = effects.map do |effect|
COLORS[effect] || STYLES[effect]
end.compact
return self if codes.empty?
"\e[#{codes.join(';')}m#{self}\e[0m"
end
end
# Additional mapped color method shortcts (using above implementation)
[:red, :green, :yellow, :blue, :cyan, :magenta, :gray].each do |color|
String.define_method(color) { colorize(color) }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment