Skip to content

Instantly share code, notes, and snippets.

@ags
Last active December 26, 2015 09:49
Show Gist options
  • Save ags/7132315 to your computer and use it in GitHub Desktop.
Save ags/7132315 to your computer and use it in GitHub Desktop.
module MultipleConstuctorsFromArity
def self.included(klass)
klass.extend(ClassMethods)
end
module ClassMethods
def method_added(method_name)
return unless method_name == :initialize
if const_defined?("IGNORE_INITIALIZER_DEFINITION")
remove_const("IGNORE_INITIALIZER_DEFINITION")
else
method = instance_method(method_name)
@@_arity_initializers ||= {}
@@_arity_initializers[method.arity] = method
const_set("IGNORE_INITIALIZER_DEFINITION", true)
define_method(:initialize) do |*args|
if arity_initializer = @@_arity_initializers[args.size]
arity_initializer.bind(self).call(*args)
else
raise ArgumentError, "wrong number of arguments"
end
end
end
end
end
end
class Foo
include MultipleConstuctorsFromArity
attr_reader :foo, :bar
def initialize(foo)
@foo = foo
end
def initialize(foo, bar)
initialize(foo)
@bar = bar
end
end
describe MultipleConstuctorsFromArity do
it "allows definition of multiple constructors with different arity" do
one = Foo.new("a")
expect(one.foo).to eq("a")
two = Foo.new("a", 1)
expect(two.foo).to eq("a")
expect(two.bar).to eq(1)
end
it "raises ArgumentError when no initializer takes the given number of arguments" do
expect do
Foo.new(1, 2, 3)
end.to raise_error(ArgumentError, "wrong number of arguments")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment