Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Using "my" suppresses "Name used only once" warning?

by Wysardry (Pilgrim)
on Feb 02, 2003 at 22:33 UTC ( [id://232066]=perlquestion: print w/replies, xml ) Need Help??

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

I was under the impression that using the strict pragma and declaring variables with my was a good thing.

However, I have found that using "my" actually prevents warnings about variable names that are used only once being displayed.

Compare the following code examples:-

#!/Perl/bin/perl -w use CGI::Carp qw(fatalsToBrowser warningsToBrowser); # use strict; use warnings; print "Content-type: text/html\n\n"; warningsToBrowser(1); $blah = 1; print "No problemo\n";

The above code generates the following warning message (in an HTML comment):-

warning: Name "main::blah" used only once: possible typo at c:\test\test.pl line 7.

#!/Perl/bin/perl -w use CGI::Carp qw(fatalsToBrowser warningsToBrowser); use strict; use warnings; print "Content-type: text/html\n\n"; warningsToBrowser(1); my $blah = 1; print "No problemo\n";

The above code generates no warnings - even if I change "my $blah = 1" to just "my $blah" thereby not even giving it a value.

I realise that any real variable name typos would most likely be caught if using strict with "my" because they show up as undeclared, but how can you catch variables that are declared and not used?

Also, is there a reliable way of making a Perl CGI program run in an "ultra pedantic" mode so that errors such as using a string as a number or vice versa are caught? (The above settings don't do that.)

__________
"Every program has at least one bug and can be shortened by at least one instruction -- from which, by induction, one can deduce that every program can be reduced to one instruction which doesn't work." -- (Author Unknown)

Replies are listed 'Best First'.
Re: Using "my" suppresses "Name used only once" warning?
by Abigail-II (Bishop) on Feb 02, 2003 at 23:47 UTC
    The "used only once" warning isn't there to spot declared, but unused variables. They are harmless. The "used only once" warning is there to catch typos in variables - "use strict" won't catch typos in fully qualified variable names - which certainly can be harmfull.

    Personally I think this warning is one of the more annoying ones. It triggers to many false positives (at least, for the way I code). I hate having to use local, our, or use vars just to quiet the warning.

    I'm not sure what you mean by "using a string as a number". Scalars in Perl are both strings and numbers. But Perl does already warn you (if you have warning on) if you use a string that doesn't look like a number as an operand for an arithmetic operation.

    $ perl -we '"foo" + "bar"' Argument "bar" isn't numeric in addition (+) at -e line 1. Argument "foo" isn't numeric in addition (+) at -e line 1.

    Abigail

      I tend to want to pre-declare variables, as it's how I learnt in BASIC, C and COBOL. I also got into the habit of defining them before doing anything else.

      Obviously in large programs this can lead to some being declared but never used, or left behind when the code that uses them is removed.

      The using a string as a number thing was because I was testing what warnings were given and set a variable to 1 (numeric), concanated it with "1" with the . operand and then added a numeric number 1 to it, without getting any warnings about it.

      I know a "make your mind up about the context of $such_and_such" warning is too much to ask, but I'd have expected some sort of non-fatal complaint.

      I guess what I'm really after is a psuedo strong type casting option for variables. In other words, if I used a scalar in string context, I want to be warned if I later use it as a number (even if it looks like a number).

        I guess what I'm really after is a psuedo strong type casting option for variables. In other words, if I used a scalar in string context, I want to be warned if I later use it as a number (even if it looks like a number).

        Then you shouldn't have used Perl to begin with. This automatic casting between numbers and strings is a feature, just as it's considered a feature in C that if you divide a float by an integer, the integer is casted to a float.

        Also realize that in Perl, that any checking of the form "is this a number" has to be done at run-time (unlike the typechecking in C that can be done in compile time). You really don't want to do a check for each operation, the slowdown would be noticeable. You get the "Argument 'foo' isn't numeric" for 'free', because Perl needs to convert the string value to a numeric value, and the C library functions strto* will flag failure. You will notice that you get the warning only if Perl hasn't attempted to translate the string value to a numeric value - if Perl already did this (unsuccesfully), you don't get a warning.

        Abigail

        The using a string as a number thing was because I was testing what warnings were given and set a variable to 1 (numeric), concanated it with "1" with the . operand and then added a numeric number 1 to it, without getting any warnings about it.

        This seems reasonable to me. Just assume that any time you do math with strings, or string operations with numbers that perl silently handles the type conversions required. So the below

        >perl -e "print 1 . '1' + '.01'" 11.01
        can be implictily read as
        >perl -e "print str2num(num2str(1) . '1') + str2num('.01')"
        but is much less confusing.

        Dont knock it, eventually youll wonder why it isnt this easy in all of the other languages...

        ;-)

        --- demerphq
        my friends call me, usually because I'm late....

Re: Using "my" suppresses "Name used only once" warning?
by jepri (Parson) on Feb 03, 2003 at 00:32 UTC
    At first I thought that perl would optimise away useless declarations, but after playing with B::Deparse I discovered that perl did not do this. And then I figured out why:

    my $d; my $s = '$d=10;print $d'; eval $s;

    Naughty, but still legal. So in this case, it really is a feature, and not a bug.

    ____________________
    Jeremy
    I didn't believe in evil until I dated it.

      Good point.

      I vaguely recall of some discussion for addition of a compile time option to specify that you won't be using eval. The idea may seem appealing, but eval is eval, and s///e is eval, and there are tons of other uses for eval, and lots of modules use eval, that pretty quickly the potential optimization that might be gained by that option (at least for perl5) disappear pretty quickly (that's how I see it).


      MJD says you can't just make shit up and expect the computer to know what you mean, retardo!
      ** The Third rule of perl club is a statement of fact: pod is sexy.

        s///e is eval
        No, that would be s///ee - the right side of s///e is compiled during the inital compilation phase.

        Makeshifts last the longest.

Re: Using "my" suppresses "Name used only once" warning?
by Marza (Vicar) on Feb 02, 2003 at 23:15 UTC

    Why yes it does.

    Using the strict module forces you to declare variables lexically (using my $var) and belong to a block or file, or be declared globally.

    When it is declared to a block of code(ie sub), I guess the value of "used once" is no longer issue as the value disappears after the sub has completed.

    A global declaration well the same thing comes to play but they disappear at programs end.

    Mind you that is how I understand it. If I am wrong one of brothers will surely correct me! ;-)

      Well, I'm not really concerned if a variable is truly only used once, but more if it isn't used at all.

      Unfortunately, the act of using "my" in declaring a variable ready for use - even without setting a value - is counted as using it, which seems a little odd.

      I was hoping to be able to be warned if I'd declared a variable and then not used it for anything. This might happen if I removed a section of code, or declared a lot of variables at once in the early stages of coding, but then decided not to (or just plain forgot to) use one of them later in the development process.

      Oh, by the way, it isn't the strict pragma that's causing this - it is my (I tried this without strict, but with my).

        Oh I know that. I used the strict description as you will hear "use strict" chanted to newbies all the time. When you use strict, you have to declare the variable (ie my) which in turn causes your situation.

Re: Using "my" suppresses "Name used only once" warning?
by theorbtwo (Prior) on Feb 02, 2003 at 23:32 UTC

    If you want to make warnings fatal, try use warnings 'FATAL';, or, for specifc categories of warning, use warnings qw(FATAL numeric).

    To find where a variable is used, declared, etc, try B::Xref.

    As to the main point of your post, yeah, I think you're right.


    Warning: Unless otherwise stated, code is untested. Do not use without understanding. Code is posted in the hopes it is useful, but without warranty. All copyrights are relinquished into the public domain unless otherwise stated. I am not an angel. I am capable of error, and err on a fairly regular basis. If I made a mistake, please let me know (such as by replying to this node).

Re: Using "my" suppresses "Name used only once" warning?
by dragonchild (Archbishop) on Feb 03, 2003 at 15:50 UTC
    With regards to your angst about strings and numbers ... flip your thinking. You're worried about making a mistake and using a string or number where you shouldn't have and getting wonky results because of it. That's a valid worry and every single monk worth their salt has had it bite them in the ass, easily losing a day or two of working time.

    So, we stop using Perl, right?

    Naaah! Instead, consider the following points:

    1. Perl was initially designed to process "stuff". One of its most common uses is to handle CGI "stuff". Having worked with CGI stuff in C++, the http server will give you everything in strings. That would've gotten real annoying in C, but C++ had these neat overloaded operators for me, so I could add two strings together. Perl takes that idea and makes it better.
    2. Ever since I started working with Perl, especially OO Perl app development, my skill as a developer has improved. In some cases, by leaps and bounds. Perl lets you do (nearly!) anything you want. But, if you want to work with it three months from now or if you want to work with it in a remote-development group, you'd better do it intelligently. Because Perl doesn't force you to design, it lets you design better. It lets you make the mistakes, then allows you to do it right. This means that I (now) naturally name variables and structure programs so that the number / string issue, well, isn't an issue. :-)
    3. If the above points don't convince you, consider that there are thousands of extremely smart developers who wish that every language they have to work in has X feature from Perl. (For me, it's hashes and regexes and, yes, scalars.) I hate not being able to use hashes. I hate having to do the stupid book-keeping to know if I'm going to want a string or an int or a float or whatever. I know I'm not alone. Even if you don't understand it now, trust that we do and that you'll understand it very soon.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      Wow. The last sentence of every point you make is worth a ++ alone. Nice post!

      Perl takes that idea and makes it better.

      This means that I (now) naturally name variables and structure programs so that the number / string issue, well, isn't an issue. :-)

      Even if you don't understand it now, trust that we do and that you'll understand it very soon.

      Well said, and ++ to you!

      --- demerphq
      my friends call me, usually because I'm late....

      I wasn't even considering not using Perl!

      Besides anything else, it excels at text processing, and text is at the core of most Web applications.

      I know Perl gives users so much more rope than other languages - I'm just trying to make sure I don't trip myself up or hang myself with it. ;o)

      There are also so many different ways to do anything, that I sometimes find it helpful to restrict the options a little.

        I'm just trying to make sure I don't trip myself up or hang myself with it.

        Actually, while you're learning, you should hang yourself a few times. It sounds like you were the kid (like me) who just wouldn't believe that "hot" meant "Don't touch" until you had to go to the emergency room.

        I sometimes find it helpful to restrict the options a little.

        Sure. Do what comes natural. But, leave your mind open for new paradigms. When I first came to Perl, I was very disturbed by scalars. But, over time, I learned to appreciate the power of dwimmery. ("Do What I Mean"-ery) I also learned I could trust the Perl developers. But, I've found that every "hot" kid has to learn that trust for themselves.

        Another comment - Perl is not the be-all-end-all of programming languages. (It's close, but not quite.) And, frankly, it wasn't intended to be (though Perl6 might be really, really close!). There are applications for which Perl is absolutely horrible, like embedded or time-critical apps. I just wanted to say that because you're sounding like you have Perl up on a pedestal.

        Remember - many of the most-used Perl modules have their guts written in XS and/or Inline::C. That's not cause Perl is bad ... just XS or Inline::C might be better for the specific purpose.

        ------
        We are the carpenters a.nd bricklayers of the Information Age.

        Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (2)
As of 2024-04-26 00:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found