backslash in hash keys

M

Marko Riedel

Hi folks,

it seems that "exists" does not work on hash keys that begin with a
backslash, but grep on the keys finds the key. (These keys occur
e.g. when working with IMAP message flags.)

Would someone explain, please?

[PROMPT]> perl -e '%h=qw/A 1 B 2/; print "yes\n" if exists($h{B});'
yes
[PROMPT]> perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if exists($h{\B});'
[PROMPT]> perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if grep('\B', keys %h);'
yes

perl -v

This is perl, v5.8.0 built for i586-linux-thread-multi

Copyright 1987-2002, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using `man perl' or `perldoc perl'. If you have access to the
Internet, point your browser at http://www.perl.com/, the Perl Home Page.

Best regards,
 
M

Marko Riedel

Hello again,

my apologies: I didn't use grep properly. That said, the problem persists.

[PROMPT]> perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if grep(/\\B/, keys %h);'
yes
[PROMPT]> perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if grep(/\\C/, keys %h);'
[PROMPT]> perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if exists($h{\B});'
[PROMPT]>

Best regards,
 
T

Tad McClellan

Marko Riedel said:
it seems that "exists" does not work on hash keys that begin with a
backslash,
Would someone explain, please?

Sure.


[PROMPT]> perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if exists($h{\B});'
^^
^^
Where are the quotes for your hash key?

You don't get auto-quoting for keys that don't look like identifiers.


perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if exists($h{ q/\B/ });'
 
A

Anno Siegel

Marko Riedel said:
Hi folks,

it seems that "exists" does not work on hash keys that begin with a
backslash, but grep on the keys finds the key. (These keys occur
e.g. when working with IMAP message flags.)

Autoquoting doesn't work with backslashes (as documented), exists()
works fine.
Would someone explain, please?

[PROMPT]> perl -e '%h=qw/A 1 B 2/; print "yes\n" if exists($h{B});'
yes
[PROMPT]> perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if exists($h{\B});'

Apparently you're not running under warnings, or Perl would have
complained. Write that "exists{ '\B'}".

Anno
 
S

Sandman

Hi folks,

it seems that "exists" does not work on hash keys that begin with a
backslash, but grep on the keys finds the key. (These keys occur
e.g. when working with IMAP message flags.)

Would someone explain, please?

[PROMPT]> perl -e '%h=qw/A 1 B 2/; print "yes\n" if exists($h{B});'
yes
[PROMPT]> perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if exists($h{\B});'
[PROMPT]> perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if grep('\B', keys %h);'
yes

The \B need to be treated literally, not interpolated. This works:

#!/usr/bin/perl
use strict;
use warnings;

my %foo = qw/\A 1 \B 2/;
print exists($foo{'\B'}) ? "Yes" : "No";

__END__
Output: Yes


But this doesn't work:

print exists($foo{"\B"}) ? "Yes" : "No";

perl is trying to treat \B as an escaped character in interpolated context, and
you get this warning:

Unrecognized escape \B passed through
 
S

Sandman

Hello again,

my apologies: I didn't use grep properly. That said, the problem persists.

[PROMPT]> perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if grep(/\\B/, keys %h);'
yes
[PROMPT]> perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if grep(/\\C/, keys %h);'
[PROMPT]> perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if exists($h{\B});'

Either:

perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if exists($h{"\\B"});'

or

perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if exists($h{q/\B/});'

works fine.
 
J

Jim Cochrane

Hi folks,

it seems that "exists" does not work on hash keys that begin with a
backslash, but grep on the keys finds the key. (These keys occur
e.g. when working with IMAP message flags.)

Would someone explain, please?

[PROMPT]> perl -e '%h=qw/A 1 B 2/; print "yes\n" if exists($h{B});'
yes
[PROMPT]> perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if exists($h{\B});'
[PROMPT]> perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if grep('\B', keys %h);'
yes

perl -v

And if you tell perl, in the 2nd program to "use strict", you get:

yes
Bareword "B" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.
yes

which gives you a clue as to why what you expected is not happening.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top