Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Dumping variables but DRY and simple

by LanX (Canon)
on Mar 27, 2010 at 13:37 UTC ( #831338=perlquestion: print w/ replies, xml ) Need Help??
LanX has asked for the wisdom of the Perl Monks concerning the following question:

Hi

is there a comfortable and DRY way to dump variables?

I mean neither printing "$VAR1" nor having to repeat the name over and over again, and working with both kinds of variables?

For instance always writing:  print Data::Dumper->Dump([\@fontspec],['*fontspec']); is no fun.

I made this hack, which works quite fine so far (ATM for lexicals only):

sub dmp (\[$@%];\[$@%]\[$@%]\[$@%]\[$@%]\[$@%]\[$@%]\[$@%]\[$@%]\[$@%] +){ # die "to many arguments for dmp()" if @_>10; use PadWalker qw/var_name/; for $struc (@_){ local $,="\n"; my $name=var_name(1, $struc); $name=~s/^[\@\$\%]/\*/; print Data::Dumper->Dump([$struc],[$name]); } }

which called with

dmp @fontspec;

produces the same output:

@fontspec = ( { 'id' => '0', 'family' => 'Helvetica', 'size' => '10' }, { # ... and so on

But I have the uncomfortable feeling of reinventing the wheel...

Cheers Rolf

UPDATE: improved code

UPDATE: hmm maybe Conway's Smart::Comments should be mentioned, but it uses code filters...

Comment on Dumping variables but DRY and simple
Select or Download Code
Re: Dumping variables but DRY and simple
by rubasov (Friar) on Mar 27, 2010 at 14:16 UTC
    Have you seen Data::Dump::pp? It eliminates the $VARn ugliness.
      yes .... I saw it some days ago...but
      Returns a string containing a Perl expression. If you pass this string to Perl’s built-in eval() function it should return a copy of the arguments you passed to dump().

      didn't encourage me a lot, wrapping all in evals is not what I really wanted.

      But maybe I'm wrong, can you show me example code?

      Cheers Rolf

        eval() is needed only when you want a deep copy.
        use Data::Dump qw( pp dd ); my $ref = [ 'foo', 'bar', { asd => 1, qwe => 2 } ]; # pp() called in void context prints to STDERR pp $ref; # prints: ["foo", "bar", { asd => 1, qwe => 2 }] # dd() called in void context prints to STDOUT dd $ref; # named printing is still not DRY, but much better than: # print Data::Dumper->Dump( [$ref], ['*ref'] ); print '$ref = ', pp($ref), "\n"; # prints: $ref = ["foo", "bar", { asd => 1, qwe => 2 }] # eval() for a deep copy my $deep_copy = eval pp($ref); pp $deep_copy;
        The printing format is a lot more readable than Data::Dumper's default. However beware that Data::Dump is not among the core modules.
        Same goes for Data::Dumper. If you want to reify the structure, you need to use eval. As far as I'm concerned, they are debugging tools, not storage tools.
Re: Dumping variables but DRY and simple
by rovf (Priest) on Mar 27, 2010 at 14:35 UTC
    For a fairly terse output, I usually set:

    local $Data::Dumper::Indent=0; local $Data::Dumper::Varname=''; local $Data::Dumper::Terse=1; local $Data::Dumper::Pair='=>'; local $Data::Dumper::Sortkeys=1; local $Data::Dumper::Quotekeys=0;

    -- 
    Ronald Fischer <ynnor@mm.st>
      OK thanks it doesn't display $VAR1 anymore ...

      ...but one still doesn't get the realname displayed and you still have to reference the dumped structures.

      or do I miss it?

      Cheers Rolf

        To get to the real name, you would have to fiddle with the compiler. Data::Dumper doesn't do this.

        -- 
        Ronald Fischer <ynnor@mm.st>
Re: Dumping variables but DRY and simple
by tinita (Parson) on Mar 27, 2010 at 16:43 UTC
    I have a vim mapping for that kind of thing. Since it's not trivial to get the variable name with perl standard functions I consider that a good workaround to let your editor help you.
    imap DUMPER <ESC>^iwarn __PACKAGE__.':'.__LINE__.$".Data::Dumper->Dump +([\<ESC>llyw$a], ['<ESC>pa']);<ESC>

    this mapping lets you type
    $my_variableDUMPER
    which gets expanded to
    warn __PACKAGE__.':'.__LINE__.$".Data::Dumper->Dump([\$my_variable], ['my_variable']);

    I can only say that I'm using this for many years now and it has saved me so much time, when typing, as well as when trying to find out the source of Dumper statements in the log. (ever worked on team code and getting various $VAR dumps in the log not knowing where they come from?)
      Ok this goes somehow in the direction of code generation like Smart::Comments with the difference that you can still safely use it in production code.

      But then I would rather prefer to insert an eval-macro solution giving me the opportunity to change details dynamically at central place:

      #!/usr/bin/perl my @bla=(0..9); sub dmp_macro { my $var=shift; (my $var2=$var) =~ tr/@%$//d; use Data::Dumper; return "print Data::Dumper->Dump([\\$var],['\*$var2'])" } print dmp_macro('@bla'),"\n"x3; eval (dmp_macro qw/@bla/);

      output:

      print Data::Dumper->Dump([\@bla],['*bla']) @bla = ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 );

      (OK I admit, it's not only lisp-ish, it's even uglier ;-)

      Cheers Rolf

Re: Dumping variables but DRY and simple
by BrowserUk (Pope) on Mar 27, 2010 at 16:50 UTC
    UPDATE: hmm maybe Conway's Smart::Comments should be mentioned, but it uses code filters...

    ...but only on comments, and only when you're debugging. Once you've finished, comment it out and it's all gone.

    It's far less invasive than PadWalker.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      > It's far less invasive than PadWalker.

      In my example "hack" I'm using PadWalker to determine the variable name for use in debugging or error msg context.

      I can check if it's installed and otherwise savely fall back to something like "$VAR1" or the "$filename-$linenumber" if not.

      And I doubt that PadWalker can cause instabilities just by parsing the optree!

      In any way I wouldn't suggest using code filters for error msgs in productive code...

      Cheers Rolf

        And I doubt that PadWalker can cause instabilities just by parsing the optree!

        No? Try

        perl -MPadWalker=peek_my -e"my $x = 42; sub { my $closed_over = $x; sub { peek_my 0 } }->()->() +"
        In any way I wouldn't suggest using code filters for error msgs in productive code...

        Neither did I.

        But then neither would I recommend the tracing of variables in production code.

        The need for that is: a) a clear sign of inadequate testing; b) poor design.

        Excepting Acts of God and Cosmic Rays, given the same values, code produces the same results. The only source of variability is IO.

        And if this is a permanent feature of your logging or error handling, then the trivial extra investment to log:

        20100327204831.321 file.pl(87): Received '...' from socket:0xdeadbeef

        over

        20100327204831.321 file.pl(87): $buf = '...';

        The point is that noone, neither programmer nor user, is going to be able to draw any conclusions from "$buf = '...', without consulting the source. And with the file and line number, the variable that contains the value is obvious. Making it unnecessary information in the log.

        For development time debugging, watching the values of variables change without reference to the source can give the programmer clues to his mistakes--out by one being the classic. And Smart::Comments is ideal for this.

        But once you move into production, there is always a better identification for a value--more meaningful to both user and maintenance programmer alike--than the internal variable identifier.

        You won't agree. And I won't argue the point further.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (10)
As of 2014-09-22 10:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (186 votes), past polls