Zo has asked for the wisdom of the Perl Monks concerning the following question:

This node falls below the community's threshold of quality. You may see it by logging in.

Replies are listed 'Best First'.
Re: Is this a hash? or what?
by swiftone (Curate) on Sep 26, 2000 at 00:02 UTC
    Please put <CODE> </CODE> tags around your code, it keeps it from wrapping messily,and renders Perl code HTML-safe.
    ###### else { print EBSDET parser ($bai{$ocab}{d16}[$1]{text_full}, (27- $bai{$ocab}{d16}[$1]{n2_offset}), 27,"\;",12); } ######
    Okay, let's take this apart piece by piece. First there's a call to print Easy enough. The EBDSET is (presumably) an open filehandle, which means that print will send the rest of the line to that file. parser appears to be a subroutine call. Somewhere else in the program you should find sub parser that defines what parser does. In particular, the arguments that are passed to parser (inside the ()'s) will show up in the @_ array.

    Next, we have the arguments to parser(). There are 5.

    1. $bai{$ocab}{d16}[$1]{text_full}
    2. 27 - $bai{$ocab}{d16}[$1]{n2_offset}
    3. 27
    4. "\;"
    5. 12
    I think the trouble for you is the syntax found in #1 and #2. These are references, documented in perlref. Basically this is $bai{$ocab}->{d16}->[$1]->{text_full}, or more verbosely: $bai is a hash. The value stored at $bai{$ocab} is a reference to a hash. The value stored at key d16 of that hash is an array reference. The value stored at index $1 of that array is a hash reference. You are ultimately getting the value stored at key text_full of that array.

    references are a bit of an advanced concept, but basically they are a way to nest data structures (lists of lists, lists of hashes, etc)
    Update:Adam correctly points out that I'm short selling references (see below). Read the replies for more in depth coverage, but this explanation is enough for this question.

    Next:

    push(@{ $pay[($#pay + 1)] }, $pay_aba, $pay_acct);
    @pay is an array. $#pay is the index of the last element of that array (Note that since arrays normally start at 0, "index of the last element" and "size" are not the same. $#pay+1 is normally the size of the array.

    I suspect the problem here is again, references. Like I said, see perlref, but Here's the basics:

    If $foo is a reference to an array (All references are scalar values), the way to deal with the array that $foo refers to is @{$foo} So here, we see that $pay[($#pay+1)] is being treated as an array reference. I don't imagine that's good practice, as $#pay+1 should not exist on @pay (It's one past the last index). A better way to write this would be:

    push @pay, [$pay_aba, $pay_acct];
    This creates a reference to an anonymous array (consisting of $pay_aba and $pay_acct), and pushes it onto the end of @pay.

    Hope this helps, and if you're a Perl newbie, here's the tip that everyone will tell you: Have your programs use strict;, and run perl with the -w flag. You'll get sick of error messages, but you'll quickly write better code, and better understand what's going on.

      That is a very well written response. A definate ++.

      I do want to expand on the concept of references though. You said:

      references are a bit of an advanced concept, but basically they are a way to nest data structures (lists of lists, lists of hashes, etc)

      References may be a bit advanced, but not much. Any student of CS will be introduced to the concept within the first year, year and half. I think you under-sell the power of references by just saying that they are a way to nest data structures. I will attempt to explain them further here (and of course invite comments, criticisms, offers of affection, etc.).

      References
      In the realm of the land we call the computer there is no concept of language. There is no "Hello World", there is barely even a world. There are millions of digital gates where electricity either flows, or it doesn't. These are known colloquially as switches, or bits, or memory. We group together bits into nibbles, nibbles into bytes, and bytes into words for convenience and speed. Words we gather together in a carefully ordered array of memory, each byte or word is given an integer address. This memory holds everything, variables, code, everything. All machine code is in this binary language. Every instruction, every variable, and every pointer.

      "Pointer? What's a pointer?" you ask. That is a variable which contains an address in memory.

      "You mean it is an address in memory?" NO. I mean it contains an address. Memory is addressed by byte or by word. A word is usually (these days) four 8bit bytes, or 32 bits. That gives a boundry on how much virtual memory a process may use. If the addresses don't fit in a 32 bit unsigned integer, then you couldn't have pointers. So a pointer is a variable stored at some address in memory, and the value of that variable is a memory address. Got it?

      Now it gets a little more complicated. In C the programmer is responsable for allocating memory. Want to store a array of characters? Allocate enough consecutive bytes to hold the correct number of characters (plus an end marker). Want to iterate through that array? Time for memory math... pointer arithmetic. Get the address of the first char and start adding one. Perl makes it easy. Larry Wall abstracted these powerful data types because they are used so often, and because they are so easy to do wrong.

      So what is a reference Adam? You promised to explain references to us. All you've done is talk about pointers and memory and stuff.

      References are the Perl abstraction of pointers. That is not to say that references are pointers (They most certainly are not) but to say that you can usually think of them as such. A reference is basically a scalar which contains the address (sort of) to another object... that object could be anything. A hash, a scalar, an array, another reference... anything. HEY! We saw some double talk in there... what do you mean "sort of" ??? I don't want to get to far into the inner workings of Perl. I just want to demystify references a little bit. So suffice it that a reference is a pointer to an object. It knows the address of that object, but its a reference, not a pointer, so it knows a little more then just the address. And of course, that address might not make much sense to you since Perl retains control over its memory space.

      So what CAN I do with a reference? Well, you can't do pointer arithmetic with it (not a pointer... remember?) But you can de-reference it later. Or pass it to a subroutine, or store a collection of arrays in a hash by storing their references (but don't try to use references as hash keys... Perl converts them to a string for you, but won't reverse the process.)

      Surely that isn't everything? Nope. There is plenty more to know about references... like (obfuscation trick) did you know that you can symbolically reference something? (This violates strict 'refs' though)

      use strict 'vars'; use vars qw( $data $data_ref ); $data = "Just another Perl hacker\n"; # must be global $data_ref = 'data'; print $$data_ref;
      More? You want More? "Won't ask for more when he knows what's in store."* If you really want to learn more about what references are, then I recommend that you buy a copy of Advanced Perl Programming by Sriram Srinivasan (yup... O'Reilly Press) But for now I'll be happy if you at least try to use them with out fear. They are a powerful tool and a definate must have in your book of Perl skills.

      *That's from Oliver Twist for those of you who don't get out much.

        That is a very well written response. A definate ++.

        Thanks

        References are the Perl abstraction of pointers. That is not to say that references are pointers (They most certainly are not) but to say that you can usually think of them as such.

        This is a statement I hear a lot, and I just don't get it. While references certainly _ARE_ Perl's abstraction of pointers, the use of them is so different that the comparison isn't really worth making. Pointers can be manipulated, references can't. (You noted that). If I can't do pointer operations on a reference, why pull in all the pointer baggage (While learning pointers wasn't conceptually hard for me, in practice they were the hardest CS concept for me to get working)

        I think you under-sell the power of references by just saying that they are a way to nest data structures.

        Okay, guilty as charged.

        But you can de-reference it later. Or pass it to a subroutine, or store a collection of arrays in a hash by storing their references (but don't try to use references as hash keys... Perl converts them to a string for you, but won't reverse the process.)

        All true. So how is the following as a short description (basically saying what you said without bringing in pointers):

        "References are scalars that refer to a perl data structure. They can be de-referenced, which gives you the data structure. Because Perl data structures are normally "flat" (An array element or hash value can only be scalar), this allows you to creat nested data structures. Because perl subroutines are passed 1 list of parameters, it allows you to call a subroutine with multiple arrays, hashes, and even references to other subroutines. References are the backbone of modules, which change perl from a good scripting language into a powerful programming language."

      Wow!
      I only wish I could vote more than once for this response.
      Exceptionally well done.

      eclecticIO "Given the pace of technology, I propose we leave math to the machines and go play outside."
      Calvin - Homicidal Psycho Jungle Cat