For Programmers: Free Programming Magazines  


Home > Archive > PERL Miscellaneous > April 2004 > backslash in hash keys









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author backslash in hash keys
Marko Riedel

2004-04-27, 2:06 am


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,

--
+------------------------------------------------------------+
| Marko Riedel, EDV Neue Arbeit gGmbH, mriedel@neuearbeit.de |
| http://www.geocities.com/markoriedelde/index.html |
+------------------------------------------------------------+
Marko Riedel

2004-04-27, 2:06 am


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,

--
+------------------------------------------------------------+
| Marko Riedel, EDV Neue Arbeit gGmbH, mriedel@neuearbeit.de |
| http://www.geocities.com/markoriedelde/index.html |
+------------------------------------------------------------+
Tad McClellan

2004-04-27, 2:06 am

Marko Riedel <mriedel@neuearbeit.de> wrote:

> 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/ });'


--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas
Anno Siegel

2004-04-27, 2:06 am

Marko Riedel <mriedel@neuearbeit.de> wrote in comp.lang.perl.misc:
>
> 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
Christian Winter

2004-04-27, 2:06 am

Marko Riedel schrieb:
> 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


Using the "\" outside of quotes lets perl interprete it
as reference operator. "use strict;" would have made that
obvious. Try
perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if exists($h{q/\B/});'
perl -e '%h=qw/\A 1 \B 2/; print "yes\n" if exists($h{"\\B"});'
which both work, as does your grep-example that also uses
quotes.

HTH
-Christian
Sandman

2004-04-27, 2:06 am

In article <m2llkivr3e.fsf@linuxsexi.nasttg>,
mriedel@neuearbeit.de (Marko Riedel) wrote:

> 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

--
Sandman[.net]
Jim Cochrane

2004-04-27, 2:06 am

In article <m2llkivr3e.fsf@linuxsexi.nasttg>, Marko Riedel wrote:
>
> 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.

--
Jim Cochrane; jtc@dimensional.com
[When responding by email, include the term non-spam in the subject line to
get through my spam filter.]
Sandman

2004-04-29, 11:49 am

In article <m2ekqavpor.fsf@linuxsexi.nasttg>,
mriedel@neuearbeit.de (Marko Riedel) wrote:

> 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.

--
Sandman[.net]
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com