access to variable names inside subprocedure

C

ccc31807

Question: I would like to access the string value of the variable
names passed as arguments to a sub inside the sub.

The following stores a hash in a file named like
'HASH(0xdeadbeef).dat' but I would like to store the hash in a file
named like 'hashref1.dat'.

use Storable;
my $hashref1 = retrieve('hashref1.dat');
my $hashref2 = retrieve('hashref2.dat');
my $hashref3 = retrieve('hashref3.dat');
# extensive processing on $hashref1, $hashref2, and $hashref3
# ... then
save_hashes($hashref1, $hashref2, $hashref3);
exit(0);

sub save_hashes
{
foreach my $hashref (@_)
{
my $filename = sprintf("%s.dat", $hashref);
store($hashref, $filename);
}
}


I can do it by passing the arguments twice, once as a string and the
second time as a variable, like this:

save_hashes($hashref1,.'hashref1', $hashref2, .'hashref1',
$hashref3.'hashref1', );

and then in the sub use the even arguments as the hashref and the odd
arguments as the filename, but this strikes me as a problem that ought
not to be a problem.

Thanks, CC.
 
J

J. Gleixner

Question: I would like to access the string value of the variable
names passed as arguments to a sub inside the sub.

The following stores a hash in a file named like
'HASH(0xdeadbeef).dat' but I would like to store the hash in a file
named like 'hashref1.dat'.

That's saying that the data is a hash, to see the data:

use Data::Dumper;
use Storable;
my $hashref1 = retrieve('hashref1.dat');
my $hashref2 = retrieve('hashref2.dat');
my $hashref3 = retrieve('hashref3.dat');
# extensive processing on $hashref1, $hashref2, and $hashref3
# ... then
save_hashes($hashref1, $hashref2, $hashref3);
exit(0);

sub save_hashes
{
foreach my $hashref (@_)
{
my $filename = sprintf("%s.dat", $hashref);
store($hashref, $filename);
}
}


I can do it by passing the arguments twice, once as a string and the
second time as a variable, like this:

save_hashes($hashref1,.'hashref1', $hashref2, .'hashref1',
$hashref3.'hashref1', );

and then in the sub use the even arguments as the hashref and the odd
arguments as the filename, but this strikes me as a problem that ought
not to be a problem.

save_hashes( hashref1 => $hashref1, etc. )
or
save_hashes( 'hashref1', $hashref1, etc. )

sub save_hashes
{
my %data = @_;

for my $fname ( keys %data )
{
etc...
}
}

'hashref1' is not a terribly helpful filename.

If 'hashref1' is in the data, then pass $hashref1 and pull the filename
from the data.
 
C

ccc31807

The problem is that a variable doesn't know its name. You use its name
*in the code* to refer to it. As far as I know, that name is lost at
runtime. Here's a workaround:

--->
...
save_hashes(qw/hashref1 hashref2 hashref3/);

sub save_hashes
{
   foreach my $hashName (@_)
   {
     my $filename = sprintf("%s.dat", $hashName);
     store(eval "\$$hashName", $filename);
   }}

<---

Can you see why it works?

Yes. The value of each element is a string, to which sprintf() appends
a '.dat'.

If the value of each element is a string, then to fool Perl into
thinking it's a scalar, you need to prepend the '$' sigil. But then
you need to eval() the string to get at the value.

I'm munging large data files to produce several different reports with
several different pages each. I don't really know the content of the
data, or the number of reports, or the number of pages, until I
process the data, and I have to remember each days data because the
files overwrite each day.

I can dynamically create the data structures, and dynamically populate
them with the appropriate values, but have spent most of the morning
trying to come up with a dynamic way to save the data structures.

I very much appreciate the help. Sometimes we are so wedded to a
particular paradigm that we cannot make the small shift that makes the
difference between success and failure. Yes, I can see how to move
from strings to variable names and values, and as you said, it appears
to be impossible to move from values to the names we have given them,
particularly when the values are a memory location.

Thanks, CC.
 
C

ccc31807

'hashref1' is not a terribly helpful filename.

If 'hashref1' is in the data, then pass $hashref1 and pull the filename
from the data.

You are right ... I'm actually using long English names for the
hashes, like $daily_site_count_by_type, and $daily_counts_by_status. I
can generate these filenames from the data as I pass through it. Other
than that, I don't care what the names are.

Data::Dumper isn't a solution for me except just to look at the
structure of the data structure. I don't care what the names are, as
the names are in the data. I spit out the reports doing something like
this:

open OUT, '>', $dynamically_generated_file_name or die $!;
foreach my $k1 (sort keys %{$hashref})
{ foreach my $k2 (sort keys %{$hashref->{$k1}})
{ foreach my $k3 (sort keys %{$hashref->{$k10{$k2}}})
{ print OUT qq("$k1","$k2","$k3","$hashref->{$k1}{$k2}
{$k3}"\n); } } }
close OUT;

I don't pretend to be expert at this, but it works and does what I
need, and the users that consume the output are happy -- so I guess I
am too.

CC.
 
C

ccc31807

Come on, you've been here long enough to know that.

Maybe, but we all tend to become more narrow in the course of time. I
consider myself moderately competent in what I do, which is a
combination of web applications, database applications, and data
munging, but I've never run across PadWalker.

I'm not actually a programmer, much less a Perl expert. I use Perl to
perform my job functions, and don't spend much time writing code.
If you insist: PadWalker.

Thanks for the tip. I have glanced through it, and see how it could be
useful. I'm going to play with it some.

CC.
 
M

Mart van de Wege

ccc31807 said:
You are right ... I'm actually using long English names for the
hashes, like $daily_site_count_by_type, and $daily_counts_by_status. I
can generate these filenames from the data as I pass through it. Other
than that, I don't care what the names are.
If you're constructing your names on the fly, why don't you then just
put your data in a hash, using the names as a key?

The description of your problem should cry out 'hash!' to any competent
programmer.

Mart
 
C

ccc31807

    my %Data;

    for (qw/fileone filetwo/) {
        read_file $_;
        write_file $_;
    }

    sub read_file {
        my ($file) = @_;
        open my $F, "<", $file or die ...;
        $Data{$file} = [ <$F> ];
    }

    sub write_file {
        my ($file) = @_;
        open my $F, ">", $file or die ...;
        for (@{ $Data{$file} }) {
            print $F $_;
        }
    }

Okay, some thoughts about programming paradigms.

When I learned C, I learned to write a main function, which called
other functions and then exited.

When I learned Java, I learned to decompose my problem domain into
classes. Unfortunately, I had a couple of OO development classes
before I actually learned Java, and it didn't make much since to me,
but when I started writing Java for real, I wrote it bottom up, tests
first, and liked it very much.

In the past couple of years, I've begun writing Lisp, and have
acquired a taste for the functional style. Whenever I have the energy,
I try to write my Perl scripts in a more-or-less functional style, but
it takes a lot of energy and I often get lazy.

My Perl scripts tend to start off as pseudo code, and I implement the
script incrementally, converting the pseudo code to real code piece by
piece. This has more in common with C than with the others, but I
don't think in terms of one MAIN function, but a number of MAIN
functions that I call sequentially, much like a batch file.

I see where you are going -- wrapping the program in one gigantic
foreach loop. Conceptually, the idea is new to me, and I'm not sure
how to deal with it, or if I can deal with it in the light of my
previous experience. It strikes me as being more closely related to
the functional style than the others, and if I were writing in Lisp, I
can visualize how the program would appear visually (and I don't mean
like fingernail clippings mixed with oatmeal).

Thoughts?

CC.
 
C

ccc31807

but I can't see something like those first three lines without wanting
to turn it into a loop.

In my current state of just-above-minimal competence, I try to
abstract the logic. I bought a copy of 'Higher Order Perl' a number of
years ago, and quite frankly found it beyond me at that time. After
having studied through about eight Lisp books, it makes more sense,
but it's still hard work.

Over this period of time, I have had interesting and sometimes
acrimonious discussions with others, in person and on line, about the
fundamental distinction between code and data. I wrote a pretty big
web app a couple of years ago with the intention of processing code as
if it were data, and because of the way HTML is generated was able to
programatically modify code to generate dynamic output based on the
input parameters. However, I'm still a novice at applying these
lessons in my day job. For what I do, this is often overkill, anyway.

I appreciate your comments.

CC.
 
C

ccc31807

But check out clojure too. Successful example: cascalog.

I have looked at Clojure, Haskell, and (more than just a look) Prolog.

I divide languages into three kinds: those you need to get your work
done, those you would like to study for some particular reason, and
'hobby' languages -- those you would like to study for no particular
reason.

In the first group, I have quite a list, Perl, Java, JavaScript, SQL,
and so on. It's pretty much all I can do to keep these in mind enough
to use them.

In the second group, I would include R (generating graphics),
Objective-C (mobile apps), PowerShell, and several others.

In the third group, I would include Lisp and Erlang.

Unfortunately, the more time you spend with the first group, the less
time you have to spend with the others. And vice versa.

Still, I fully agree with the guy who said (Eric Raymond? Richard
Stallman?) that you should learn one new language every year. I find
that the idioms of different languages can be profitably applied with
your workhorse language.

CC.
 
C

Charlton Wilbur

"KKiuhnm" == Kiuhnm <kiuhnm03.4t.yahoo.it> writes:

KKiuhnm> You should read the book "Concepts, Techniques, and Models
KKiuhnm> of Computer Programming".

Or possibly _The Structure and Interpretation of Computer Programs_.

When I was an undergraduate, the requirement for a course in writing
compilers was under heavy attack because, hey, everyone knew that
Borland and Microsoft had the market cornered and who really needs to
write a compiler from scratch? Way to miss the point, guys.


Charlton
 

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,014
Latest member
BiancaFix3

Latest Threads

Top