Hash of array access tricks. Sorry, long.

S

s. keeling

I've built a HoA as so:

my %prompt = (
FIRST_NAME => [ qq(NULL), qq(NULL), qq(\tFirst name -> ),
qq(You MUST supply a first name.\n) ],
LAST_NAME => [ qq(NULL), qq(NULL), qq(\tLast name -> ),
qq(You MUST supply a last name.\n) ],

and so on. I'd like to write to and access $prompt->{$key}[2] when
prompting a user for the name, and I'd like to stuff the reply in
$prompt{$key}[1], then compare that with $prompt->{$key}[0], which
I'll try to supply via a call to mysql. :)

# FIRST_NAME
#
my $key = qq(FIRST_NAME);
print STDOUT qq($prompt->{$key}[2]);
$prompt->{$key}[1]=<STDIN>;
chomp($prompt->{$key}[1]);
if ( ! $prompt->{$key}[1] ) {
die $prompt->{$key}[3];
}

What I get is:

Use of uninitialized value in string at ./mupdate.pl line 154 (#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.


Use of uninitialized value in die at ./mupdate.pl line 158, <STDIN> line 1 (#1)

Died at ./mupdate.pl line 158, <STDIN> line 1 (#2)
(F) You passed die() an empty string (the equivalent of die "") or
you called it with no args and both $@ and $_ were empty.

Uncaught exception from user code:
Died at ./mupdate.pl line 158, <STDIN> line 1.
at ./mupdate.pl line 158


I think I'm using the same sort of thing, using the same syntax as
Perl Cookbook and Camel say it's to be done. It sort of works when I
use $prompt{$key}[N] instead. What am I confusing?
 
X

xhoster

s. keeling said:
I've built a HoA as so:

my %prompt = (
FIRST_NAME => [ qq(NULL), qq(NULL), qq(\tFirst name -> ),
qq(You MUST supply a first name.\n) ],
LAST_NAME => [ qq(NULL), qq(NULL), qq(\tLast name -> ),
qq(You MUST supply a last name.\n) ],

%prompt is a lexical hash.
$prompt->{$key}[1]=<STDIN>;

$prompt is an (undeclared?) scalar which is unrelated to %prompt, other
than that their names look kind of similar. You are trying to derefence
that scalar as if it held a reference to a hash, which there is no reason
to believe that it does.
What am I confusing?

The usefulness of "use strict", probably.

Xho
 
S

s. keeling

s. keeling said:
I've built a HoA as so:

my %prompt = (
FIRST_NAME => [ qq(NULL), qq(NULL), qq(\tFirst name -> ),
qq(You MUST supply a first name.\n) ],
LAST_NAME => [ qq(NULL), qq(NULL), qq(\tLast name -> ),
qq(You MUST supply a last name.\n) ],

and so on. I'd like to write to and access $prompt->{$key}[2] when
prompting a user for the name, and I'd like to stuff the reply in
$prompt{$key}[1], then compare that with $prompt->{$key}[0], which
I'll try to supply via a call to mysql. :)

I should also say for some reason it won't work if I don't declare
both $prompt and %prompt, ... or should I just be "my"ing the former
and not the latter? I'll try that too.
 
P

Paul Lalli

s. keeling said:
s. keeling said:
I've built a HoA as so:

my %prompt = (
FIRST_NAME => [ qq(NULL), qq(NULL), qq(\tFirst name -> ),
qq(You MUST supply a first name.\n) ],
LAST_NAME => [ qq(NULL), qq(NULL), qq(\tLast name -> ),
qq(You MUST supply a last name.\n) ],

and so on. I'd like to write to and access $prompt->{$key}[2] when
prompting a user for the name, and I'd like to stuff the reply in
$prompt{$key}[1], then compare that with $prompt->{$key}[0], which
I'll try to supply via a call to mysql. :)

I should also say for some reason it won't work if I don't declare
both $prompt and %prompt, ... or should I just be "my"ing the former
and not the latter? I'll try that too.


Throwing stuff at the wall to see what sticks is a poor method of
debugging your program. The reason it told you to define $prompt is
because you were using $prompt intead of the variable you actually
declared, which was %prompt. $prompt and %prompt are 100% unrelated.

%prompt ==> hash
$prompt{$key} ==> value of %hash at $key
$prompt ==> scalar. Possibly a reference to a hash
$prompt->{$key} ==> value of the hash referenced by $prompt, at $key

For more information:
perldoc perlref

Paul Lalli
 
S

simon.chao

Paul said:
Throwing stuff at the wall to see what sticks is a poor method of
debugging your program. The reason it told you to define $prompt is
because you were using $prompt intead of the variable you actually
declared, which was %prompt. $prompt and %prompt are 100% unrelated.


to be pedantic, aren't $prompt and %prompt related by the fact that
they are in the same typeglob?

the typeglob *prompt contains in its symbol table both $prompt and
%prompt.

the contents of the variables $prompt and %prompt may be unrelated, but
the variables themselves are related. i think. i don't know too much
about typeglobs...
 
A

A. Sinan Unur

(e-mail address removed) wrote in
to be pedantic, aren't $prompt and %prompt related by the fact that
they are in the same typeglob?

the typeglob *prompt contains in its symbol table both $prompt and
%prompt.

the contents of the variables $prompt and %prompt may be unrelated,
but the variables themselves are related. i think. i don't know too
much about typeglobs...

http://www.perl.com/pub/a/2002/05/14/mod_perl.html

<blockquote>
When you create a symbol, Perl creates a symbol table entry for
that symbol in the current package's symbol table (by default main::).
Each symbol table entry is called a typeglob. Each typeglob can hold
information on a scalar, an array, a hash, a subroutine (code), a
filehandle, a directory handle and a format, each of which all have the
same name. So you see now that there are two indirections for a global
variable: the symbol (the thing's name) points to its typeglob, and the
entry in the typeglob for the thing's type (scalar, array, etc.) points
to the data. If we had a scalar and an array with the same name, then
their name would point to the same typeglob, but for each type of data
the typeglob points to somewhere different. Hence, the scalar's data and
the array's data are completely separate and independent, they just
happen to have the same name.
</blockquote>

Sinan
 
X

xhoster

to be pedantic, aren't $prompt and %prompt related by the fact that
they are in the same typeglob?

If they were package variables I would agree. But because at least one
of them was lexical, I think not.


Xho
 
S

s. keeling

Paul Lalli said:
s. keeling said:
s. keeling said:
I've built a HoA as so:

my %prompt = (
FIRST_NAME => [ qq(NULL), qq(NULL), qq(\tFirst name -> ),
qq(You MUST supply a first name.\n) ],
LAST_NAME => [ qq(NULL), qq(NULL), qq(\tLast name -> ),
qq(You MUST supply a last name.\n) ],

and so on. I'd like to write to and access $prompt->{$key}[2] when
prompting a user for the name, and I'd like to stuff the reply in
$prompt{$key}[1], then compare that with $prompt->{$key}[0], which
I'll try to supply via a call to mysql. :)

I should also say for some reason it won't work if I don't declare
both $prompt and %prompt, ... or should I just be "my"ing the former

Throwing stuff at the wall to see what sticks is a poor method of

Granted. It was just reflex.
debugging your program. The reason it told you to define $prompt is
because you were using $prompt intead of the variable you actually
declared, which was %prompt. $prompt and %prompt are 100% unrelated. ..................................^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

%prompt ==> hash
$prompt{$key} ==> value of %hash at $key

Do you not see the relationship?!?
$prompt ==> scalar. Possibly a reference to a hash
$prompt->{$key} ==> value of the hash referenced by $prompt, at $key

Yes, and I'm trying to get to an element of array $key, $prompt->{$key}[2]
For more information:
perldoc perlref

Will do, have done, will do again. Thanks.
 
S

s. keeling

Lawrence Statton N1GAK/XE2 said:
s. keeling said:
s. keeling said:
I've built a HoA as so:

my %prompt = (
FIRST_NAME => [ qq(NULL), qq(NULL), qq(\tFirst name -> ),
qq(You MUST supply a first name.\n) ],
LAST_NAME => [ qq(NULL), qq(NULL), qq(\tLast name -> ),
qq(You MUST supply a last name.\n) ],

and so on. I'd like to write to and access $prompt->{$key}[2] when
prompting a user for the name, and I'd like to stuff the reply in
$prompt{$key}[1], then compare that with $prompt->{$key}[0], which
I'll try to supply via a call to mysql. :)

I should also say for some reason it won't work if I don't declare
both $prompt and %prompt, ... or should I just be "my"ing the former

perhaps this will help you understand...

#!/usr/bin/perl

Well,it adds to the mystery.
%prompt at $prompt are different variables.... Just WISHING $prompt
to become a refrence to %prompt will not make it so.

It seems my books disagreed, as I understood them. Now I see a
construct I hadn't seen necessary 'til now: @{$prompt->{$key}[2]}. Thx.
 
A

A. Sinan Unur

Paul Lalli said:
s. keeling said:
s. keeling <[email protected]>:
I've built a HoA as so:

my %prompt = (
FIRST_NAME => [ qq(NULL), qq(NULL), qq(\tFirst name ->
),
qq(You MUST supply a first name.\n) ],
LAST_NAME => [ qq(NULL), qq(NULL), qq(\tLast name ->
),
qq(You MUST supply a last name.\n) ],

and so on. I'd like to write to and access $prompt->{$key}[2]
when prompting a user for the name, and I'd like to stuff the
reply in $prompt{$key}[1], then compare that with
$prompt->{$key}[0], which I'll try to supply via a call to
mysql. :)

I should also say for some reason it won't work if I don't declare
both $prompt and %prompt, ... or should I just be "my"ing the
former

Throwing stuff at the wall to see what sticks is a poor method of

Granted. It was just reflex.
debugging your program. The reason it told you to define $prompt is
because you were using $prompt intead of the variable you actually
declared, which was %prompt. $prompt and %prompt are 100%
unrelated. .................................
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^

%prompt ==> hash
$prompt{$key} ==> value of %hash at $key

Do you not see the relationship?!?

There is no relationship between the scalar variable $prompt and $prompt
{$key}.
$prompt ==> scalar. Possibly a reference to a hash
$prompt->{$key} ==> value of the hash referenced by $prompt, at $key

Yes, and I'm trying to get to an element of array $key,
$prompt->{$key}[2]

Here is the problem you are having: You have a hash, %prompt, and you
are expecting that $prompt will be a reference to that hash. That is not
so, for all the reasons explained in this thread. You have two options:
Ditch %prompt, and declare $prompt to be a reference to an anonymous
hash containing the data you want:

my $prompt = {
FIRST_NAME => [ qq(NULL), qq(NULL), qq(\tFirst name -> ),
qq(You MUST supply a first name.\n) ],
LAST_NAME => [ qq(NULL), qq(NULL), qq(\tLast name -> ),
qq(You MUST supply a last name.\n) ],
};

Then, $prompt->{FIRST_NAME}->[2] will be "\tLast name ->".

Alternatively, if you want to keep %prompt, but want to access it using
a reference to it in $prompt, you'll need to explicitly say:

my $prompt = \%prompt;

Otherwise, there is no relationship between $prompt and %prompt.

Creating a hash called %prompt does not automatically create a reference
to it by the name $prompt.

Sinan

PS: Setting X-No-Archive: yes is a good way of making your way into many
killfiles.
 
I

it_says_BALLS_on_your forehead

s. keeling said:
Paul Lalli said:
s. keeling said:
s. keeling <[email protected]>:
I've built a HoA as so:

my %prompt = (
FIRST_NAME => [ qq(NULL), qq(NULL), qq(\tFirst name -> ),
qq(You MUST supply a first name.\n) ],
LAST_NAME => [ qq(NULL), qq(NULL), qq(\tLast name -> ),
qq(You MUST supply a last name.\n) ],

and so on. I'd like to write to and access $prompt->{$key}[2] when
prompting a user for the name, and I'd like to stuff the reply in
$prompt{$key}[1], then compare that with $prompt->{$key}[0], which
I'll try to supply via a call to mysql. :)

I should also say for some reason it won't work if I don't declare
both $prompt and %prompt, ... or should I just be "my"ing the former

Throwing stuff at the wall to see what sticks is a poor method of

Granted. It was just reflex.
debugging your program. The reason it told you to define $prompt is
because you were using $prompt intead of the variable you actually
declared, which was %prompt. $prompt and %prompt are 100% unrelated. .................................^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

%prompt ==> hash
$prompt{$key} ==> value of %hash at $key

Do you not see the relationship?!?
$prompt ==> scalar. Possibly a reference to a hash
$prompt->{$key} ==> value of the hash referenced by $prompt, at $key

Yes, and I'm trying to get to an element of array $key, $prompt->{$key}[2]
For more information:
perldoc perlref

Will do, have done, will do again. Thanks.

I'm fairly certain Paul sees the relation ship between:
%prompt and $prompt{$key}. the former is a hash, and the latter
represents the scalar ($) value associated with the key ($key) of the
hash (%prompt).

but re: the scenario you presented, you were attempting to relate:
%prompt (hash)
and
$prompt (from the context, you expected $prompt to be a hash reference)

....i believe you are confused because of the name. to access a value in
$prompt (assuming it was a valid hash reference), you would need to
write:
$prompt->{$key}

an analogy that i can think of which may help you out is this: i have a
token which can get me on the subway. i have named this token 'Max'. i
also have a voucher for a token that can get me on the subway. i call
this voucher 'Max' as well. these two items can get me to my goal
(getting on the subway), and they have the same name, but they are 2
different types of things. one can grant me direct access to the
subway, and the other can get me the thing that can get me on the
subway.

please correct me if i'm mangling this analogy...
 
S

s. keeling

it_says_BALLS_on_your forehead said:
s. keeling said:
Paul Lalli said:
s. keeling wrote:
s. keeling <[email protected]>:
I've built a HoA as so:

my %prompt = (
FIRST_NAME => [ qq(NULL), qq(NULL), qq(\tFirst name -> ),
qq(You MUST supply a first name.\n) ],
LAST_NAME => [ qq(NULL), qq(NULL), qq(\tLast name -> ),
qq(You MUST supply a last name.\n) ],

and so on. I'd like to write to and access $prompt->{$key}[2] when
prompting a user for the name, and I'd like to stuff the reply in
$prompt{$key}[1], then compare that with $prompt->{$key}[0], which
I'll try to supply via a call to mysql. :)

I should also say for some reason it won't work if I don't declare
both $prompt and %prompt, ... or should I just be "my"ing the former

debugging your program. The reason it told you to define $prompt is
because you were using $prompt intead of the variable you actually
declared, which was %prompt. $prompt and %prompt are 100% unrelated. .................................^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

%prompt ==> hash
$prompt{$key} ==> value of %hash at $key

Do you not see the relationship?!?
$prompt ==> scalar. Possibly a reference to a hash
$prompt->{$key} ==> value of the hash referenced by $prompt, at $key

Yes, and I'm trying to get to an element of array $key, $prompt->{$key}[2]
For more information:
perldoc perlref

Will do, have done, will do again. Thanks.

I'm fairly certain Paul sees the relation ship between:
%prompt and $prompt{$key}. the former is a hash, and the latter
represents the scalar ($) value associated with the key ($key) of the
hash (%prompt).

but re: the scenario you presented, you were attempting to relate:
%prompt (hash)
and
$prompt (from the context, you expected $prompt to be a hash reference)

I was going from things I was looking at in books thinking:

my %hash;
$hash{$key}[$subs] = qq(blah!);

Which works.

I was unaware of the other side of this; a reference to a hash?

my %hash;
$hash = \%hash;
@{$hash->{$key}[$subs]} = qq(blah!);

I think. I was trying to concentrate on the former method.
...i believe you are confused because of the name. to access a value in
$prompt (assuming it was a valid hash reference), you would need to
write:
$prompt->{$key}

Many thanks for everybody's input on this. I've got it working
splendidly now.
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top