package Data::DPath::Filters; our $AUTHORITY = 'cpan:SCHWIGON'; # ABSTRACT: Magic functions available inside filter conditions $Data::DPath::Filters::VERSION = '0.58'; use strict; use warnings; use Data::Dumper; use Scalar::Util; use constant { HASH => 'HASH', ARRAY => 'ARRAY', SCALAR => 'SCALAR', }; our $idx; our $p; # current point sub affe { return $_ eq 'affe' ? 1 : 0; } sub idx { $idx } sub size() { no warnings 'uninitialized'; return -1 unless defined $_; # speed optimization: first try faster ref, then reftype # ref return scalar @$_ if ref $_ eq ARRAY; return scalar keys %$_ if ref $_ eq HASH; return 1 if ref \$_ eq SCALAR; # reftype return scalar @$_ if Scalar::Util::reftype $_ eq ARRAY; return scalar keys %$_ if Scalar::Util::reftype $_ eq HASH; return 1 if Scalar::Util::reftype \$_ eq SCALAR; # else return -1; } sub key() { no warnings 'uninitialized'; my $attrs = defined $p->attrs ? $p->attrs : {}; return $attrs->{key}; } sub value() { no warnings 'uninitialized'; return $_; } sub isa($) { my ($classname) = @_; no warnings 'uninitialized'; #print STDERR "*** value ", Dumper($_ ? $_ : "UNDEF"); return $_->isa($classname) if Scalar::Util::blessed $_; return undef; } sub reftype() { return Scalar::Util::reftype($_); } sub is_reftype($) { no warnings 'uninitialized'; return (Scalar::Util::reftype($_) eq shift); } 1; =pod =encoding UTF-8 =head1 NAME Data::DPath::Filters - Magic functions available inside filter conditions =head1 API METHODS =head2 affe Mysterious test function. Will vanish. Soon. Or will it really? No, probably not. I like it. :-) Returns true if the value eq "affe". =head2 idx Returns the current index inside array elements. Please note that the current matching elements might not be in a defined order if resulting from anything else than arrays. =head2 size Returns the size of the current element. If it is an array ref it returns the number of elements, if it is a hash ref it returns number of keys, if it is a scalar it returns 1, everything else returns -1. =head2 key If it is a hashref returns the key under which the current element is associated as value. Else it returns undef. This gives the key() function kind of a "look back" behaviour because the associated point is already after that key. =head2 value Returns the value of the current element. =head2 isa Frontend to UNIVERSAL::isa. True if the current element is_a given class. =head2 reftype Frontend to Scalar::Util::reftype. Returns Scalar::Util::reftype of current element $_. With this you can do comparison by yourself with C, C<=~>, C<~~> or whatever in filter expressions. =head2 is_reftype($EXPECTED_TYPE) Frontend to Scalar::Util::reftype. Checks whether Scalar::Util::reftype of current element $_ equals the provided argument $EXPECTED_TYPE and returns true/false. =head1 AUTHOR Steffen Schwigon =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2019 by Steffen Schwigon. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut __END__ # sub parent, Eltern-Knoten liefern # nextchild, von parent und mir selbst # previous child # "." als aktueller Knoten, kind of "no-op", daran aber Filter verknüpfbar, löst //.[filter] und /.[filter] # IDEA: functions that return always true, but track stack of values, eg. last taken index # # //AAA/*[ _push_idx ]/CCC[ condition ]/../../*[ idx == pop_idx + 1]/ # # This would take a way down to a filtered CCC, then back again and take the next neighbor.