URI.encode single parameter

Hello.
I was attempting to use the new URI.encode method.
I used to be able to call this:

URI.escape("some string", true)

but replacing with URI.encode("some string", true) I get this:

URI.encode("peter + paul", true)

In test2.cr:4:5

 4 | URI.encode("peter + paul", true)
         ^-----
Error: no overload matches 'URI.encode' with types String, Bool

Overloads are:
 - URI.encode(string : String, io : IO, *, space_to_plus : Bool = false)
 - URI.encode(string : String, *, space_to_plus : Bool = false)
 - URI.encode(string : String, io : IO, space_to_plus : Bool = false, &block)

but this works:

URI.encode("peter + paul", space_to_plus: true) # => "peter+%2B+paul"

Am I missing something fundamental here? Should it be callable with only two parameters? Thanks!

If you look at the overloads, the * means that any arguments after it must be named arguments; hence why your first example doesn’t work while the second does.

See https://crystal-lang.org/reference/syntax_and_semantics/default_values_named_arguments_splats_tuples_and_overloading.html#how-call-arguments-are-matched-to-method-arguments.

When these methods were refactored and renamed in #7997, space_to_plus became a named-only argument. This is intended to better express the intention at the call site: When reading URI.encode(string, true), the meaning of true argument is not obvious. Instead, the reader might wonder why such a method needs a configuration argument at all. Requiring to pass it as a named argument called space_to_plus makes its purpose clear. Since renaming the method broke the API anyway, it was a good opportunity to improve the configuration argument as well.

1 Like