I need to handle some HTTP URLs in a Perl program, but I have doubts how should the URI
class help me.
Particularly, I'd like the to use the URI
class for resolving relative URLs and getting their components. However, the problems are:
I need a function to work with both URI
objects and URI strings as arguments (or ensure only one gets passed)
sub foo_string_or_url {
my $uri = URI->new(shift);
is that the right approach? I don't quite like it, because it stringifies the URI
and creates new object unnecessarily.
Extract the components
my $host = $uri->host;
This is also problematic, because not all URI
s have host, particularly, if someone passes garbage to the function, this will die()
.
Resolve a relative URL
my $new_url = URI::URL->new($uri, $base)->abs;
IIUC, without the ->abs
, the result will still stringify to the relative URL (and will not work for HTTP::Request
s), am I right? Also, is this guaranteed to return a URI
?
How should I handle these problems? The possibilities are
->isa('URI')
and ->can("host")
all the time
URI
class at all and parse URLs using regexes
URI
operations in try { ... } catch { ... }
Is there a sane, fool-proof way of using the URI
classes? Something simple I haven't thought of (in the list above)?
I think your question can be summarised: parameter validation is tedious, what do I do about it?
I don't like it, either. This is a matter of differing opinion among developers, other say coercions are better than sliced bread, especially when automatically done by Moose. I argue that allowing only one type of simplifies the program. Also, YAGNI applies in the vast majority of cases. Reject wrong types, employ a helper module such as Params::Validate/MooseX::Method::Signatures/MooseX::Declare in order to avoid the manual checks as shown in your code samples.
This is the desired behaviour. Exception handling mechanisms let you write custom code appropriate for each situation. If you think it's not aesthetically pleasing, remove it and mind the consequences of letting exceptions go unchecked.
use Try::Tiny;
my $host;
try {
$host = $uri->host;
} catch {
warn "Could not determine host for $uri. Message was: $_. Retry/abort/ignore?\n";
…
};
Yes and yes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With