Couldn't you achieve what you want by using keyword arguments:
class MyClass
attr_reader :num1, :num2, :num3
def initialize(n1: nil, n2: nil, n3: nil)
if n2.nil?
puts 'num2 is nil'
end
if n3.nil?
puts 'num3 is nil'
end
@num1 = n1 || 0
@num2 = n2 || 0
@num3 = n3 || 0
end
end
MyClass.new(n1: 1, n2: 3)
# num3 is nil
# => <MyClass:0x0... @num1=1, @num2=3, @num3=0>
MyClass.new(n1: 4, n3: 1)
# num2 is nil
# => <MyClass:0x0... @num1=4, @num2=0, @num3=1>
Keyword arguments are available since ruby 2.0. Google or see for instance here for more information regarding keyword arguments.
If you want to stay close to the MyClass() syntax, you could set it up like this:
class MyClass
attr_reader :num1, :num2, :num3
def initialize(n1 = 0, n2 = 0, n3 = 0)
@num1 = n1
@num2 = n2
@num3 = n3
end
def self.call(n1: nil, n2: nil, n3: nil)
if n2.nil?
puts 'num2 is nil'
end
if n3.nil?
puts 'num3 is nil'
end
new n1, n2, n3
end
end
MyClass.(n1: 1, n2: 3)
# num3 is nil
# => <MyClass:0x0... @num1=1, @num2=3, @num3=nil>
MyClass.(n1: 4, n3: 1)
# num2 is nil
# => <MyClass:0x0... @num1=4, @num2=nil, @num3=1>
Note the '.' after the class name.
Yet another alternative is to use def self.[](...)
instead of def self.call(...)
and make your calls use MyClass[...]
(no dot after class).