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

In several programs I have written or debugged, I have often wished there was a quick and dirty way to have perl print out the names and values of all variables that it knows about, then exit. This would aid in the debugging process when I'm trying to figure out things like "Did I already initialize this variable somewhere?" or "I think $var equals 'xyz', but I'm not sure." Does anyone know of a module that handles this type of thing? Or is it possible using another method?
  • Comment on How do I tell what variables have been defined?

Replies are listed 'Best First'.
Re: How do I tell what variables have been defined?
by BrowserUk (Patriarch) on Sep 26, 2002 at 03:41 UTC

    Using perl -d scriptname will take you into the debugger and then there are the X and Y cammands that will display all the vars know in the current program (or package) at the current point in the program.

    This means that if all your varables are globals (a BAD idea) then with the exception of any created through eval's, autovivification and the like, you would be able to see all your vars immediatly the debugger has loaded.

    However, if you are being good and using my and or our vars, then these do not come into existance (visibility?) until the line where the are declared (my'd or our'd) has been executed. Which means you need set a break point and run to it & then use the X or Y commands to see what variables are visible at that point in the code.

    I don't know of anything better than this.

    I might think about trying to write a source file parser to extract variable names and line numbers, but I've seen the quote "Only Perl can parse perl" often enough to dismiss that idea:)

    One trick that might give you most of the information if your code doesn't use globals is to use your editor or another perl script or one-liner:) to globally replace the word "my" with something easily identifiable (I used 1;;;;;;;;;) that will be easy to revert. Leave strict enabled and try and run the program. You get output that looks like

    C:\test>calc Global symbol "$tree" requires explicit package name at C:\test\calc.p +l line 8. Global symbol "$tree" requires explicit package name at C:\test\calc.p +l line 9. .... Global symbol "@ops" requires explicit package name at C:\test\calc.pl + line 77. Global symbol "@ops" requires explicit package name at C:\test\calc.pl + line 78. Execution of C:\test\calc.pl aborted due to compilation errors. C:\test>

    Combining this information with the dump of globals from the debugger should cover most things.


    Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring!
      I second BrowserUK's suggestion of using 'use strict;'. If you're worried about using variables that aren't defined(maybe mis-spelled?), then start doing
      #!/usr/bin/perl -w use strict;
      at the top of every Perl script. I always use both of those.

      HTH.
        Thanks everyone for all of your replies on this. I have several options now, all of which I plan to explore. I love this place!
Re: How do I tell what variables have been defined?
by tadman (Prior) on Sep 26, 2002 at 03:23 UTC
    In a sense, you can't, since most variables are declared using my which makes them lexical. You can't just open up the symbol table and poke around looking for them in the same way you can for subroutines. Of course, this is presuming you're not using something like our or use vars to declare variables.

    Usually, you're curious about the value of a particular variable, or even a group of them, which is where a tool like Data::Dumper can come in handy. In the formatted mode, where you label your variables, it can be rather informative.

    Of course, I'm only touching the surface here. There's probably a way to do it if you're really determined.
(jeffa) Re: How do I tell what variables have been defined?
by jeffa (Bishop) on Sep 26, 2002 at 03:40 UTC
    Devel::Symdump is of slight help, but like tadman said, you are out of luck when trying to inspect lexical variables. I still think that the best prescription for this kind of problem is to design, design, design and get into the habit of writing unit tests before you start coding.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)