http://www.perlmonks.org?node_id=267707

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

I understand the underlying condition which causes a Useless use of private variable in void context error. However, I am encountering this error in at least one spot in my code and no matter what I do to tweak the small portion of code we're dealing with here, I can't make the error go away.

Perhaps the problem is occuring outside of this portion of code (it's a large function/sub so I would rather not post the entire thing unless it's necessary). However, the error specifically indicates the line below..

My code does what I need without any problems, but I'm cleaning up my code in general and this one has really got me.

My program is fairly large (all code totals about 16,000 lines) and the following error apperas with use warnings;.

Useless use of private variable in void context at /home/www/somedomain.com/beta.cgi line 2765.

Line 2765 is this:

my $generated_password = &GeneratePassword;

GeneratePassword() is the following:

sub GeneratePassword { my $password = `passwdgen -pa --length=6`; $password =~ s/Your password is: (.*)/$1/; chomp($password); return($password); }

When I run this, $generated_password contains the intended data (a six character password) just as it should. But I still get that error. I have tried parens around $generated_password and even tried doing away with the sub entirely and putting the contents of sub GeneratePassword directly into the calling parent. I still get the same error.

The only thing I could think of was that $1 from the regex match is considered private and "not used", thus useless? But doesn't the fact that $1 is stuffed into $password as the new value of that scalar mean that it is used?

If I haven't provided enough detail, let me know and I'll try to copy in the rest of the calling routine. It's over a hundred lines so I didn't want to pollute this question with even more unless definitely needed.

Hoping this isn't as simplistic and stupid as my gut is telling me it is.

Replies are listed 'Best First'.
Re: "Useless use of private variable in void context"
by BrowserUk (Patriarch) on Jun 20, 2003 at 21:35 UTC

    I concur with chromatic that the line you posted almost certainly isn't the line that is causing the error.

    The binary chop technique of commenting out lumps of code is a very useful one, but isn't always practical. Often commenting out one block of code early in the routine, causes so many errors later in the code that the compiler aborts before it ever gets to the error you're trying to find. Another technique I picked up somewhere is to introduce a deliberate but benign error, one that won't cause the compiler to abort, and then move this slowly through the code until it transitions from appearing before the error you're trying to track down to after.

    Here it is before

    #! perl -slw use strict; my $deliberate_error=''; my $i; length $deliberate_error; $i; __END__ D:\Perl\test>test Useless use of length in void context at D:\Perl\test\test.pl8 line 7. Useless use of private variable in void context at D:\Perl\test\test.p +l8 line 9.

    And here after

    #! perl -slw use strict; my $deliberate_error=''; my $i; $i; length $deliberate_error; __END__ D:\Perl\test>test Useless use of private variable in void context at D:\Perl\test\test.p +l8 line 7. Useless use of length in void context at D:\Perl\test\test.pl8 line 9.

    Simplistic, but it can sometimes be very effective.

    Wouldn't it be nice if the error reported was

    Useless use of $i in void context at ....


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller


      Yes, thank you! I'll attempt this. I hate to show my ignorance, but I'm not clear on the "binary technique" chromatic mentioned? Is there more to it than just chopping out lines and running perl -wc on it? And yes, if I comment out a chunk of this sub, it's going to give a *lot* of compile errors. *grin*

      Off I go to try this out.

        Basically, the binary chop means

        1. Comment out the top half of the code

          Compile -- has the error gone away?

          1. Yes -- It is in the top half of the program.

            So now uncomment the second quarter. Did it come back?

            1. Yes. It is in that second quarter.

              Uncomment the first half and the 3rd eight of the code. Is it still there?

              1. Yes. ....
              2. No. ....
            2. No. It must be in the first quarter

              So uncomment the second eigth....

        2. No. So the error must be in the bottom half of the program.

          So uncomment the first half and comment out the 3rd quarter.

          Compile -- did the error go away?

          1. Yes, It's in the 3rd quarter.

            So uncomment the 6th eigth of the code.

            Compile -- did it come back?

            1. Yes ... Its in the 6th eigth.
            2. No ... Its in the 5th eight.
              1. No ... its in the 4th quarter....

            Damn! That was tedious to type. And probably equally tedious to read for anyone who already knows it, but... I typed it now so there:)


            Examine what is said, not who speaks.
            "Efficiency is intelligent laziness." -David Dunham
            "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller


      To clarify, using your method, do I want to have the length error appear physically before/after the error in question - or numerically?

      Also, how is this possible?

      Useless use of private variable in void context at beta.cgi line 2766. Useless use of length in void context at beta.cgi line 2766.

      The 'length' line of code is one line before the GeneratePassword() line, yet they show up as the same line in the error? Is this because the perl interpreter has simplified them into one line of code?

      However, if I place the 'length' line on the very next line after the GeneratePassword() line, I get the following (this is what I'm looking for, correct?

      Useless use of private variable in void context at beta.cgi line 2766. Useless use of length in void context at beta.cgi line 2767.

      So using this method, does it not point to the line my $generated_password = GeneratePassword(); as the culprit?

        As a pure guess, check the line before the GeneratePassword() line and see if you haven't type a comma (,) on the end rather than a semi-colon (;)?

        this is what I'm looking for, correct?

        Essentially yes. I would now move slowly backwards through the code until the line number becomes 2765.

        At that point, you wil have found the limit of the code that perl is taking as being "one line". You can then start looking for things like commas instead of semicolons, unclosed ""s or ''s etc. try commenting out the whole of th e previous line. Does the line number change then?


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller


Re: "Useless use of private variable in void context"
by chromatic (Archbishop) on Jun 20, 2003 at 21:09 UTC

    I don't think that's the line in question. Can you try a binary search to find the real line? Comment out half of the sub at a time and run perl -wc on the source.

Re: "Useless use of private variable in void context"
by Mr. Muskrat (Canon) on Jun 20, 2003 at 21:15 UTC
    I would look at the line right before this one:
    my $generated_password = &GeneratePassword;
Re: "Useless use of private variable in void context"
by kutsu (Priest) on Jun 20, 2003 at 21:13 UTC

    I don't get that error, so I'd guess it's somewhere else in your code. Also you might consider using my $generated_password = GeneratePassword();, that last part is just my opinion as I have had trouble with &.

    "Pain is weakness leaving the body, I find myself in pain everyday" -me

      I don't seem to get the same error if I run it in a test script by itself, either. But if I remove the line in question, I do get an error - just later in the script (the next chunk of code, which is an eval{} but in which I can find no problem either).

      As for the ampersand - I have been conflicted over this. At one point I had read that there was a difference between calling a sub naked and calling it with an ampersand prefixed to it. I believe that it stated you should use an ampersand if you expected something to be returned (or to make the sub return to its calling point no matter what?). But I have since been told by a couple of people that the rule of the ampersand is obsolete (or more accurately, was documented but then never implemented).

      I do it out of habit now, though I'm trying to break it!

      I guess I just needed some people smarter than myself to assure me that the snippet of code and how it was being accessed wasn't really the problem. (I assumed it was not, since I coudl run it by itself). Now I know that focusing on that bit is a waste of time and can look toward the rest of the sub for the culprit. It's a huge sub, but it's syntatically quite clean. I still am sure it'll end up being a simple oversight somewhere that I'll slap my forehead over though. I'll update here when I reach the conclusion.