package Data::HAL::URI; use strictures; use Moo; # has use Types::Standard qw(InstanceOf Str); use URI qw(); our $VERSION = '1.000'; my %uri_require_attempted = (); my %uri_implements = (); BEGIN { ## no critic (TestingAndDebugging::ProhibitNoWarnings) no warnings 'redefine'; *URI::implementor = sub { my($scheme, $impclass) = @_; if (!$scheme || $scheme !~ /\A$URI::scheme_re\z/o) { require URI::_generic; return "URI::_generic"; } $scheme = lc($scheme); if ($impclass) { # Set the implementor class for a given scheme my $old = $uri_implements{$scheme}; $impclass->_init_implementor($scheme); $uri_implements{$scheme} = $impclass; return $old; } my $ic = $uri_implements{$scheme}; return $ic if $ic; # scheme not yet known, look for internal or # preloaded (with 'use') implementation $ic = "URI::$scheme"; # default location # turn scheme into a valid perl identifier by a simple transformation... $ic =~ s/\+/_P/g; $ic =~ s/\./_O/g; $ic =~ s/\-/_/g; ## no critic (TestingAndDebugging::ProhibitNoStrict,TestingAndDebugging::ProhibitProlongedStrictureOverride) no strict 'refs'; # check we actually have one for the scheme: unless (@{"${ic}::ISA"}) { if (not exists $uri_require_attempted{$ic}) { # Try to load it my $_old_error = $@; ## no critic (BuiltinFunctions::ProhibitStringyEval) eval "require $ic"; ## no critic (Variables::RequireLocalizedPunctuationVars) die $@ if $@ && $@ !~ /Can\'t locate.*in \@INC/; $@ = $_old_error; $uri_require_attempted{$ic} = 1; } ## no critic (Subroutines::ProhibitExplicitReturnUndef) return undef unless @{"${ic}::ISA"}; } $ic->_init_implementor($scheme); $uri_implements{$scheme} = $ic; $ic; }; } has('_original', is => 'rw', isa => Str); # just records what was passed to the constructor, this is a work-around for # URI->new being a lossy operation has( 'uri', is => 'ro', isa => InstanceOf['URI'], default => sub { my ($self) = @_; return URI->new($self->_original); }, handles => [qw(abs as_iri canonical clone eq fragment implementor new_abs opaque path rel scheme secure STORABLE_freeze STORABLE_thaw)], lazy => 1, # MT#5615 setting required=>1 breaks on Debian Squeeze required => 0, ); sub BUILDARGS { my (undef, @arg) = @_; return 1 == @arg ? {_original => $arg[0]} : {@arg}; } sub as_string { my ($self, $root) = @_; if ( $self->eq($self->_original) || $root && $root->_nsmap && $self->uri->eq($root->_nsmap->uri($self->_original)->as_string) ) { return $self->_original; } else { return $self->uri->as_string; } } 1; __END__ =encoding UTF-8 =head1 NAME Data::HAL::URI - URI wrapper =head1 VERSION This document describes Data::HAL::URI version 1.000 =head1 SYNOPSIS my $relation = $resource->relation->as_string; =head1 DESCRIPTION This is a wrapper for L objects. =head1 INTERFACE =head2 Composition None, but L methods are delegated through the L attribute. =head2 Constructors =head3 C my $u = Data::HAL::URI->new('http://example.com/something'); Takes a string argument, returns a C object. =head2 Attributes =head3 C Type C, B, B, can only be set from the L constructor. This attribute delegates all methods to L except L. =head2 Methods =head3 C Returns the original argument to the constructor if still equal to the L, where equality also takes CURIE expansion into account, or otherwise the L as string. The unaltered behaviour is still available through the L accessor, e.g.: $resource->relation->uri->as_string =head2 Exports None. =head1 DIAGNOSTICS None. =head1 CONFIGURATION AND ENVIRONMENT Requires no configuration files or environment variables. =head1 AUTHOR Lars Dɪᴇᴄᴋᴏᴡ C<< >> =head1 LICENSE Copyright © 2013 Lars Dɪᴇᴄᴋᴏᴡ C<< >> This library is free software; you can redistribute it and/or modify it under the same terms as Perl 5.18.0.