Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re: I have a perl snippet. And I need help understanding it. Can you help answer these questions.

by davido (Cardinal)
on Nov 07, 2011 at 22:18 UTC ( [id://936595]=note: print w/replies, xml ) Need Help??


in reply to I have a perl snippet. And I need help understanding it. Can you help answer these questions.

Here are some pointers:

  1. I didn't see a question 1.
  2. my $numApplepackets= $obj->{records}->{0AA0}->{totalRecords}; is accessing the scalar value held in a hash ref that is nested several levels deep. The entire structure is held in the object reference named $obj. Breaking encapsulization like that isn't a very good object interface for the Fruits class though.
  3. With $fruitobj = $obj->parse0FFA($BananaNum); the Fruits::parse0FFA() function is being used as an object method for the class Fruits's object held as a blessed reference in $obj. The -> operator is dereferencing $obj to access the parse0FFA() sub from package Fruits.
  4. $obj->{$j}->{rxABC} > -100 You're testing whether the value held in $obj->{$j}->{rxABC} is greater than -100.
  5. shift is documented in shift. It shifts a value off of the array passed to it as a parameter argument. If there's no parameter, it shifts off of @_, which is the param list from the sub that it's being invoked within (or @ARGV outside of subs).
  6. my $size = $self->{records}->{0FFA}->{totalRecords} stores a value in $size that is held in the object structure referred to by $self.
  7. $obj->{timestamp} is being assigned a value that is held in $self->{records}->{0FFA}->{$i}->{_timestamp}
  8. ( $tmp, $obj->{$j}->{txABC}, .... ) are being assigned the list of items that are unpacked by unpack.

It probably still doesn't make a ton of sense yet. You're going to need to read the following: shift, unpack, pack, perlpacktut, perlreftut, perldsc, and perlobj, at minimum, before it's going to start becoming clearer. That's several hours of reading material, which will probably need to be broken up into a couple of days. The information is quite dense, and may or may not help the light bulb of understanding to flick on.

A much gentler approach is available: It might be a really good idea to rush over to your local bookstore (or oreilly.com or amazon.com) and pick up a copy of Learning Perl (O'Reilly) and Intermediate Perl (O'Reilly). You'll spend a week or so with each book, and suddenly find yourself able to understand the code posted, as well as a great many other things Perl related.

ps. ikegami is right. StackOverflow is fine for questions that can be answered without a lot of deeper discussion. StackOverflow is not well suited to threaded discussions. When it comes to coaching a person along the learning process, the PerlMonks Monastery is a more flexible environment.


Dave

  • Comment on Re: I have a perl snippet. And I need help understanding it. Can you help answer these questions.
  • Select or Download Code

Replies are listed 'Best First'.
Re^2: I have a perl snippet. And I need help understanding it. Can you help answer these questions.
by aaron_baugher (Curate) on Nov 07, 2011 at 23:28 UTC

    Good answers to the specific questions. I just want to chime in and agree that this is pretty dense code to try to learn from. It's got unpack, which is fairly complex in itself, plus OO (and an object structure several levels deep), subroutine argument handling, and more. On top of that, it's not very Perlish code. If you're learning Perl, you don't want to learn to use C-style for loops like the first line below when you can do the second one:

    for( my $j=0; $j<2; $j++){ # C-style loop for my $j (0..1){ # Perl-style loop, much clearer

      hey bud. So when I replaced the for loop exactly the way you have mentioned I get the following error.

      Use of uninitialized value in numeric gt()) at logprocess.pl in line 119

      which is that loops line number where the for loop is at.

      Also, can you please teach me how to print the value inside of a nested nested nested hash. THis one. I want to see the value of rxABC from? $obj->{$j}->{rxABC} I tried print "Found: $$obj->{$j}->{rxABC}" and it wont work. :(

        "It depends" (as the professors in my Economics classes liked to say).

        If $obj->{$j}->{rxABC} holds a scalar value, you should be able to print it like this:

        print "Found: $obj->{$j}->{rxABC}\n";

        That reminds me. Anytime you have a -> between two brackets you can omit it. So that becomes:

        print "Found: $obj->{$j}{rxABC}\n";

        On the other hand, if $obj->.....{rxABC} holds a reference to another layer (an array ref or hash-ref, for example), you will need to deal with that layer too. Fortunately Perl can print an array in a sensible way. So let's say that {rxABC} holds an array ref like this:

        $obj->{$j}{rxABC} = ['a', 'b', 'c'];

        Then you would need to dereference that array ref to make sense of it too. Here's one way:

        print "Found: ", join( ' ', @{ $obj->{$j}{rxABC} } ), "\n";

        Or another way:

        print "Found: @{$obj->{$j}{rxABC}}\n";

        Dave

        I'm not sure what you did, because the for loop I suggested doesn't have a numeric gt() to cause that error. I meant that instead of using the C-style, three-arguments-separated-by-commas for loop, it's almost always better in Perl to do something like this:

        for my $i (0..99){ # do something with $i from 0 to 99 } # instead of this: for( my $i=0; $i<100; $i++){ # do something with $i from 0 to 99 }

        See how much cleaner the first one is? It also has the advantage of showing you exactly what number it'll start and stop on, so you don't have to remember that $i<100 means it'll stop at 99 (likely to cause off-by-one errors), or use the even uglier $i>=99 as your condition.

        There are occasions when the C-style method may make sense, like if you want to step by some number other than 1. They're just very rare. In 15 years of programming in Perl, I'm sure I could count on one hand how many times I've used it, and even those times there was probably a better way.

        Aaron B.
        My Woefully Neglected Blog, where I occasionally mention Perl.

Re^2: I have a perl snippet. And I need help understanding it. Can you help answer these questions.
by Fighter2 (Novice) on Nov 08, 2011 at 00:55 UTC

    Thank-you so much Dave! I am really grateful to you. I sort agree this is a bad way to study Perl. But then again, this is a work that fell in my lap, and they just expect me to do it ASAP whether I know Perl or not. I had to understand this code in order to make the required hacks/modifications to meet my new specs.

    I got the books you have told me to fetch from the company library :). Btw, to answer your question why is the scalar value nested in so deep, that is the way the log file is which I need to dig out the data from. It's from a Universal format for Scientific data called NetCDF unfortunately.

    For Question 3. I want to write down what I understood. I know parse0FFA is a function inside the .pm file Fruits.pm and that obj is a reference to that pm file and by $obj->parse0FFA() I am able to fetch a sub from that pm file. Correct me if I am wrong thus far.

    Now, you used a term 'deference' which I didn't understand in your answer. Here. Lets try again. Are you telling me sir that in

    $fruitobj=$obj->parse0FFA($BananaNum);

    the number of Bananapackets is given to the subroutine parse0FFA() which is in the pm file and the result (or return) of that function is now stored in the scalar variable $fruitobj. And that $obj is only a reference (what we call objects in C or C++) to the function parse0FFA ? Is that a correct understanding. I think I am getting the hang of Perl now. At-least syntax and coding style. And finally for Q7. I fully understand your answer. Thankyou. Please read your answer again. Now, I have a question. Is the $obj->{timestamp} the reference $obj from the logprocess.pl file or is this a local reference $obj from the .pm file? I think it's the latter, but just wanted to check. Thanks again!

      The word was "dereference," which means "to get at the thing pointed to by the reference." If you're familiar with C, references are a lot like pointers, except that you can't do arithmetic on them; they're essentially read-only. So for instance:

      my @array = qw(a b c d); # create an array print $array[2]; # prints 'c' my $arrayref = \@array; # create a reference to the array print $arrayref->[2]; # prints 'c'. The arrow is required when # getting an element of an array or hash # pointed to by a reference my @newarray = @{$arrayref}; # dereference $arrayref to get at the # array it points to, and # copy it to @newarray print $newarray[2]; # prints 'c'

      Aaron B.
      My Woefully Neglected Blog, where I occasionally mention Perl.

Re^2: I have a perl snippet. And I need help understanding it. Can you help answer these questions.
by Fighter2 (Novice) on Nov 08, 2011 at 01:09 UTC
    I also now notice that 'new' is not a Perl keyword and it was another subroutine defined (and derived) from the pm file which I fail to notice and see. I should have realized that all Perl keywords are highlighted in blue color in my editor(Notepad++). btw, in case anyone's confused,new is a log parser, it takes a file and a filterlist and puts all the values into a variable.

      Correct: new() is not a built-in. I assumed that it existed in the module, and that you just didn't include that portion of the code. Otherwise, the code you posted wouldn't have made much sense. new() is the "constructor" for the object, and it has to be written by the module's author. There's nothing special about the name new() either. DBI uses connect(), and other modules use other names that make sense as constructors for their respective classes. However, unless you have a good reason, new() is usually the most predictable and sensible name to use.

      One thing: The code you posted is really a bad example to learn from. It's considered a bad practice to deal with the object's internals directly from outside the object, and that's what the example code is doing. The class's author should be free to implement the object however he wants internally, and expose its internals through well-defined accessors in a way that abstracts away the details of implementation. ...that's at least my opinion about what code I saw posted. But I understand you've got the hand of cards that some previous developer handed you. Just be aware that when it comes time to actually learn how to write OO in Perl, Intermediate Perl is an excellent resource. And Modern Perl (by chromatic) will get you started with Moose (Perl's newer, more palatable object system).


      Dave

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://936595]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (4)
As of 2024-04-19 04:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found