About method overloading(Error: missing argument)

Hello, everyone! I got below error when use overloading:

$ cat demo.cr 
class A
    def self.x(b : String)
      puts("x1=#{b}")
    end
    def self.x(c : String)
      puts("x2=#{c}")
    end
end
A.x(b: "b")
A.x(c: "c")

$ crystal build demo.cr 
Showing last frame. Use --error-trace for full trace.

In demo.cr:10:3

 10 | A.x(b: "b")
        ^
Error: missing argument: c

Overloads are:
 - A.x(c : String)

And my expection output is:

x1=b
x2=c

I had seen Overloading - Crystal, and search in forum by keyword overload, but still not understand the above error ~

Thanks~
Si

By default, Crystal looks at method signatures purely as positional arguments, so if you write two methods that take a String, the second doesn’t overload the first, it overwrites it. This confused me, too, but it makes sense from a certain perspective — if you pass positional arguments to the method, which one gets called?

If you want to be able to distinguish method signatures using keyword arguments, you have to force them to be keyword arguments. You can separate positional arguments from keyword arguments in a method signature with a * in the arg list. If you don’t want positional arguments at all (as is the case here), you can use * in the first argument spot:

class A
  def self.x(*, b : String)
    puts("x1=#{b}")
  end

  def self.x(*, c : String)
    puts("x2=#{c}")
  end
end
2 Likes

It works! Thanks~

1 Like