So I had the idea of introducing a new undefined type/value with the purpose of allowing the default values of a method to be invoked, even if a value was provided. For example:
class Example
def self.from_range(range : Range, message : String = "Not in range")
new range.begin, range.end, message
end
def initialize(@min : Int32, @max : Int32, @message : String = "Not in range"); end
end
Foo.from_range (1..10)
In order for default message property to be used when using the from_range constructor, it has to be duplicated on both definitions. WIth this proposal you would be able to something like:
class Example
def self.from_range(range : Range, message : String = undefined)
new range.begin, range.end, message
end
def initialize(@min : Int32, @max : Int32, @message : String = "Not in range"); end
end
Foo.from_range (1..10)
When not providing a message to from_range the value of the message argument is undefined; thus when the actual constructor sees undefined it knows to treat that value as if it wasnât provided at all, resulting in the message being Not in range. However if you do provide a message to from_range the argument would be the passed in message, resulting it that value being used.
Currently this is kinda possible by doing something like:
class Example
def self.from_range(range : Range, message : String? = nil)
new range.begin, range.end, message
end
def initialize(@min : Int32, @max : Int32, message : String? = nil)
@message = message || "Not in range"
end
end
Foo.from_range (1..10)
However I donât like that the message argument needs to be made nilable when in fact it technically isnât and is only nilable for this use case. Iâd be down for other solutions as well, like maybe if nil is passed as an argument that isnât nilable and has a default value, just use the default? Not a real big fan of that as it could probably lead to some bugs/surprising behavior that would have normally been caught.
Thoughts?

