Last active
May 16, 2025 18:37
-
-
Save Rhoxio/7f14d77944f0e95988d35ad19b9e9d44 to your computer and use it in GitHub Desktop.
ActiveSupport-like overrides for plain Ruby
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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