tags:

views:

112

answers:

2

I'm iterating through a list of links on a page, creating a URI object for each. When the URI object is created, I don't know whether the URL has a scheme, so when I later call $uri->host(), I will sometimes get

Can't locate object method "host" via package "URI::_generic" at -e line 1.

because the URI object is of type URI::_generic, and doesn't have a host() attribute.

I could check before object creation with regex, or I could wrap the $uri->host() call in an eval block to handle the exception, but I figure there has to be a more suave method than either of those.

+10  A: 

My suggestion: use the built in language features to your advantage before a regex.

Instead of a regex, you can do

if ($uri->can('host')) {
    say "We're good!";
}

to see if it's available. You could also check it's type:

if ($uri->isa('URI::_generic')) {
    die 'A generic type - not good!' ;
}

and verify that you have one that's good.

Robert P
I never even knew about the ->can() method for objects, thanks!
Drew Stephens
You've got an unmatched ' in your say() call.
Ether
+3  A: 

The UNIVERSAL class (perldoc UNIVERSAL) is pretty useful indeed; it contains:

  • $obj->can( METHOD ), for determining if METHOD is available on the $obj class (or you can use a bare classname rather than a blessed object - used for duck typing!

  • $obj->isa( TYPE ), for determining if $obj is type TYPE or is descended from TYPE (essentially, checks if ref($obj) is in TYPE's @ISA array) (bare classname also allowed) - used for some polymorphic implementations

  • VERSION, for getting a module's version string (boorrrrring)

Ether