Where is the alternative to URI.join(*strs)?

Check following Ruby code.

def self.join(*str)
  RFC3986_PARSER.join(*str)
end

Thanks.

I think it is Path.join :

https://crystal-lang.org/api/1.7.2/Path.html

1 Like

Yes, i consider it similar, thanks.

Even, there is not need use #join.

URI.join(“https://www.google.com/”, “/search”) # => Ruby
URI.parse(Path[“http://www.google.com/”, “/search”].to_s) # => Crystal

If we must use like this way, should we let the URI directly support Path as a arguments?

Using Path.join (or Path.[]) like that is most certainly a bad idea. Path does not understand URIs and could butcher the syntax.

What do you actually want to do?

I’m not sure how URI.join exactly works in Ruby, the documentation is pretty sparse. But it looks more like a variation on URI#resolve than Path.join.
So I figure the equivalent in Crystal would look more like URI.parse("http://www.google.com/").resolve("/search").

1 Like

I knew it, but i am not consider it is a alternative to URI.join(*args), because resolve only accept one argument, need invoke it more times.

e.g.

Ruby

URI.join("https://www.google.com/", "/search", "?q=crystal")

Crystal

URI.parse("https://www.google.com).resolve("/search").resolve("?q=crystal")

It not as good as Ruby usage.

Path works too, at least, it need only twice method invoke.

ic(1.7.2):017> p = Path["https://www.google.com/", "/search", "?q=crystal"]
 => Path["https://www.google.com/search/?q=crystal"]
ic(1.7.2):018> URI.parse(p.to_s)
 => #<URI:0x7fb2f586e5a0 @scheme="https", @host="www.google.com", @port=nil, @path="/search/", @query="q=crystal", @user=nil, @password=nil, @fragment=nil>

In what sense of good?

Yes, it may more or less work for this example, but as I said before, you shouldn’t trust on that. It may very well brake for other input. I’m saying “more or less” because it already alters the URI by inserting / before ? which isn’t in either of the URI-based variants.

Ouch, i miss it, it not work!

In what sense of good?

URI.parse(“https://www.google.com”).resolve(“/search”).resolve(“?q=crystal”)

Above invoke method 3 times, but follow only once.

URI.join(“https://www.google.com”, “/search”, “?q=crystal”)


We probably have to use reduce to make code more easy to refactor.

[“/search”, “?q=crystal”].reduce(URI.parse(“https://www.google.com”)) { |a, e| a.resolve(e) }

Finally, I accept this as my port_ruby_to_crystal answer.

If you consider accepting a PR, I may can try add URI.join to Crystal

Although, there still exists cases not cover, e.g. following Ruby code support one of arg is a URI.

 URI.join(URI.parse("https://www.google.com/"), "/search", "?q=crystal")

I propose add URI.parse(url : URI) method, which return itself or a copy to avoid following error in Crystal.

x = URI.parse("https://www.rfc-editor.org/rfc/rfc3986.txt")
URI.parse(x)
 10 | URI.parse(x)
                ^
Error: expected argument #1 to 'URI.parse' to be String, not URI

Overloads are:
 - URI.parse(raw_url : String)

Created a new feature request.