This document discusses monkey patching in Ruby. It defines monkey patching as modifying an existing class at runtime to modify or extend its functionality. It provides examples of monkey patching classes like Person, Hash, Array, and DateTime to add new methods. It also discusses the Axlsx and AxlsxStyler gems, where AxlsxStyler patches the Array class to add style formatting methods to simplify styling Excel spreadsheets generated with Axlsx.
9. ActiveSupport gem adds a method to merge nested hashes
require 'active_support/core_ext/hash/deep_merge'
puts h1.deep_merge(h2)
# { first_name: "Bob",
# personal_data: { age: 30, weight: 160 },
# last_name: "Smith"
# }
The new method is added by the Hash classreopening
class Hash
def deep_merge(other_hash, &block)
# some code
end
def deep_merge!(other_hash, &block)
# some code
end
end
10. Example: custom extensions - Rails
# lib/core_extensions.rb
class DateTime
def weekday?
!sunday? && !saturday?
end
end
11. The patch can be wrapped in a module
# lib/core_extensions/date_time/business_days.rb
module CoreExtensions
module DateTime
module BusinessDays
def weekday?
!sunday? && !saturday?
end
end
end
end
and the module gets mixed in
DateTime.include CoreExtensions::DateTime::BusinessDays
13. Example: scoped patching in Ruby 2+
module Starrable
refine Array do
alias_method :old_to_s, :to_s
def to_s
stars = "n" << '*' * 40 << "n"
"#{stars}#{old_to_s}#{stars}"
end
end
end
class Logger
using Starrable
def self.debug(x)
puts x.to_s
end
end
Logger.debug [4, 5, 6]
# ****************************************
# [4, 5, 6]
# ****************************************
14. and gems for Excel
spreadsheets
Axlsx AxlsxStyler
18. Axlsx allows to retrieve an array of cells with
sheet["B2:D5"]
This allows to for easy implementation of style applications,
such as
sheet["B2:D2"].add_style b: true
sheet["B2:D5"].add_border
sheet["B3:D3"].add_border [:top]
19. AxlsxStyler: a patch to the Array (for now)
module AxlsxStyler
module Array
def add_style(style)
validate_cells
each do |cell|
cell.add_style(style)
end
end
def add_border(edges = :all)
validate_cells
selected_edges(edges).each do |edge|
add_border_at(edge)
end
end
# ...
end
end