Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Perl Warnings...

by Rodster001 (Pilgrim)
on Jan 27, 2009 at 17:10 UTC ( [id://739256]=perlquestion: print w/replies, xml ) Need Help??

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

Hello There,

So, I might get burned for asking this, but it has been on my mind and I want to really understand.

I tend to avoid using -w for one reason, it complains about a habit I have. I like to do this:

my $query = "SELECT something FROM somewhere"; my $sth = $dbh->prepare($query); my $rv = $sth->execute; my $first_result = $sth->fetchrow_hashref; my $query = "SELECT somethingelse FROM somewhereelse"; my $sth = $dbh->prepare($query); my $rv = $sth->execute; my $second_result = $sth->fetchrow_hashref; ... then do something with $first_result and $second_result
Is this really *that* bad? If so why? And how would you rewrite the same block? Just omit the my's or use different variable names?

Also, if I "reuse" $query, $sth, $rv several times (as in the above example) what is actually happening in memory?

Thanks for your insight and helping me be a better Perl programmer :)

Replies are listed 'Best First'.
Re: Perl Warnings...
by ikegami (Patriarch) on Jan 27, 2009 at 17:23 UTC

    You could do

    my ($query, $sth, $rv); $query = ...; $sth = ...; $rv = ...; ... $query = ...; $sth = ...; $rv = ...; ...

    I did that in a .t file recently. The complexity of the alternative was immense.

    Of course, in your specific case, you could write

    my $first_result = $dbh->selectrow_hashref( "SELECT something FROM somewhere" ); my $second_result = $dbh->selectrow_hashref( "SELECT somethingelse FROM somewhereelse" );

    what is actually happening in memory

    Two different variables are created, as if they had different names.

    $ perl -MO=Concise -e'my $x; my $x; my $y;' 2>&1 | grep padsv 3 <0> padsv[$x:1,4] vM/LVINTRO ->4 5 <0> padsv[$x:2,4] vM/LVINTRO ->6 7 <0> padsv[$y:3,4] vM/LVINTRO ->8
Re: Perl Warnings...
by moritz (Cardinal) on Jan 27, 2009 at 17:23 UTC
    If you repeat this pattern, it tells you one things: You should write it into a subroutine.
    sub first_row { my ($dbh, $query, @args) = @_ my $sth = $dbh->prepare($query); my $rv = $sth->execute(@args); my $first_row = $sth->fetchrow_hashref; return ($rv, $first_row); } my ($success, $first_result) = first_row($dbh, "SELECT ... "); # and if you don't want to actually check success my $second_result = first_row(...);

    (Update: or as ikegami points out, just use $dbh->fetchrow_hashref($query) in the first place.)

    (Even more elegant if you don't check for $rv, but instead die on errors, and catch them where appropriate).

    If you insist on your current pattern, you can use warnings, but disable single warnings that bother you - read perllexwarn for more details. Or simply put a block around the declarations.

Re: Perl Warnings...
by matija (Priest) on Jan 27, 2009 at 18:49 UTC

    I like to run with warnings on. But sometimes I don't see them, like for instance, when I was editing a fairly substantial mod_perl script, which printed a whole bunch of stuff to the log, hiding any warnings in the scrollback.

    Because I didn't see the warnings, I spent some frustrating time trying to discover what is going on in code that went something like this:

    my $some_index = 0; while ($thing = $thingies->next) { my $some_index = $thing->something_or_other; last if (test_for_fitness($some_index)); }

    Yeah, I had originally declared the variable in the loop, but then I realized I would need it outside the loop, moved the declaration out, and forgot to remove the inner my. The loop worked perfectly, but the moment the program left the loop, $some_index was restored to 0 again.

    And that is why I like perl warning me about a re-used my declaration.

    I know it's not what you asked, just some food for thought

Re: Perl Warnings...
by JadeNB (Chaplain) on Jan 27, 2009 at 22:09 UTC
    Is this really *that* bad? If so why?

    Short version: I think it's clear that

    my $x = 'string'; my $x = 17;
    is undesirable, and I think that the warnings are more to prevent this sort of behaviour than your innocuous example.

    Long version: It's nice to have some imperative semblance of referential transparency—when I see a variable, I like to know what it means (even if I can't quite translate

    my $x = 5; $x += 1; print $x;
    to
    my $x = 5; $x += 1; print 5;
    ). If you use my twice, you're explicitly saying “This isn't close enough to the old variable that I can view the re-assignment as updating; I want to view it as an entirely new variable.” Thus, if I'm skimming the code, I have to keep careful track of declarations to be able to tell whether a given occurrence of $query refers to the original kind of query, or the new one.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (5)
As of 2024-04-24 00:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found