Problem with hash and regexp

F

Francisco

Can someone please explain me what's wrong here? (coments in the code).
Thank you.

#!/usr/bin/perl -w
use strict;
use diagnostics;

my %severity = (
000 => 'emerg',
001 => 'alert',
010 => 'crit',
011 => 'err',
100 => 'warn',
101 => 'notice',
110 => 'info',
111 => 'debug'
);

my $numsev = 123;
my $binsev = dec2bin($numsev);
#it's clear after some experiments that the problem comes from this
conversion
print "binsev: $binsev\n";
#the binary number was converted OK
$binsev =~ /(\d{3})$/;
print "binsev3: $1\n";
#it appears that I get the 3 LSB of the binary number as I wanted
print "sev: $severity{$binsev3}\n";
#but here the hash lookup fails and I can't understand the reason, maybe
something at the end of the string that is wrong?

sub dec2bin { return sprintf "%b", shift }

Perl output:
binsev: 1111011
binsev3: 011
Use of uninitialized value in concatenation (.) or string at ./bla.pl line
24 (#1)
(W uninitialized) An undefined value was used as if it were already
defined. It was interpreted as a "" or a 0, but maybe it was a mistake.
To suppress this warning assign a defined value to your variables.

To help you figure out what was undefined, perl tells you what operation
you used the undefined value in. Note, however, that perl optimizes
your
program and the operation displayed in the warning may not necessarily
appear literally in your program. For example, "that $foo" is
usually optimized into "that " . $foo, and the warning will refer to
the concatenation (.) operator, even though there is no . in your
program.

sev:
 
B

Brian McCauley

Francisco said:
Subject: Problem with hash and regexp

Your problem has nothing to do with hashes or regexes.
my %severity = (
000 => 'emerg',
001 => 'alert',
010 => 'crit',
011 => 'err',
100 => 'warn',
101 => 'notice',
110 => 'info',
111 => 'debug'
);

The auto quoting effect of => does not apply to numbers. 000 is just 0.
001 is just 1. 010 is just 8.
 
F

Fabian Pilkowski

* Francisco said:
Can someone please explain me what's wrong here? (coments in the code).
Thank you.

#!/usr/bin/perl -w
use strict;
use diagnostics;

my %severity = (
000 => 'emerg',
001 => 'alert',
010 => 'crit',
011 => 'err',
100 => 'warn',
101 => 'notice',
110 => 'info',
111 => 'debug'
);

Here I would add the following two lines

use Data::Dumper;
print Dumper \%severity;

to see how %severity is initialized now. Remember: numbers beginning
with zero are interpreted as octal ones. Try to use more quotes.

regards,
fabian
 
X

xhoster

Francisco said:
print "binsev3: $1\n";
#it appears that I get the 3 LSB of the binary number as I wanted
print "sev: $severity{$binsev3}\n";
# ^^^^^^^^ Where did this come from?

Aside from the fact that you haven't made sure the contents of your
hash are what you think they are, as others have pointed out, you also
apparently aren't using strict.

Xho
 
F

Francisco

Brian said:
The auto quoting effect of => does not apply to numbers. 000 is just 0.
001 is just 1. 010 is just 8.

I can't believe it!!, thank you very much. I've made tests before asking for
the values directlly, but I was using the value "101" of the hash that
wasn't changed, so I though the hash wasn't the problem.
 
T

Tad McClellan

Fabian Pilkowski said:
* Francisco schrieb:

Try to use more quotes.


Or, try to use *less* quotes:

my %severity = qw(
000 emerg
001 alert
010 crit
011 err
100 warn
101 notice
110 info
111 debug
);

:)
 
P

Paul Lalli

Francisco said:
Can someone please explain me what's wrong here? (coments in the code).
Thank you.

#!/usr/bin/perl -w
use strict;
use diagnostics;

my %severity = (
000 => 'emerg',
001 => 'alert',
010 => 'crit',
011 => 'err',
100 => 'warn',
101 => 'notice',
110 => 'info',
111 => 'debug'
);

my $numsev = 123;
my $binsev = dec2bin($numsev);
#it's clear after some experiments that the problem comes from this
conversion
print "binsev: $binsev\n";
#the binary number was converted OK
$binsev =~ /(\d{3})$/;
print "binsev3: $1\n";
#it appears that I get the 3 LSB of the binary number as I wanted
print "sev: $severity{$binsev3}\n";
#but here the hash lookup fails and I can't understand the reason, maybe
something at the end of the string that is wrong?

sub dec2bin { return sprintf "%b", shift }

Perl output:
binsev: 1111011
binsev3: 011
Use of uninitialized value in concatenation (.) or string at ./bla.pl line
24 (#1)

That's a lie.

Here's the output I get from running your program:
Global symbol "$binsev3" requires explicit package name at clpm.pl line
25.
Execution of clpm.pl aborted due to compilation errors (#1)

Please post real code. Have you read the posting guidelines for this
group yet?

Paul Lalli
 
T

Tad McClellan

Jim Gibson said:
8: crit

So '010' and '011' are being interpreted as octal numbers. This would
seem to belie the Comma Operator documentation in perldoc perlop:

"The "=>" operator is a synonym for the comma, but forces any word to
its left to be interpreted as a string (as of 5.001). It is helpful in
documenting the correspondence between keys and values in hashes, and
other paired elements in lists."

Why this is so and whether or not this is a bug in perl must be left to
those more knowledgable about perl internals than I.


It may be a bug in the documentation, but I don't see how it
could be a bug in the internals.

"word" appears to mean "follows the same rules as user-defined
identifiers", that is: it is a word (and hence will be auto-quoted)
if it matches:

/^[a-zA-Z_]\w*$/
 
C

Chris Mattern

Tad said:
Or, try to use *less* quotes:

my %severity = qw(
000 emerg
001 alert
010 crit
011 err
100 warn
101 notice
110 info
111 debug
);

:)
Arguably, that's still "using more quotes". You're just getting
Perl to put them in for you.

--
Christopher Mattern

"Which one you figure tracked us?"
"The ugly one, sir."
"...Could you be more specific?"
 
C

Charles DeRykus

Jim Gibson said:
8: crit

So '010' and '011' are being interpreted as octal numbers. This would
seem to belie the Comma Operator documentation in perldoc perlop:

"The "=>" operator is a synonym for the comma, but forces any word to
its left to be interpreted as a string (as of 5.001). It is helpful in
documenting the correspondence between keys and values in hashes, and
other paired elements in lists."

Why this is so and whether or not this is a bug in perl must be left to
those more knowledgable about perl internals than I.


It may be a bug in the documentation, but I don't see how it
could be a bug in the internals.

"word" appears to mean "follows the same rules as user-defined
identifiers", that is: it is a word (and hence will be auto-quoted)
if it matches:

/^[a-zA-Z_]\w*$/

Ah, I've never noticed that subtlety.

Without clarifying what's meant by 'word', one might assume '=>'
acts like 'qw'. The docs IMO would be greatly improved by spelling
it out:

'...but forces any user-identifier (i.e.,/^[a-zA-Z]\w*$/)
to its left to be interpreted as a string...'
 
A

ajs

Jim Gibson wrote:
[...]
So '010' and '011' are being interpreted as octal numbers. This would
seem to belie the Comma Operator documentation in perldoc perlop:

"The "=>" operator is a synonym for the comma, but forces any word to
[...]

Your mistake here is a misunderstanding of the definition of the word,
"word".

In Perl, this has a clear meaning: a string of characters that starts
with a letter matching the pattern "[A-Za-z_]" and contains zero or
more characters after the first that match the pattern "[A-Za-z0-9_]".
This is also Perl's definition of an "identifier" for purposes of
unquoted variable and subroutine naming (among other things).

Numbers are never auto-quoted by "=>" because they are not words, just
as any other sequence of non-word characters would not.
 
X

xhoster

Jim Gibson said:
So '010' and '011' are being interpreted as octal numbers. This would
seem to belie the Comma Operator documentation in perldoc perlop:

"The "=>" operator is a synonym for the comma, but forces any word to
its left to be interpreted as a string (as of 5.001). It is helpful in
documenting the correspondence between keys and values in hashes, and
other paired elements in lists."

The => operator is more clearly documented in perldata than it is perlop.

It is often more readable to use the "=>" operator between key/value
pairs. The "=>" operator is mostly just a more visually distinctive
synonym for a comma, but it also arranges for its left-hand operand
to be interpreted as a string--if it's a bareword that would be a
legal identifier. This makes it nice for initializing hashes:

Xho
 

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,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top