Skip to content

Instantly share code, notes, and snippets.

@jodosha
Created July 22, 2020 07:37
Show Gist options
  • Save jodosha/e3097ed693e9b7c255b658ac39c2e403 to your computer and use it in GitHub Desktop.
Save jodosha/e3097ed693e9b7c255b658ac39c2e403 to your computer and use it in GitHub Desktop.
Ruby Method Overloading
require "benchmark/ips"
require_relative "./method_overloading"
class Foo
include MethodOverloading
def call(number)
"foo #{number}"
end
end
class Bar
def call(number)
"bar #{number}"
end
end
foo = Foo.new
bar = Bar.new
Benchmark.ips do |x|
x.report("method overloading") { foo.call(23) }
x.report("method") { bar.call(23) }
x.compare!
end
__END__
Warming up --------------------------------------
method overloading 24.146k i/100ms
method 305.480k i/100ms
Calculating -------------------------------------
method overloading 225.254k (±13.5%) i/s - 1.111M in 5.053180s
method 3.274M (± 3.5%) i/s - 16.496M in 5.045562s
Comparison:
method: 3273590.9 i/s
method overloading: 225253.9 i/s - 14.53x (± 0.00) slower
require_relative "./method_overloading"
class Foo
include MethodOverloading
def call
puts "foo"
end
def call(number)
puts "foo #{number}"
end
end
foo = Foo.new
foo.call # => "foo"
foo.call(23) # => "foo 23"
module MethodOverloading
def self.included(klass)
klass.class_eval do
@__method_overloading = {}
def self.method_added(method_name)
m = instance_method(method_name)
method_id = [method_name, m.arity]
@__method_overloading[method_id] = m
undef_method method_name
end
def self.respond_to_matching?(method_name, *args)
@__method_overloading.key?([method_name, args.count])
end
def self.matched_call(instance, method_name, *args, &blk)
m = @__method_overloading[[method_name, args.count]]
m.bind_call(instance, *args)
end
end
end
def method_missing(method_name, *args, &blk)
super unless self.class.respond_to_matching?(method_name, *args, &blk)
self.class.matched_call(self, method_name, *args, &blk)
end
def respond_to_missing?(method_name, *)
self.class.respond_to_method?(method_name)
end
end
@dblock
Copy link

dblock commented Jul 25, 2020

If anyone wants to continue to improve this, https://github.com/dblock/ruby-overload

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment