Last active
February 5, 2024 05:03
-
-
Save jaymcgavren/d0159038f7de3d353e9ac6311e7d9ae3 to your computer and use it in GitHub Desktop.
A Ruby example of prepending a proxy module to a class to intercept method calls.
This file contains 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
module MethodBroadcaster | |
def broadcast_calls_to(*method_names) | |
proxy = Module.new | |
method_names.each do |method_name| | |
proxy.define_method(method_name) do |*args, **kwargs, &block| | |
arg_strings = args.map(&:inspect) | |
kwarg_strings = kwargs.map{|k, v| "#{k}: #{v.inspect}" } | |
all_arg_strings = arg_strings + kwarg_strings | |
puts "#{method_name}(#{all_arg_strings.join(', ')})" | |
super(*args, **kwargs, &block) | |
end | |
end | |
self.prepend proxy | |
end | |
end | |
class Foo | |
extend MethodBroadcaster | |
def positional_arguments(arg1, arg2) | |
p [arg1, arg2] | |
end | |
def keyword_arguments(foo:, bar: "bar!") | |
p [foo, bar] | |
end | |
def positional_and_keyword_arguments(arg1, arg2, foo:, bar: "bar!") | |
p [arg1, arg2, foo, bar] | |
puts yield("block arg") if block_given? | |
end | |
broadcast_calls_to :positional_arguments, :keyword_arguments, :positional_and_keyword_arguments | |
end | |
foo = Foo.new | |
foo.positional_arguments("arg1!", "arg2!") | |
# => positional_arguments("arg1!", "arg2!") | |
# => ["arg1!", "arg2!"] | |
foo.keyword_arguments(foo: "foo!") | |
# => keyword_arguments(foo: "foo!") | |
# => ["foo!", "bar!"] | |
foo.positional_and_keyword_arguments("arg1!", "arg2!", foo: "foo!", bar: "bar!!") | |
# => positional_and_keyword_arguments("arg1!", "arg2!", foo: "foo!", bar: "bar!!") | |
# => ["arg1!", "arg2!", "foo!", "bar!!"] | |
foo.positional_and_keyword_arguments("arg1!", "arg2!", foo: "foo!") { |block_arg| "block got #{block_arg}!" } | |
# => positional_and_keyword_arguments("arg1!", "arg2!", foo: "foo!") | |
# => ["arg1!", "arg2!", "foo!", "bar!"] | |
# => block got block arg! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment