how do I print the name and value of a scalar

C

cartercc

Given a list of scalars, such as:
<code>
my $name;
my $address;
my $city;
my $state;
my $zip;
my @scalar_names = ($name, $address, $city, $state, $zip);
my %var_names_and_values;
</code>

How do I do this:
<pseudocode>
foreach my $element (@scalar_names)
{
$var_names_and_values{?ELEMENT_NAME?} => $element;
}
</pseudocode>

So that I can do this:
<code>
print "Variable names and values\n";
foreach my $key (sort keys %var_names_and_values)
{
print " * $key => $var_names_and_values{$key}\n";
}
</code>

With the objective of producing output like this:
<output>
Variable names and values
* name => John Smith
* address => 1234 Easy Street
* city => Paradise
....
</output>

As always, thanks, CC.
 
C

Charlton Wilbur

cc> How do I do this: [...] So that I can do this:
cc> With the objective of producing output like this:

If what you really want is a hash, use a hash in the first place.

Charlton
 
C

cartercc

    cc> How do I do this: [...] So that I can do this:
    cc> With the objective of producing output like this:

If what you really want is a hash, use a hash in the first place.

Charlton


What I need is a way to get at the NAME of a variable as well as a
value.

CC
 
A

A. Sinan Unur

"cc" == cartercc  <[email protected]> writes:

    cc> How do I do this: [...] So that I can do this:
    cc> With the objective of producing output like this:

If what you really want is a hash, use a hash in the first place.

[ don't quote sigs ]
What I need is a way to get at the NAME of a variable as well as a
value.

Nope. What you need to do is to use a hash in the first place, if you want
a hash.

Sinan

--
A. Sinan Unur <[email protected]>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://www.rehabitation.com/clpmisc/
 
T

Tad J McClellan

cartercc said:
"cc" == cartercc  <[email protected]> writes:

    cc> How do I do this: [...] So that I can do this:
    cc> With the objective of producing output like this:

If what you really want is a hash, use a hash in the first place.

What I need is a way to get at the NAME of a variable as well as a
value.


That is what using a hash will give you.

What you need is a way to get at the KEY of a hash variable as
well as a value. :)
 
C

Charlton Wilbur

cc> What I need is a way to get at the NAME of a variable as well as
cc> a value.

Yes, which means that what you want is a hash.

Charlton
 
C

cartercc

Yes, which means that what you want is a hash.  

Okay, I'm confused, and I don't mind admitting it. (sorry about that)

In my little app, I've reached a point where the sheer volume of
scalar values has become burdensome. I don't know whether I really
need a hash or something else. I can print out the values of my
variables with no problem. The problem is that some of the variables
have similar values and I need to distinguish them, e.g., $password1,
$password2, $password3.

Maybe I'm approaching this in the wrong way, and to be honest, I
haven't given it a lot of thought. I have an array, which I have been
populating manually, which consists of the variable names, and I have
been using this array to print out the values of the variables. This
array looks like either one of these two examples:

my @vars = qw(name,address,city,state,zip);
my @vars = qw($name,$address,$city,$state,$zip);

I find that I can print either the (1) variable names, or (2) the
variable values -- but not both. What I would really like to do is
automate a print to console a list that looks like this:

name => John Doe
pw1 => qwerty
pw2 => qwertx
#pw2 should match pw1
email => some(at)domain(dot)com
#intentionally not valid, can't use a RE because of the variances of
falsifying email addresses

I might add that in Lisp I can do this without a problem, by printing
the symbol and then the value of the symbol. I ought to be able to do
this easily in Perl, but I can't. I'm willing to take the hit for my
confusion, or my ignorance.

CC
 
J

Jürgen Exner

cartercc said:
Given a list of scalars, such as:
<code>
my $name;
my $address;
my $city;
my $state;
my $zip;
my @scalar_names = ($name, $address, $city, $state, $zip);
my %var_names_and_values;
</code>

How do I do this:
<pseudocode>
foreach my $element (@scalar_names)
{
$var_names_and_values{?ELEMENT_NAME?} => $element;
}
</pseudocode>

As has been pointed out last week already (did you read the replies?)
you are looking for symbolic references. It has also been pointed out
that symbolic references have _A_LOT_ of issues and that in 99.99999% of
all cases you absolutely, definately don't want to use them. The
remaining 0.000001% or so are for those experts, who know what they are
doing and really truly understand the purpose and limitations of
symbolic references for very special applications that involves
deep-down, dirty perl interna and access to the system symbol table.

In short: symbolic references allow you to access the internal symbol
table and for 99.9999% of all cases there is no good reason to use the
internal symobl table instead of creating your own private symbol table
in form of a hash.

my @scalar_names = qw/name address city state zip);
my %vars;
for (@scalar_names) { #strictly speaking initialisation is unnecessary!
$vars{$_} = undef;
}

Now you got your scalar values $vars{name}, $var{address}, and so on.

jue
 
T

Tad J McClellan

cartercc said:
Okay, I'm confused, and I don't mind admitting it. (sorry about that)

In my little app, I've reached a point where the sheer volume of
scalar values has become burdensome. I don't know whether I really
need a hash or something else.


That may make it difficult to rework into using a hash instead
of a bunch of (I assume) file-scoped lexical variables...

What I would really like to do is
automate a print to console a list that looks like this:

name => John Doe
pw1 => qwerty
pw2 => qwertx

rework your program to use a hash instead of standalone named variables:

my %v; # all of the variables
$v{name} = 'John Doe'; # instead of: my $name = 'John Doe'
$v{pw1} = 'qwerty'; # instead of: my $pw1 = 'qwerty'
...

then dump them out:

print "$_ => $v{$_}\n" for keys %v;

I might add that in Lisp I can do this without a problem, by printing
the symbol and then the value of the symbol. I ought to be able to do
this easily in Perl, but I can't.


You can do that relatively easily in Perl if the variables
are package variables (by examining the Symbol Table).

But package variables are global variables, and come with all of
the negative baggage associated with global variables.

For lexical variables (declared with my()), you could perhaps work
out something using the PadWalker module...
 
J

Jürgen Exner

cartercc said:
"cc" == cartercc  <[email protected]> writes:

    cc> How do I do this: [...] So that I can do this:
    cc> With the objective of producing output like this:

If what you really want is a hash, use a hash in the first place.

What I need is a way to get at the NAME of a variable as well as a
value.

Then use a hash. In
my $name = 'foobar';
$myhash{ $name} = 'whatever';
you got the name of the variable ('foobar') as well as the value
('whatever').

jue
 
G

Gunnar Hjalmarsson

I believe that what others who have replied mean is that doing literally
what you asked about is considered bad Perl practice; see

perldoc -q "variable name"

There are other approaches available, without a need to use symrefs. See
Jürgen's reply.
 
J

J. Gleixner

cartercc said:
Okay, I'm confused, and I don't mind admitting it. (sorry about that)

In my little app, I've reached a point where the sheer volume of
scalar values has become burdensome. I don't know whether I really
need a hash or something else. I can print out the values of my
variables with no problem. The problem is that some of the variables
have similar values and I need to distinguish them, e.g., $password1,
$password2, $password3.

I'd suggest using more meaningful variable names.
Maybe I'm approaching this in the wrong way, and to be honest, I
haven't given it a lot of thought. I have an array, which I have been
populating manually, which consists of the variable names, and I have
been using this array to print out the values of the variables. This
array looks like either one of these two examples:

my @vars = qw(name,address,city,state,zip);
my @vars = qw($name,$address,$city,$state,$zip);

Really? Take a look at what's in @vars after those statements.
I find that I can print either the (1) variable names, or (2) the
variable values -- but not both. What I would really like to do is
automate a print to console a list that looks like this:

name => John Doe
pw1 => qwerty
pw2 => qwertx
#pw2 should match pw1
email => some(at)domain(dot)com
#intentionally not valid, can't use a RE because of the variances of
falsifying email addresses

my %data = ( name => 'abc', address => '123 abc', city => 'Some city' );
for my $k ( keys %data )
{
print "$k => $data{$k}\n";
}

If you want the keys in a particular order:

my @keys = qw(name address city);
for my $k ( @keys ) { ... }

I might add that in Lisp I can do this without a problem, by printing
the symbol and then the value of the symbol. I ought to be able to do
this easily in Perl, but I can't. I'm willing to take the hit for my
confusion, or my ignorance.

Take a peek at: perldoc perldsc
 
C

Charlton Wilbur

cc> The problem is that some of the variables have similar values
cc> and I need to distinguish them, e.g., $password1, $password2,
cc> $password3.

Any time you have variables that end in numbers, like those, it's a sign
that what you really wanted was an array.

cc> Maybe I'm approaching this in the wrong way, and to be honest, I
cc> haven't given it a lot of thought.

You will save yourself a great deal of time and frustration if you think
*first* and code *second*.

cc> my @vars = qw(name,address,city,state,zip); my @vars =
cc> qw($name,$address,$city,$state,$zip);

my %var;
my $var{name} = $name;
my $var{address} = $address;

and so on.

You may make things easier on yourself by dispensing with $name,
$address, etc., and just using $var{name}, $var{address} throughout.

cc> I might add that in Lisp I can do this without a problem, by
cc> printing the symbol and then the value of the symbol.

If you want Lisp, you know where to find it. This is Perl. You do what
you want by printing the key and then the associated value.

Charlton
 
J

Jürgen Exner

cartercc said:
In my little app, I've reached a point where the sheer volume of
scalar values has become burdensome.

That is almost always a sure sign, that you are using a poor design for
your data structure.
I don't know whether I really
need a hash or something else. I can print out the values of my
variables with no problem. The problem is that some of the variables
have similar values and I need to distinguish them, e.g., $password1,
$password2, $password3.

YIKES! That hurts.
Names like that are a very strong indication that an array would have
been a better choice:
$password[1];
$password[2];
$password[3];

Or often maybe instead of an index a more identifying name, i.e. a hash
with
$password{local};
$password{server};
$password{web};
Maybe I'm approaching this in the wrong way, and to be honest, I
haven't given it a lot of thought.

Yeah, most people underestimate the benefits of a carefully thought out
datastructure as well as the pain of a randomly created one.
I have an array, which I have been
populating manually, which consists of the variable names, and I have
been using this array to print out the values of the variables. This
array looks like either one of these two examples:

my @vars = qw(name,address,city,state,zip);
my @vars = qw($name,$address,$city,$state,$zip);
I find that I can print either the (1) variable names, or (2) the
variable values -- but not both. What I would really like to do is
automate a print to console a list that looks like this:

What is so difficult about creating a hash with the elements
$myhash{name}, $myhash{address}, $myhash{city}, ....
instead of the individual variables $name,$address,$city, ...?
name => John Doe
pw1 => qwerty
pw2 => qwertx
email => some(at)domain(dot)com

for (qw/name pw1 pw2 email/) {
print "$_=>$myhash{$_}\n";
}
I might add that in Lisp I can do this without a problem, by printing
the symbol and then the value of the symbol. I ought to be able to do
this easily in Perl, but I can't. I'm willing to take the hit for my
confusion, or my ignorance.

To jump the boundary between code and data in Perl you can use eval().
But it has it's own set of potential risks. After all there is a very
good reason why modern programming languages made a clear distinction
between code and data and don't mingle them as in LISP.

jue
 
T

Tad J McClellan

Charlton Wilbur said:
You will save yourself a great deal of time and frustration if you think
*first* and code *second*.


And all the congregation said "Amen"!


I started my professional career as an EE. I'd taken just enough
programming courses to be dangerous.

I eventually noticed that most of my (home) programming projects
would get to 80-90% complete, and then stall out, never to be completed.

After doing that enough times (I'm a slow learner), I eventually
realized that I was not doing it right...

.... I went back to school for a Software Engineering degree.

:)


Giving careful thought to algorithms, data structures, modularity, etc
*before* starting coding may seem "wasteful" in your rush to
"get the job done", but if you can muster the discipline to do so,
your software developments will take *less* time overall.
 
F

Frank Seitz

cartercc said:
What I need is a way to get at the NAME of a variable as well as a
value.

AFAIK it's not possible in Perl to get the name of a lexical (my) variable.

Frank
 
C

cartercc

Given a list of scalars, such as:
With the objective of producing output like this:
<output>
Variable names and values
 * name => John Smith
 * address => 1234 Easy Street
 * city => Paradise
...
</output>

Guys, this is what I did. I added this subroutine to each of my
modules and added the function call to the top of each file. It works
and has proven to be very useful today, telling me which variables
have been declared but not assigned a value, and the values of those
that have them.

One of the problems is that this 'little app' did indeed start off
little, with about 50 LOC and about ten variables, but grew
incrementally to seven modules, about a hundred variables, and several
KLOCs. I just couldn't face changing the data structures or changing
the names of the variables, and besides, I had developed a semi-
automated process using REs to populate the variable arrays.

Here's the code I used for validating my solution:

my $name = 'John Smith';
my $address = '1234 Easy Street';
my $city = 'Paradise';
my $state;
my $zip;
my $email;
my @scalar_names = qw(name address city state zip email);

foreach my $element (@scalar_names)
{
my $varval = '$'.$element;
print " * $element => ", eval $varval, "\n";
}
 
C

Charlton Wilbur

cc> One of the problems is that this 'little app' did indeed start
cc> off little, with about 50 LOC and about ten variables, but grew
cc> incrementally to seven modules, about a hundred variables, and
cc> several KLOCs. I just couldn't face changing the data structures
cc> or changing the names of the variables, and besides, I had
cc> developed a semi- automated process using REs to populate the
cc> variable arrays.

The sooner you face this pain, the better off you will be. Your mess of
a "solution" is going to cause you more trouble overall than biting the
bullet and actually fixing the problem would have.

There's a concept called "design debt." It's what you accrue when you
do something in a quick and dirty way instead of a clean, sensible way.
You pay interest on it when you add new features, because you have to do
more work to get the new features to work on top of a kludgy base. If
you keep on doing kludgy workarounds instead of fixing the problem,
eventually you'll be so swamped that you spend all your time keeping up
with the bad design decisions you made.

Just as when you max out your credit cards and get three payday loans
to pay your living expenses, all of your income starts going to pay
interest. The smart thing to do is to stop taking out new loans -- to
stop adding new workarounds for your earlier bad design decisions -- and
to accept the pain of not having any money while you pay off your debts.

You've had this explained to you at least twice so far in this group,
and it does not seem to have sunk in yet. Perhaps the next time you
have a crisis programming experience, you'll reflect on this and the
light bulb will go on. They say the third time is the charm, after all.

Charlton
 
C

cartercc

The sooner you face this pain, the better off you will be.  Your mess of
a "solution" is going to cause you more trouble overall than biting the
bullet and actually fixing the problem would have.

This didn't start out like this. It started out as a quick and dirty
little solution to a little problem. It was a database problem and the
purpose was to clean up some data, and it was MY automation. When some
other people saw what a good thing it was, they went to my supervisor,
and my supervisor came to me, and over a period of time it just grew,
without any thought given to design and with no planning whatsoever.
There's a concept called "design debt."  It's what you accrue when you
do something in a quick and dirty way instead of a clean, sensible way.
You pay interest on it when you add new features, because you have to do
more work to get the new features to work on top of a kludgy base.  If
you keep on doing kludgy workarounds instead of fixing the problem,
eventually you'll be so swamped that you spend all your time keeping up
with the bad design decisions you made.  

It's kind of hard to do when you explain this to my boss (which I did)
and ask for some time to redesign the whole thing from top to bottom
and do it right (which I did) and be told that it wasn't important
enough to do but to leave it alone. Unfortunately, the people I have
to work with aren't developers or designers and think that writing a
'little app' is more or less the same as writing up a PowerPoint for a
presentation. I was told this just a few days ago by someone WHO
KNOWS!
Just as when you max out your credit cards and get three payday loans
to pay your living expenses, all of your income starts going to pay
interest.  The smart thing to do is to stop taking out new loans -- to
stop adding new workarounds for your earlier bad design decisions -- and
to accept the pain of not having any money while you pay off your debts.

I agree with 100%. Most of what I do is write scripts less than 50
lines, or between 50 and 100 lines, for my own purpose, and I write
these on the fly. Yeah, they are pretty crappy, but I can bang them
out in less than half an hour and it saves me hours of work. (I deal
with big data files, tens of thousands of records, and the norm before
I can to work here was to use Excel to manually manipulate the data.
Sometimes this can take a couple of days and the error rate is pretty
high.) There just isn't any percentage in spending several hours
designing something I can be through with in an hour from start to
finish.
You've had this explained to you at least twice so far in this group,
and it does not seem to have sunk in yet.  Perhaps the next time you
have a crisis programming experience, you'll reflect on this and the
light bulb will go on.  They say the third time is the charm, after all..

Come talk to my boss, and his boss. I do my work on schedule and under
budget. My crisis experiences come from others when they come to me to
bail them out on a project that's already late and over budget, or to
fill in for someone who left yesterday for a two week vacation.

If I were a prophet and could foretell the monster around the corner,
I'd be all set. Do you have any advice on how to do this?

CC
 
C

cartercc

I started my professional career as an EE. I'd taken just enough
programming courses to be dangerous.

I started my professional career as an attorney, and practiced law for
17 years before transitioning into IT. As an attorney, if you don't
plan your work, you will get eaten alive. I've been on both sides of
that equation, both eating and being eaten.
After doing that enough times (I'm a slow learner), I eventually
realized that I was not doing it right...

I, too, am a slow learner. I'm a bright guy, but it takes a long time
before something sinks in.
... I went back to school for a Software Engineering degree.
Likewise.


:)


Giving careful thought to algorithms, data structures, modularity, etc
*before* starting coding may seem "wasteful" in your rush to
"get the job done", but if you can muster the discipline to do so,
your software developments will take *less* time overall.

FWIW, this is my take.

(1) Make sure you have clear and measurable requirements. This is
difficult when the user doesn't know what he wants, but in my
experience, the biggest problems by far are caused by ambiguous or
unclear requirements.

(2) Plan and if possible write your tests BEFORE you start coding. I
learned this playing with Java, and when I can make my own schedule, I
write the tests before I write the code -- nothing fancy, just some
function calls with varied data and an output of the results. When my
tests produce the expected output, I can at least enjoy the illusion
of success if not the reality.

(3) Read the code. Read it line by line, carefully and thoroughly. I
frequently print out a hard copy of something I'm working on and take
it home to read through. I also like to read through it with another
person, one driving and the other navigating. It's surprising how many
mistakes you find simply by reading the code.

In the real world, you have to deal with unclear (or unknown!)
requirements, lack of time for proper testing, and no time to walk
through the code, but in my experience I have found that following
these three practices helps me create a little order out of chaos.

CC
 

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,009
Latest member
GidgetGamb

Latest Threads

Top