File Coverage

blib/lib/Attean/API/Term.pm
Criterion Covered Total %
statement 218 326 66.8
branch 62 164 37.8
condition 11 33 33.3
subroutine 51 55 92.7
pod 7 21 33.3
total 349 599 58.2


line stmt bran cond sub pod time code
1 50     50   561 use v5.14;
  50         150  
2 50     50   226 use warnings;
  50         85  
  50         2105  
3              
4             =head1 NAME
5              
6             Attean::API::Term - RDF Terms
7              
8             =head1 VERSION
9              
10             This document describes Attean::API::Term version 0.032
11              
12             =head1 DESCRIPTION
13              
14             The Attean::API::Term role defines a common API for all RDF terms.
15              
16             =head1 REQUIRED METHODS
17              
18             The following methods are required by the L<Attean::API::Term> role:
19              
20             =over 4
21              
22             =item C<< value >>
23              
24             Returns the term's value string.
25              
26             =item C<< ntriples_string >>
27              
28             Returns an N-Triples-compatible string serialization.
29              
30             =back
31              
32             =head1 METHODS
33              
34             This role provides default implementations of the following methods:
35              
36             =over 4
37              
38             =item C<< as_string >>
39              
40             Returns a string serialization of the term.
41              
42             =cut
43              
44             use Moo::Role;
45 50     50   254
  50         102  
  50         321  
46             with 'Attean::API::TermOrVariable', 'Attean::API::ResultOrTerm';
47             with 'Attean::API::TermOrVariableOrTriplePattern';
48            
49             requires 'value'; # => (is => 'ro', isa => 'Str', required => 1);
50             requires 'ntriples_string';
51             shift->ntriples_string();
52             }
53 927     927 1 17198  
54             =item C<< ebv >>
55              
56             Returns true if the term has a true SPARQL "effective boolean value", false otherwise.
57              
58             =cut
59              
60             requires 'ebv';
61             requires 'compare';
62            
63             my $self = shift;
64             my $value = $self->value;
65             if ($value =~ m/^[\x20\x23-\x5a\x5d-\x7e]*$/o) {
66 491     491   685 return $value;
67 491         1027 }
68 491 100       1559
69 490         6762 my @chars = split(//, $value);
70             my $string = '';
71             while (scalar(@chars)) {
72 1         7 my $c = shift(@chars);
73 1         2 my $o = ord($c);
74 1         3 if ($o < 0x8) {
75 20         19 $string .= sprintf("\\u%04X", $o);
76 20         20 } elsif ($o == 0x9) {
77 20 50       63 $string .= "\\t";
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
78 0         0 } elsif ($o == 0xA) {
79             $string .= "\\n";
80 0         0 } elsif ($o < 0xC) {
81             $string .= sprintf("\\u%04X", $o);
82 0         0 } elsif ($o == 0xD) {
83             $string .= "\\r";
84 0         0 } elsif ($o < 0x1F) {
85             $string .= sprintf("\\u%04X", $o);
86 0         0 } elsif ($o < 0x21) {
87             $string .= $c;
88 0         0 } elsif ($o == 0x22) {
89             $string .= "\"";
90 0         0 } elsif ($o < 0x5B) {
91             $string .= $c;
92 0         0 } elsif ($o == 0x5C) {
93             $string .= "\\";
94 5         7 } elsif ($o < 0x7E) {
95             $string .= $c;
96 0         0 } elsif ($o < 0xFFFF) {
97             $string .= sprintf("\\u%04X", $o);
98 14         18 } else {
99             $string .= sprintf("\\U%08X", $o);
100 1         5 }
101             }
102 0         0 return $string;
103             }
104              
105 1         17 with 'Attean::API::TermOrTriple';
106             }
107              
108             use IRI;
109             use Scalar::Util qw(blessed);
110             use Types::Standard qw(Maybe Str ConsumerOf);
111             use AtteanX::SPARQL::Constants;
112 50     50   56424 use AtteanX::SPARQL::Token;
  50         2456330  
  50         8553  
113 50     50   511 use Attean::API::Query;
  50         98  
  50         2881  
114 50     50   285  
  50         100  
  50         450  
115 50     50   36314 use Moo::Role;
  50         97  
  50         7039  
116 50     50   292
  50         93  
  50         883  
117 50     50   22422 with 'Attean::API::Term';
  50         205  
  50         2085  
118             with 'Attean::API::SPARQLSerializable';
119 50     50   395 with 'Attean::API::TermOrVariableOrTriplePattern';
  50         88  
  50         185  
120            
121             requires 'language'; # => (is => 'ro', isa => 'Maybe[Str]', predicate => 'has_language');
122             requires 'datatype'; # => (is => 'ro', isa => 'Attean::API::IRI', required => 1, coerce => 1, default => sub { IRI->new(value => 'http://www.w3.org/2001/XMLSchema#string') });
123            
124             around 'BUILDARGS' => sub {
125             my $orig = shift;
126             my $class = shift;
127             my $args = $class->$orig(@_);
128       443 0   if (my $lang = $args->{language}) {
129             my $oldlang = $lang;
130             # http://tools.ietf.org/html/bcp47#section-2.1.1
131             # All subtags use lowercase letters
132             $lang = lc($lang);
133              
134             # with 2 exceptions: subtags that neither appear at the start of the tag nor occur after singletons
135             # i.e. there's a subtag of length at least 2 preceding the exception; and a following subtag or end-of-tag
136              
137             # 1. two-letter subtags are all uppercase
138             $lang =~ s{(?<=\w\w-)(\w\w)(?=($|-))}{\U$1}g;
139              
140             # 2. four-letter subtags are titlecase
141             $lang =~ s{(?<=\w\w-)(\w\w\w\w)(?=($|-))}{\u\L$1}g;
142             $args->{language} = $lang;
143             }
144             return $args;
145             };
146             around 'BUILD' => sub {
147             my $orig = shift;
148             my $self = shift;
149             $self->$orig(@_);
150             if (my $dt = $self->datatype) {
151             my $type = $dt->value;
152             if ($type =~ qr<^http://www[.]w3[.]org/2001/XMLSchema#(?:integer|decimal|float|double|non(?:Positive|Negative)Integer|(?:positive|negative)Integer|long|int|short|byte|unsigned(?:Long|Int|Short|Byte))$>) {
153             Moo::Role->apply_roles_to_object($self, 'Attean::API::NumericLiteral');
154             } elsif ($type eq 'http://www.w3.org/2001/XMLSchema#boolean') {
155             Moo::Role->apply_roles_to_object($self, 'Attean::API::BooleanLiteral');
156             } elsif ($type eq 'http://www.w3.org/2001/XMLSchema#dateTime') {
157             Moo::Role->apply_roles_to_object($self, 'Attean::API::DateTimeLiteral');
158             }
159             }
160             };
161            
162             my $self = shift;
163             my @tokens;
164            
165             my $dt = $self->datatype;
166             if ($self->does('Attean::API::NumericLiteral') and $dt->value eq 'http://www.w3.org/2001/XMLSchema#integer') {
167             if ($self->value =~ /^\d+$/) {
168 86     86 0 2666 my $t = AtteanX::SPARQL::Token->fast_constructor( INTEGER, -1, -1, -1, -1, [$self->value] );
169 86         100 return Attean::ListIterator->new( values => [$t], item_type => 'AtteanX::SPARQL::Token' );
170             }
171 86         1511 }
172 86 100 66     1511
173 16 50       360 my $t = AtteanX::SPARQL::Token->fast_constructor( STRING1D, -1, -1, -1, -1, [$self->value] );
174 16         76 push(@tokens, $t);
175 16         925 if (my $lang = $self->language) {
176             my $l = AtteanX::SPARQL::Token->fast_constructor( LANG, -1, -1, -1, -1, ["$lang"] );
177             push(@tokens, $l);
178             } else {
179 70         1609 if ($dt->value ne 'http://www.w3.org/2001/XMLSchema#string') {
180 70         3046 push(@tokens, AtteanX::SPARQL::Token->hathat);
181 70 100       269 push(@tokens, $dt->sparql_tokens->elements);
182 6         27 }
183 6         229 }
184             return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
185 64 100       240 }
186 2         8
187 2         80 my $self = shift;
188             my $value = $self->value;
189             my $dt = $self->datatype->value;
190 70         1164 if ($dt eq 'http://www.w3.org/2001/XMLSchema#boolean') {
191             return ($value eq 'true' or $value eq '1');
192             } else {
193             return (length($value) > 0);
194 28     28 1 51 }
195 28         87 }
196 28         540
197 28 100       76 my ($a, $b) = @_;
198 26   66     234 return 1 unless blessed($b);
199             return 1 unless ($b->does('Attean::API::Literal') or $b->does('Attean::API::Binding'));
200 2         8 return -1 if ($b->does('Attean::API::Binding'));
201             my $c = ((($a->language // '') cmp ($b->language // '')) || ($a->datatype->value cmp $b->datatype->value) || ($a->value cmp $b->value));
202             return $c;
203             }
204            
205 1     1 1 5 if ($ENV{ATTEAN_TYPECHECK}) {
206 1 50       5 my %map = (
207 1 50 33     4 language => Maybe[Str],
208 1 50       19 datatype => ConsumerOf['Attean::API::IRI'],
209 1   33     39 );
210 1         3 foreach my $method (keys %map) {
211             my $type = $map{$method};
212             around $method => sub {
213             my $orig = shift;
214             my $self = shift;
215             my $class = ref($self);
216             my $value = $self->$orig(@_);
217             my $err = $type->validate($value);
218             if ($err) {
219             my $name = $type->display_name;
220             die "${class}'s $method failed conformance check for $name: $value";
221             }
222             return $value;
223             };
224             }
225             }
226            
227             my $self = shift;
228             my %args;
229             $args{language} = $self->language if ($self->language);
230             $args{datatype} = $self->datatype if ($self->datatype);
231             return %args;
232             }
233            
234             my $self = shift;
235             my @terms = @_;
236 0     0 0 0
237 0         0 if (my $l = $self->language) {
238 0 0       0 foreach my $t (@terms) {
239 0 0       0 return 0 unless ($t->does('Attean::API::Literal'));
240 0         0 if ($t->language) {
241             return 0 unless (defined($t->language));
242             return 0 unless ($t->language eq $l);
243             } else {
244 0     0 0 0 return 0 unless ($t->datatype->value eq 'http://www.w3.org/2001/XMLSchema#string');
245 0         0 }
246             }
247 0 0       0 return 1;
    0          
248 0         0 } elsif ($self->datatype->value eq 'http://www.w3.org/2001/XMLSchema#string') {
249 0 0       0 foreach my $t (@terms) {
250 0 0       0 return 0 unless ($t->does('Attean::API::Literal'));
251 0 0       0 return 0 if ($t->language);
252 0 0       0 return 0 unless (blessed($t->datatype));
253             return 0 unless ($t->datatype->value eq 'http://www.w3.org/2001/XMLSchema#string');
254 0 0       0 }
255             return 1;
256             }
257 0         0
258             return 0;
259 0         0 }
260 0 0       0
261 0 0       0 my $self = shift;
262 0 0       0 my $str = sprintf('"%s"', $self->__ntriples_string);
263 0 0       0 if (my $l = $self->language) {
264             return join('@', $str, $l);
265 0         0 } else {
266             my $dt = $self->datatype;
267             if ($dt->value eq 'http://www.w3.org/2001/XMLSchema#string') {
268 0         0 return $str;
269             } else {
270             return join('^^', $str, $dt->ntriples_string);
271             }
272 64     64   1524 }
273 64         235 }
274 64 50       283  
275 0         0 around as_sparql => sub {
276             my $orig = shift;
277 64         1152 my $self = shift;
278 64 50       258 my $s = $self->$orig(@_);
279 0         0
280             if ($s =~ m[^"(true|false)"\^\^<http://www[.]w3[.]org/2001/XMLSchema#boolean>$]) {
281 64         945 return $1;
282             }
283            
284             return $s;
285             };
286             }
287              
288             use DateTime::Format::W3CDTF;
289              
290             use Moo::Role;
291              
292             my $self = shift;
293             my $w3c = DateTime::Format::W3CDTF->new;
294             return $w3c->parse_datetime( $self->value );
295             }
296             }
297              
298             use Moo::Role;
299             requires 'canonicalized_term';
300 50     50   108766 }
  50         20849485  
  50         1851  
301              
302 50     50   514 use Scalar::Util qw(blessed looks_like_number);
  50         106  
  50         480  
303              
304             use Moo::Role;
305 0     0 0 0  
306 0         0 my $self = shift;
307 0         0 my $value = $self->value;
308             if ($value =~ m/^(true|false|0|1)$/) {
309             return ($value eq 'true' or $value eq '1')
310             ? Attean::Literal->true
311             : Attean::Literal->false;
312 50     50   23539 } else {
  50         109  
  50         209  
313             die "Bad lexical form for xsd:boolean: '$value'";
314             }
315             }
316             with 'Attean::API::Literal', 'Attean::API::CanonicalizingLiteral';
317 50     50   16673 }
  50         117  
  50         3051  
318              
319 50     50   308 use Scalar::Util qw(blessed looks_like_number);
  50         124  
  50         217  
320              
321             use Moo::Role;
322 0     0 0 0  
323 0         0 my ($a, $b) = @_;
324 0 0       0 return 1 unless blessed($b);
325 0 0 0     0 return 1 unless ($b->does('Attean::API::Literal') or $b->does('Attean::API::Binding'));
326             return -1 if ($b->does('Attean::API::Binding'));
327             if ($b->does('Attean::API::NumericLiteral')) {
328             return $a->numeric_value <=> $b->numeric_value;
329 0         0 } else {
330             return 1;
331             # Attean::API::Literal::compare($a, $b);
332             }
333             }
334            
335             my $self = shift;
336 50     50   24692 my $value = $self->value;
  50         111  
  50         2288  
337             my $type = $self->datatype->value;
338 50     50   310 $type =~ s/^.*#//;
  50         113  
  50         274  
339             if ($type eq 'integer') {
340             if ($value =~ m/^([-+])?(\d+)$/) {
341 1     1 0 732 my $sign = $1 || '';
342 1 50       6 my $num = $2;
343 1 50 33     4 $sign = '' if ($sign eq '+');
344 1 50       16 $num =~ s/^0+(\d)/$1/;
345 1 50       19 return Attean::Literal->integer("${sign}${num}");
346 1         11 } else {
347             die "Bad lexical form for xsd:integer: '$value'";
348 0         0 }
349             } elsif ($type eq 'negativeInteger') {
350             if ($value =~ m/^-(\d+)$/) {
351             my $num = $1;
352             $num =~ s/^0+(\d)/$1/;
353             return Attean::Literal->new(value => "-${num}", datatype => 'http://www.w3.org/2001/XMLSchema#negativeInteger');
354 5     5 0 78 } else {
355 5         16 die "Bad lexical form for xsd:integer: '$value'";
356 5         95 }
357 5         19 } elsif ($type eq 'decimal') {
358 5 100       18 if ($value =~ m/^([-+])?((\d+)([.]\d*)?)$/) {
    50          
    50          
    0          
    0          
    0          
359 1 50       3 my $sign = $1 || '';
360 1   50     5 my $num = $2;
361 1         2 my $int = $3;
362 1 50       4 my $frac = $4;
363 1         2 $sign = '' if ($sign eq '+');
364 1         3 $num =~ s/^0+(.)/$1/;
365             $num =~ s/[.](\d+)0+$/.$1/;
366 0         0 if ($num =~ /^[.]/) {
367             $num = "0$num";
368             }
369 0 0       0 if ($num !~ /[.]/) {
370 0         0 $num = "${num}.0";
371 0         0 }
372 0         0 return Attean::Literal->decimal("${sign}${num}");
373             } elsif ($value =~ m/^([-+])?([.]\d+)$/) {
374 0         0 my $sign = $1 || '';
375             my $num = $2;
376             $sign = '' if ($sign eq '+');
377 4 50       28 $num =~ s/^0+(.)/$1/;
    0          
378 4   50     18 return Attean::Literal->decimal("${sign}${num}");
379 4         7 } else {
380 4         8 die "Bad lexical form for xsd:deciaml: '$value'";
381 4         7 }
382 4 50       7 } elsif ($type eq 'float') {
383 4         9 if ($value =~ m/^(?:([-+])?(?:(\d+(?:\.\d*)?|\.\d+)([Ee][-+]?\d+)?|(INF)))|(NaN)$/) {
384 4         7 my $sign = $1;
385 4 50       9 my $inf = $4;
386 0         0 my $nan = $5;
387             no warnings 'uninitialized';
388 4 50       10 $sign = '' if ($sign eq '+');
389 4         6 return Attean::Literal->float("${sign}$inf") if ($inf);
390             return Attean::Literal->float($nan) if ($nan);
391 4         18  
392             $value = sprintf('%E', $value);
393 0   0     0 $value =~ m/^(?:([-+])?(?:(\d+(?:\.\d*)?|\.\d+)([Ee][-+]?\d+)?|(INF)))|(NaN)$/;
394 0         0 $sign = $1;
395 0 0       0 $inf = $4;
396 0         0 $nan = $5;
397 0         0 my $num = $2;
398             my $exp = $3;
399 0         0 $num =~ s/[.](\d+?)0+/.$1/;
400             $exp =~ tr/e/E/;
401             $exp =~ s/E[+]/E/;
402 0 0       0 $exp =~ s/E(-?)0+([1-9])$/E$1$2/;
403 0         0 $exp =~ s/E(-?)0+$/E${1}0/;
404 0         0 return Attean::Literal->float("${sign}${num}${exp}");
405 0         0 } else {
406 50     50   50034 die "Bad lexical form for xsd:float: '$value'";
  50         113  
  50         20986  
407 0 0       0 }
408 0 0       0 } elsif ($type eq 'boolean') {
409 0 0       0 if ($value =~ m/^(true|false|0|1)$/) {
410             return ($value eq 'true' or $value eq '1')
411 0         0 ? Attean::Literal->true
412 0         0 : Attean::Literal->false;
413 0         0 } else {
414 0         0 die "Bad lexical form for xsd:boolean: '$value'";
415 0         0 }
416 0         0 } elsif ($type eq 'double') {
417 0         0 if ($value =~ m/^(?:([-+])?(?:(\d+(?:\.\d*)?|\.\d+)([Ee][-+]?\d+)?|(INF)))|(NaN)$/) {
418 0         0 my $sign = $1;
419 0         0 my $inf = $4;
420 0         0 my $nan = $5;
421 0         0 no warnings 'uninitialized';
422 0         0 $sign = '' if ($sign eq '+');
423 0         0 return Attean::Literal->double("${sign}$inf") if ($inf);
424             return Attean::Literal->double($nan) if ($nan);
425 0         0  
426             $value = sprintf('%E', $value);
427             $value =~ m/^(?:([-+])?(?:(\d+(?:\.\d*)?|\.\d+)([Ee][-+]?\d+)?|(INF)))|(NaN)$/;
428 0 0       0 $sign = $1;
429 0 0 0     0 $inf = $4;
430             $nan = $5;
431             my $num = $2;
432             my $exp = $3;
433 0         0 $num =~ s/[.](\d+?)0+/.$1/;
434             $exp =~ tr/e/E/;
435             $exp =~ s/E[+]/E/;
436 0 0       0 $exp =~ s/E(-?)0+([1-9])$/E$1$2/;
437 0         0 $exp =~ s/E(-?)0+$/E${1}0/;
438 0         0 return Attean::Literal->double("${sign}${num}${exp}");
439 0         0 } else {
440 50     50   375 die "Bad lexical form for xsd:double: '$value'";
  50         108  
  50         42991  
441 0 0       0 }
442 0 0       0 } else {
443 0 0       0 warn "No canonicalization for type $type";
444             }
445 0         0 return $self;
446 0         0 }
447 0         0
448 0         0 my $self = shift;
449 0         0 my $type = $self->datatype->value;
450 0         0 return scalar($type =~ qr<^http://www[.]w3[.]org/2001/XMLSchema#(?:integer|non(?:Positive|Negative)Integer|(?:positive|negative)Integer|long|int|short|byte|unsigned(?:Long|Int|Short|Byte))$>);
451 0         0 }
452 0         0
453 0         0 my $self = shift;
454 0         0 return ($self->numeric_value != 0);
455 0         0 }
456 0         0  
457 0         0 my $self = shift;
458             my $v = $self->value;
459 0         0 return (looks_like_number($v)) ? eval $v : undef;
460             }
461              
462 0         0 {
463             my %type_hierarchy = (
464 0         0 'integer' => 'decimal',
465             'nonPositiveInteger' => 'integer',
466             'negativeInteger' => 'nonPositiveInteger',
467             'long' => 'integer',
468 28     28 0 40 'int' => 'long',
469 28         440 'short' => 'int',
470 28         220 'byte' => 'short',
471             'nonNegativeInteger' => 'integer',
472             'unsignedLong' => 'nonNegativeInteger',
473             'unsignedInt' => 'unsignedLong',
474 6     6 0 2052 'unsignedShort' => 'unsignedInt',
475 6         17 'unsignedByte' => 'unsignedShort',
476             'positiveInteger' => 'nonNegativeInteger',
477             );
478             my ($lhs, $rhs) = @_;
479 46     46 0 2233 for ($lhs, $rhs) {
480 46         100 s/^.*#//;
481 46 50       1684 }
482             return "http://www.w3.org/2001/XMLSchema#$lhs" if ($lhs eq $rhs);
483             my $cur = $lhs;
484             my %ancestors = ($cur => 1);
485             while ($cur = $type_hierarchy{$cur}) {
486             $ancestors{$cur}++;
487             return "http://www.w3.org/2001/XMLSchema#$cur" if ($cur eq $rhs);
488             }
489             $cur = $rhs;
490             while ($cur = $type_hierarchy{$cur}) {
491             return "http://www.w3.org/2001/XMLSchema#$cur" if exists $ancestors{$cur};
492             }
493             return;
494             }
495             my $self = shift;
496             my $rhs = shift;
497             my $op = shift;
498            
499             if ($op =~ m<^[-+*]$>) {
500             # return common numeric type
501 7     7   25 if (my $type = _lca($self->datatype->value, $rhs->datatype->value)) {
502 7         10 return $type;
503 14         49 }
504             return 'http://www.w3.org/2001/XMLSchema#double';
505 7 100       25 } elsif ($op eq '/') {
506 3         4 if ($self->is_integer_type and $rhs->is_integer_type) {
507 3         7 # return xsd:decimal if both operands are integers
508 3         6 return 'http://www.w3.org/2001/XMLSchema#decimal';
509 5         7 }
510 5 50       11 if (my $type = _lca($self->datatype->value, $rhs->datatype->value)) {
511             return $type;
512 3         5 }
513 3         5 return 'http://www.w3.org/2001/XMLSchema#double';
514 6 100       23 }
515             die "Unexpected numeric operation in binary_promotion_type: $op";
516 1         3 }
517             }
518             with 'Attean::API::Literal', 'Attean::API::CanonicalizingLiteral';
519 21     21 0 381 }
520 21         26  
521 21         25 use Scalar::Util qw(blessed);
522             use AtteanX::SPARQL::Constants;
523 21 100       80 use AtteanX::SPARQL::Token;
    50          
524             use Attean::API::Query;
525 7 100       115  
526 6         59 use Moo::Role;
527            
528 1         6 with 'Attean::API::Term', 'Attean::API::BlankOrIRI', 'Attean::API::BlankOrIRIOrTriple';
529             ;
530 14 50 33     44 with 'Attean::API::SPARQLSerializable';
531            
532 14         200 my $self = shift;
533             my $t = AtteanX::SPARQL::Token->fast_constructor( BNODE, -1, -1, -1, -1, [$self->value] );
534 0 0       0 return Attean::ListIterator->new( values => [$t], item_type => 'AtteanX::SPARQL::Token' );
535 0         0 }
536            
537 0         0 my ($a, $b) = @_;
538             return 1 unless blessed($b);
539 0         0 return -1 unless ($b->does('Attean::API::Blank'));
540             return ($a->value cmp $b->value);
541             }
542             }
543              
544             use IRI;
545             use Scalar::Util qw(blessed);
546 50     50   415 use AtteanX::SPARQL::Constants;
  50         125  
  50         2524  
547 50     50   335 use AtteanX::SPARQL::Token;
  50         110  
  50         8334  
548 50     50   401 use Attean::API::Query;
  50         135  
  50         1781  
549 50     50   295  
  50         130  
  50         1312  
550             use Moo::Role;
551 50     50   275
  50         119  
  50         242  
552             with 'Attean::API::Term', 'Attean::API::BlankOrIRI', 'Attean::API::BlankOrIRIOrTriple';
553 1     1 1 41 with 'Attean::API::SPARQLSerializable';
554            
555             my $self = shift;
556             my @tokens;
557             if ($self->value eq '') {
558             push(@tokens, AtteanX::Parser::Turtle::Token->a);
559 13     13 0 19 } else {
560 13         83 push(@tokens, AtteanX::SPARQL::Token->fast_constructor( IRI, -1, -1, -1, -1, [$self->value] ));
561 13         797 }
562             return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
563             }
564            
565 3     3 1 44 my ($a, $b) = @_;
566 3 50       24 return 1 unless blessed($b);
567 3 50       9 return -1 if ($b->does('Attean::API::Literal') or $b->does('Attean::API::Binding'));
568 3         51 return 1 unless ($b->does('Attean::API::IRI'));
569             return ($a->value cmp $b->value);
570             }
571            
572             my $self = shift;
573 50     50   25835 return sprintf('<%s>', $self->__ntriples_string);
  50         97  
  50         1480  
574 50     50   271 }
  50         122  
  50         2211  
575 50     50   314  
  50         91  
  50         6705  
576 50     50   309 around as_sparql => sub {
  50         129  
  50         1073  
577 50     50   300 my $orig = shift;
  50         102  
  50         1119  
578             my $self = shift;
579 50     50   234
  50         91  
  50         203  
580             if ($self->value eq 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type') {
581 1     1 1 112 return 'a';
582             }
583              
584             return $self->$orig(@_);
585             };
586 244     244 0 424 }
587 244         370  
588 244 50       928 1;
589 0         0  
590              
591 244         1195 =back
592              
593 244         14958 =head1 BUGS
594              
595             Please report any bugs or feature requests to through the GitHub web interface
596             at L<https://github.com/kasei/attean/issues>.
597 13     13 1 19  
598 13 50       34 =head1 SEE ALSO
599 13 50 33     28  
600 13 50       539  
601 13         167  
602             =head1 AUTHOR
603              
604             Gregory Todd Williams C<< <gwilliams@cpan.org> >>
605 427     427   4734  
606 427         871 =head1 COPYRIGHT
607              
608             Copyright (c) 2014--2022 Gregory Todd Williams.
609             This program is free software; you can redistribute it and/or modify it under
610             the same terms as Perl itself.
611              
612             =cut