access to variable names inside subprocedure

Discussion in 'Perl Misc' started by ccc31807, Feb 29, 2012.

  1. ccc31807

    ccc31807 Guest

    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.
    ccc31807, Feb 29, 2012
    #1
    1. Advertising

  2. ccc31807

    J. Gleixner Guest

    On 02/29/12 10:35, ccc31807 wrote:
    > 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.
    J. Gleixner, Feb 29, 2012
    #2
    1. Advertising

  3. ccc31807

    ccc31807 Guest

    On Feb 29, 12:36 pm, Kiuhnm <kiuhnm03.4t.yahoo.it> wrote:
    > 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.
    ccc31807, Feb 29, 2012
    #3
  4. ccc31807

    ccc31807 Guest

    On Feb 29, 12:44 pm, "J. Gleixner" <glex_no-s...@qwest-spam-
    no.invalid> wrote:
    > '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.
    ccc31807, Feb 29, 2012
    #4
  5. ccc31807

    ccc31807 Guest

    On Feb 29, 4:45 pm, Ben Morrow <> wrote:
    > 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.
    ccc31807, Feb 29, 2012
    #5
  6. ccc31807 <> writes:

    > On Feb 29, 12:44 pm, "J. Gleixner" <glex_no-s...@qwest-spam-
    > no.invalid> wrote:
    >> '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.
    >

    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
    --
    "We will need a longer wall when the revolution comes."
    --- AJS, quoting an uncertain source.
    Mart van de Wege, Mar 1, 2012
    #6
  7. ccc31807

    ccc31807 Guest

    On Feb 29, 6:23 pm, Ben Morrow <> wrote:
    >     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.
    ccc31807, Mar 1, 2012
    #7
  8. ccc31807

    ccc31807 Guest

    On Mar 1, 3:38 pm, Ben Morrow <> wrote:
    > 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.
    ccc31807, Mar 2, 2012
    #8
  9. ccc31807

    Dr.Ruud Guest

    On 2012-03-05 11:54, Kiuhnm wrote:

    > Another thing: try Haskell instead. It's much less lispy.


    But check out clojure too. Successful example: cascalog.

    --
    Ruud
    Dr.Ruud, Mar 5, 2012
    #9
  10. ccc31807

    ccc31807 Guest

    On Mar 5, 7:17 am, "Dr.Ruud" <> wrote:
    > On 2012-03-05 11:54, Kiuhnm wrote:
    >
    > > Another thing: try Haskell instead. It's much less lispy.

    >
    > But check out clojure too. Successful example: cascalog.
    >
    > --
    > Ruud


    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.
    ccc31807, Mar 5, 2012
    #10
  11. >>>>> "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


    --
    Charlton Wilbur
    Charlton Wilbur, Mar 6, 2012
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Nathan Sokalski

    Subprocedure for Oracle's SET DEFINE OFF command

    Nathan Sokalski, Nov 10, 2005, in forum: ASP .Net
    Replies:
    3
    Views:
    8,089
    =?Utf-8?B?U2ltb24=?=
    Nov 11, 2005
  2. wanwan
    Replies:
    3
    Views:
    413
    Alex Martelli
    Oct 14, 2005
  3. Richard Molgner

    VHDL subprocedure call

    Richard Molgner, Jan 18, 2011, in forum: VHDL
    Replies:
    4
    Views:
    1,291
    Paul Uiterlinden
    Jan 18, 2011
  4. Nathan Sokalski

    Subprocedure for Oracle's SET DEFINE OFF command

    Nathan Sokalski, Nov 10, 2005, in forum: ASP .Net Datagrid Control
    Replies:
    3
    Views:
    158
    Simon
    Nov 11, 2005
  5. steve
    Replies:
    2
    Views:
    121
    steve
    Aug 16, 2005
Loading...

Share This Page