recursive ref value match

this is pretty abstract from what i'm really doing, but i'll put in
the blurb anyway...

i'm using CAM::PDF to parse data. this works well. however, i am
trying to extract information out of a table. so, i want to find
certain keys, then go up 3 levels and grab the position of that peace
of data so that i can then search for text with that same horizontal
or vertical position (defined in two other refs on the same level of a
different 'branch'). so, what i want is an array ref with the number
of found keys with the refs it took to get there. i've liked
Data::Walk but i couldn't figure out how to return the results - all i
could do is 'print'. and i couldn't figure out how to use
Data::Visitor either. so, i figured i'd try myself.

a few things i don't understand here:
does the second print cut off?
when i pass $tree instead of \$tree, it gives me this:
CAM::PDF::Content=HASH(0x2b298a8) is CAM::PDF::Content LEVEL: 0 FOUND:
0 CLEAR: 0
where CAM::PDF::Content isn't going to match anything. how do i handle this?
obviously i'm not thinking clearly about how i need to build
$datdepth. and ideally, i'd like the value to be internal to the sub
and returned when it is finished instead of global. any help with my
thinking would be great.

so, here's where i'm at:


my $pdf = CAM::PDF->new('file.pdf');
my $pages = $pdf->numPages;

print "PAGES: $pages\n";

my $datdepth;

sub datarec {
my( $data, $regex, $lvl, $found, $clear ) = [at] _;
$lvl ||= 0;
$found ||= 0;
$clear ||= 0;
return -1 unless( $data );

print "$data is ", ref( $data ), " LEVEL: $lvl FOUND: $found CLEAR: $clear\n";
if( ( ref( $data ) or $data ) eq 'SCALAR' ) {
if( $data =~ /$regex/ ) {
$datdepth->[ $found + 1 ] = $datdepth->[ $found ];
$datdepth->[ $found++ ]->[ $lvl ] = $data;
$clear = 0;
} else {
return $clear = 1;
}
} elsif( ( ref( $data ) or $data ) eq 'HASH' ) {
foreach( values %$data ) {
$datdepth->[ $found ]->[ $lvl ] = $data;
$clear = datarec( $_, $regex, $lvl + 1, $found );
}
} elsif( ( ref( $data ) or $data ) eq 'ARRAY' ) {
foreach( [at] $data ) {
$datdepth->[ $found ]->[ $lvl ] = $data;
( $found, $clear ) = datarec( $_, $regex, $lvl + 1, $found );
}
} elsif( ( ref( $data ) or $data ) eq 'REF' ) {
$datdepth->[ $found ]->[ $lvl ] = $data;
( $found, $clear ) = datarec( $_, $regex, $lvl + 1, $found );
} elsif( ( ref( $data ) or $data ) ne ( 'SCALAR' or 'HASH' or 'ARRAY' ) ) {
print "$data is ", ref( $data ), "\n";
} else {
print "SOMETHING HORRIBLE!\n";
}

if( $clear and $clear == 1 ) {
foreach my $i ( $lvl .. $#{ $datdepth->[ $found ] } ) {
undef( $datdepth->[ $found ]->[ $i ] );
}
}
}


for( 1 .. $pages ) {

my $cur = $_;
my $i = 0;

print "PAGE: $cur\n" if( $cur == 8 );

if( $cur == 8 ) {
my $tree = $pdf->getPageContentTree( $cur );
#$tree->render("CAM::PDF::Renderer::Dump");

datarec( \$tree, qr/10\. / );

#print Dumper $datdepth->[ $#$datdepth ]->[ $#{ $datdepth->[
$#$datdepth ] } ], "\n";


print "DONE\n";
}
}


__DATA__

PAGES: 32
PAGE: 8
REF(0x2ef4bf8) is REF LEVEL: 0 FOUND: 0 CLEAR: 0
8 is LEVEL: 1 FOUND: 0 CLEAR: 0
8 is
DONE

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Shawn Wilson [ So, 03 April 2011 14:27 ] [ ID #2057572 ]

Re: recursive ref value match

shawn wilson wrote:
> this is pretty abstract from what i'm really doing, but i'll put in
> the blurb anyway...
>
> i'm using CAM::PDF to parse data. this works well. however, i am
> trying to extract information out of a table. so, i want to find
> certain keys, then go up 3 levels and grab the position of that peace
> of data so that i can then search for text with that same horizontal
> or vertical position (defined in two other refs on the same level of a
> different 'branch'). so, what i want is an array ref with the number
> of found keys with the refs it took to get there. i've liked
> Data::Walk but i couldn't figure out how to return the results - all i
> could do is 'print'. and i couldn't figure out how to use
> Data::Visitor either. so, i figured i'd try myself.
>
> a few things i don't understand here:
> does the second print cut off?
> when i pass $tree instead of \$tree, it gives me this:
> CAM::PDF::Content=HASH(0x2b298a8) is CAM::PDF::Content LEVEL: 0 FOUND:
> 0 CLEAR: 0
> where CAM::PDF::Content isn't going to match anything. how do i handle this?
> obviously i'm not thinking clearly about how i need to build
> $datdepth. and ideally, i'd like the value to be internal to the sub
> and returned when it is finished instead of global. any help with my
> thinking would be great.
>
> so, here's where i'm at:

[ SNIP some code ]


> if( ( ref( $data ) or $data ) eq 'SCALAR' ) {

> } elsif( ( ref( $data ) or $data ) eq 'HASH' ) {

> } elsif( ( ref( $data ) or $data ) eq 'ARRAY' ) {

> } elsif( ( ref( $data ) or $data ) eq 'REF' ) {

> } elsif( ( ref( $data ) or $data ) ne ( 'SCALAR' or 'HASH' or 'ARRAY' ) ) {


Those comparisons are not going to work, or at least not in the way you
probably intended.

$ perl -le' print "It did ", ( $ARGV[0] or $ARGV[1] ) eq "TEST" ? "" :
"NOT ", "work." ' a b
It did NOT work.
$ perl -le' print "It did ", ( $ARGV[0] or $ARGV[1] ) eq "TEST" ? "" :
"NOT ", "work." ' a TEST
It did NOT work.
$ perl -le' print "It did ", ( $ARGV[0] or $ARGV[1] ) eq "TEST" ? "" :
"NOT ", "work." ' TEST b
It did work.


You have to do it like this:

$ perl -le' print "It did ", $ARGV[0] eq "TEST" || $ARGV[1] eq "TEST" ?
"" : "NOT ", "work." ' a b
It did NOT work.
$ perl -le' print "It did ", $ARGV[0] eq "TEST" || $ARGV[1] eq "TEST" ?
"" : "NOT ", "work." ' a TEST
It did work.
$ perl -le' print "It did ", $ARGV[0] eq "TEST" || $ARGV[1] eq "TEST" ?
"" : "NOT ", "work." ' TEST b
It did work.


As to the last example you probably need something like this:

} elsif ( grep( $_ ne ref $data, 'SCALAR', 'HASH', 'ARRAY' ) ||
grep( $_ ne $data, 'SCALAR', 'HASH', 'ARRAY' ) ) {




John
--
Any intelligent fool can make things bigger and
more complex... It takes a touch of genius -
and a lot of courage to move in the opposite
direction. -- Albert Einstein

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
jwkrahn [ So, 03 April 2011 20:32 ] [ ID #2057579 ]

Re: recursive ref value match

On Sun, Apr 3, 2011 at 6:32 PM, John W. Krahn <jwkrahn [at] shaw.ca> wrote:
> shawn wilson wrote:
>>
>> this is pretty abstract from what i'm really doing, but i'll put in
>> the blurb anyway...
>>
>> i'm using CAM::PDF to parse data. this works well. however, i am
>> trying to extract information out of a table. so, i want to find
>> certain keys, then go up 3 levels and grab the position of that peace
>> of data so that i can then search for text with that same horizontal
>> or vertical position (defined in two other refs on the same level of a
>> different 'branch'). so, what i want is an array ref with the number
>> of found keys with the refs it took to get there. i've liked
>> Data::Walk but i couldn't figure out how to return the results - all i
>> could do is 'print'. and i couldn't figure out how to use
>> Data::Visitor either. so, i figured i'd try myself.
>>
>> a few things i don't understand here:
>> does the second print cut off?
>> when i pass $tree instead of \$tree, it gives me this:
>> CAM::PDF::Content=3DHASH(0x2b298a8) is CAM::PDF::Content LEVEL: 0 FOUND:
>> 0 CLEAR: 0
>> where CAM::PDF::Content isn't going to match anything. how do i handle
>> this?
>> obviously i'm not thinking clearly about how i need to build
>> $datdepth. and ideally, i'd like the value to be internal to the sub
>> and returned when it is finished instead of global. any help with my
>> thinking would be great.
>>
>> so, here's where i'm at:
>
> [ SNIP some code ]
>
>
>> =A0 =A0if( ( ref( $data ) or $data ) eq 'SCALAR' ) {
>
>> =A0 =A0} elsif( ( ref( $data ) or $data ) eq 'HASH' ) {
>
>> =A0 =A0} elsif( ( ref( $data ) or $data ) eq 'ARRAY' ) {
>
>> =A0 =A0} elsif( ( ref( $data ) or $data ) eq 'REF' ) {
>
>> =A0 =A0} elsif( ( ref( $data ) or $data ) ne ( 'SCALAR' or 'HASH' or 'AR=
RAY' )
>> ) {
>
>
> Those comparisons are not going to work, or at least not in the way you
> probably intended.
>
> $ perl -le' print "It did ", ( $ARGV[0] or $ARGV[1] ) eq "TEST" ? "" : "N=
OT
> ", "work." ' =A0 a b
> It did NOT work.
> $ perl -le' print "It did ", ( $ARGV[0] or $ARGV[1] ) eq "TEST" ? "" : "N=
OT
> ", "work." ' =A0 a TEST
> It did NOT work.
> $ perl -le' print "It did ", ( $ARGV[0] or $ARGV[1] ) eq "TEST" ? "" : "N=
OT
> ", "work." ' =A0 TEST b
> It did work.
>
>
> You have to do it like this:
>
> $ perl -le' print "It did ", $ARGV[0] eq "TEST" || $ARGV[1] eq "TEST" ? "=
" :
> "NOT ", "work." ' =A0 a b
> It did NOT work.
> $ perl -le' print "It did ", $ARGV[0] eq "TEST" || $ARGV[1] eq "TEST" ? "=
" :
> "NOT ", "work." ' =A0 a TEST
> It did work.
> $ perl -le' print "It did ", $ARGV[0] eq "TEST" || $ARGV[1] eq "TEST" ? "=
" :
> "NOT ", "work." ' =A0 TEST b
> It did work.
>
>
> As to the last example you probably need something like this:
>
> =A0 =A0} elsif ( grep( $_ ne ref $data, 'SCALAR', 'HASH', 'ARRAY' ) || gr=
ep( $_
> ne $data, 'SCALAR', 'HASH', 'ARRAY' ) ) {
>

it would seem you were right. however, it's still not catching
CAM::PDF::Content=3DHASH(0x2f27340) as i'm still getting this:

PAGES: 32
PAGE: 8
CAM::PDF::Content=3DHASH(0x2690340) is CAM::PDF::Content LEVEL: 0 FOUND:
0 CLEAR: 0
CAM::PDF::Content=3DHASH(0x2690340) is CAM::PDF::Content
DONE

i think the problem is that i'm checking if it exactly equals 'HASH'
or whatever and it's giving me the result in an object. i don't really
want to do =3D~ /HASH/ because if there's a phrase in the pdf with the
word, i don't want it to match and this just doesn't seem like the
proper way to do things.

below is my function:

sub datarec {
my( $data, $regex, $lvl, $found, $clear ) =3D [at] _;
$lvl ||=3D 0;
$found ||=3D 0;
$clear ||=3D 0;
return -1 unless( $data );

print "$data is ", ref( $data ), " LEVEL: $lvl FOUND: $found CLEAR: $clear\=
n";
if( ref( $data ) eq 'SCALAR' || $data eq 'SCALAR' ) {
if( $data =3D~ /$regex/ ) {
$datdepth->[ $found + 1 ] =3D $datdepth->[ $found ];
$datdepth->[ $found++ ]->[ $lvl ] =3D $data;
$clear =3D 0;
} else {
return $clear =3D 1;
}
} elsif( ref( $data ) eq 'HASH' || $data eq 'HASH' ) {
foreach( values %$data ) {
$datdepth->[ $found ]->[ $lvl ] =3D $data;
$clear =3D datarec( $_, $regex, $lvl + 1, $found );
}
} elsif( ref( $data ) eq'ARRAY' || $data eq 'ARRAY' ) {
foreach( [at] $data ) {
$datdepth->[ $found ]->[ $lvl ] =3D $data;
( $found, $clear ) =3D datarec( $_, $regex, $lvl + 1, $found );
}
} elsif( ref( $data ) eq 'REF' || $data eq 'REF' ) {
$datdepth->[ $found ]->[ $lvl ] =3D $data;
( $found, $clear ) =3D datarec( $_, $regex, $lvl + 1, $found );
} elsif ( grep( $_ ne ref $data, 'SCALAR', 'HASH', 'ARRAY' ) ||
grep( $_ ne $data, 'SCALAR', 'HASH', 'ARRAY' ) ) {
print "$data is ", ref( $data ), "\n";
} else {
print "SOMETHING HORRIBLE!\n";
}

if( $clear and $clear =3D=3D 1 ) {
foreach my $i ( $lvl .. $#{ $datdepth->[ $found ] } ) {
undef( $datdepth->[ $found ]->[ $i ] );
}
}
}

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Shawn Wilson [ Mo, 04 April 2011 02:40 ] [ ID #2057584 ]
Perl » gmane.comp.lang.perl.beginners » recursive ref value match

Vorheriges Thema: Re: Perl Hash Comparison and concatenate result from %hash2 comparedto %hash1 into %hash3
Nächstes Thema: Re: Perl Hash Comparison and concatenate result from %hash2 comparedto %hash1 into %hash3