
Security News
Astral Launches pyx: A Python-Native Package Registry
Astral unveils pyx, a Python-native package registry in beta, designed to speed installs, enhance security, and integrate deeply with uv.
This is a project for modifying the behavior of gems outside of your reach. You may be using a large Rails Engine and be wanting to simply decorate some existing behavior, but at the same time you want to inherit original behavior.
After a lovely and short discussion with Brian Quinn regarding these ideas, he mentioned we could try hashing methods to be able to raise warnings upon unexpected sources or targets (see his work on Deface). This project relies on another lovely meta-programming creation by John Mair, specifically his work on method_source.
Some additional background: http://stackoverflow.com/questions/4470108/when-monkey-patching-a-method-can-you-call-the-overridden-method-from-the-new-i
Add this line to your application's Gemfile:
gem 'durable_decorator', github: 'jumph4x/durable_decorator'
Or to include rake tasks for Rails you can use DurableDecoratorRails:
gem 'durable_decorator_rails', github: 'jumph4x/durable_decorator_rails'
And then execute:
$ bundle
Prior to Version 0.2.0 original methods would have a suffix of original or SHA. A recent change has been made to use prefix rather than suffix in order to be compatible with example! and example? methods. Please review your durably decorated methods when upgrading to Version 0.2.0.
Versions >= 0.2.0 are not tested on Rubies < 1.9.2. Please use version 0.1.2 if you absolutely need Ruby 1.8.7 compatibility.
class ExampleClass
def string_method
"original"
end
end
ExampleClass.class_eval do
durably_decorate :string_method do
original_string_method + " and new"
end
end
instance = ExampleClass.new
instance.string_method
# => "original and new"
Furthermore, we can hash the contents of a method as it exists at inspect-time and seal it by providing extra options to the decorator. If the method definition gets tampered with, the decorator will detect this at decoration-time and raise an error for your review.
Find the SHA of the method as currently loaded into memory, works with classes as well as modules:
DurableDecorator::Base.determine_sha('ExampleClass#instance_method')
Or for class (singleton) methods:
DurableDecorator::Base.determine_sha('ExampleClass.class_level_method')
Armed with this knowledge, we can enforce a strict mode:
DurableDecorator::Base.determine_sha('ExampleClass#no_param_method')
# => 'ba3114b2d46caa684b3f7ba38d6f74b2'
ExampleClass.class_eval do
durably_decorate :string_method, mode: 'strict', sha: 'WRONG-SHA-123456' do
original_string_method + " and new"
end
end
DurableDecorator::TamperedDefinitionError: Method SHA mismatch, the definition has been tampered with
DurableDecorator may also decorate methods with params like so:
class ExampleClass
def string_method(text)
"original #{text}"
end
end
ExampleClass.class_eval do
durably_decorate :string_method, mode: 'strict', sha: 'ba3114b2d46caa684b3f7ba38d6f74b2' do |text|
original_string_method(text) + " and new"
end
end
instance = ExampleClass.new
instance.string_method('test')
# => "original test and new"
DurableDecorator also maintains explicit versions of each method overriden by creating aliases with prepended SHAs of the form _1234abcd_some_method
so you can always target explicit method versions without relying on original_some_method
.
DurableDecorator maintains 3 versions of aliases to previous method versions, 2 of which are short-SHA versions, akin to Github:
DurableDecorator::Base.determine_sha('ExampleClass#no_param_method')
# => 'ba3114b2d46caa684b3f7ba38d6f74b2'
ExampleClass.class_eval do
durably_decorate :string_method do
"new"
end
end
# 3 explicit aliases preserve access to the original method based on it's original SHA:
# 4-char SHA, 6-char SHA and the full SHA prefix
instance = ExampleClass.new
instance._ba31_string_method
# => "original"
instance._ba3114_string_method
# => "original"
instance._ba3114b2d46caa684b3f7ba38d6f74b2_string_method
# => "original"
You can inquire about the history of method [re]definitions like this:
DurableDecorator::Base.definitions('ExampleClass#one_param_method')
# => [{:name=>:one_param_method, :sha=>"935888f04d9e132be458591d5755cb8131fec457", :body=>"def one_param_method param\n \"original: \#{param}\"\nend\n", :source=>["/home/denis/rails/durable_decorator/spec/example_class.rb", 6]}, {:name=>:one_param_method, :sha=>"3c39948e5e83c04fd4bf7a6ffab12c6828e0d959", :body=>"durably_decorate :one_param_method do |another_string|\n \"\#{one_param_method_935888f04d9e132be458591d5755cb8131fec457('check')} and \#{another_string}\"\nend\n", :source=>["/home/denis/rails/durable_decorator/spec/durable_decorator_spec.rb", 45]}]
With any luck you can even get the specific [re]definition printed!
puts DurableDecorator::Base.definitions('ExampleClass#one_param_method')[0][:body]
def one_param_method param
"original: #{param}"
end
Once you decorate the method and seal it with its SHA, if some gem tries to come in and overwrite your work BEFORE decorate-time, DurableDecorator will warn you. Similarly, expect to see an exception bubble up if the definition of the original method has changed and requires a review and a re-hash.
The usefulness is for gem consumers, and their application-level specs.
git checkout -b my-new-feature
)git commit -am 'Add some feature'
)git push origin my-new-feature
)FAQs
Unknown package
We found that durable_decorator demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Astral unveils pyx, a Python-native package registry in beta, designed to speed installs, enhance security, and integrate deeply with uv.
Security News
The Latio podcast explores how static and runtime reachability help teams prioritize exploitable vulnerabilities and streamline AppSec workflows.
Security News
The latest Opengrep releases add Apex scanning, precision rule tuning, and performance gains for open source static code analysis.