Skip to content

Instantly share code, notes, and snippets.

@SethHorsley
Created September 24, 2024 15:06
Show Gist options
  • Save SethHorsley/6596bd235d3d87952d52e7a774d50d7a to your computer and use it in GitHub Desktop.
Save SethHorsley/6596bd235d3d87952d52e7a774d50d7a to your computer and use it in GitHub Desktop.
function overloading
#!/usr/bin/ruby
module FunctionOverloading
def self.included(base)
base.extend(ClassMethods)
base.instance_variable_set(:@overloaded_methods, {})
end
module ClassMethods
def method_added(name)
super
return if @adding_method
method = instance_method(name)
arity = method.arity
@overloaded_methods[name] ||= {}
if @overloaded_methods[name][arity]
raise "Method '#{name}' with arity #{arity} already defined"
end
@overloaded_methods[name][arity] = method
@adding_method = true
define_method(name) do |*args|
arity = args.size
if method = self.class.instance_variable_get(:@overloaded_methods)[name][arity]
method.bind(self).call(*args)
else
raise ArgumentError, "No method '#{name}' with arity #{arity}"
end
end
@adding_method = false
end
end
end
# Usage
include FunctionOverloading
def my_method(x)
"Called with one argument: #{x}"
end
def my_method(x, y)
"Called with two arguments: #{x}, #{y}"
end
puts my_method(1) # Output: Called with one argument: 1
puts my_method(1, 2) # Output: Called with two arguments: 1, 2
# obj.my_method(1, 2, 3) # Raises ArgumentError
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment