Monkey patching (также называемый "открытие классов") — это мощная, но опасная техника в Ruby, позволяющая модифицировать или расширять существующие классы во время выполнения.
class String
def reverse_upcase
reverse.upcase
end
end
"hello".reverse_upcase # => "OLLEH"
class Array
def sum
inject(:+)
end
end
class Hash
alias_method :original_to_s, :to_s
def to_s
"{#{map { |k,v| "#{k}: #{v}" }.join(', ')}}"
end
end
# Патч для исправления проблемы в сторонней библиотеке
class SomeLibraryClass
def buggy_method
# Исправленная реализация
end
end
# В одном файле
class String
def length
size + 10
end
end
# В другом файле
"abc".length # => 13 (ожидалось 3)
# Неожиданное поведение базовых методов
1 + 1 # => 3 (если кто-то переопределил Fixnum#+)
module StringExtensions
refine String do
def reverse_upcase
reverse.upcase
end
end
end
using StringExtensions
"hello".reverse_upcase # => "OLLEH"
class UserDecorator
def initialize(user)
@user = user
end
def full_name
"#{@user.first_name} #{@user.last_name}"
end
end
module StringUtils
def reverse_upcase(str)
str.reverse.upcase
end
end
class MyClass
include StringUtils
def process(text)
reverse_upcase(text)
end
end
# Безопасное переопределение метода
class Array
alias_method :original_map, :map
def map(*args, &block)
puts "Mapping array..."
original_map(*args, &block)
end
end
Проблема: ActiveSupport добавляет blank?
ко всем объектам
Проблемы:
Решение:
# Вместо глобального патча
module CoreExtensions
module Object
module Blank
refine ::Object do
def blank?
respond_to?(:empty?) ? empty? : !self
end
end
end
end
end
using CoreExtensions::Object::Blank
Резюмируем: Monkey patching — мощный инструмент Ruby, но с большими рисками. Используйте его крайне осторожно, предпочитая refinements, декораторы и модули. Всегда оценивайте влияние на всю систему и документируйте изменения. В production-коде лучше вообще избегать "диких" патчей, кроме крайних случаев.