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

Dear Guru,

How can I print this:
my @arr = qw(book dog cat); print "[" . join('',', @arr) . "]\;,\n";'
such that it prints verbatim:
['book','dog','cat'];
Some how my snippet above doesn't work. How can I go a bout it.
I know I can use Data::Dumper. But here I want to create my own pretty data dumper.
Thanks so much before hand.
Eddy

Replies are listed 'Best First'.
Re:Printing Array with quote and comma
by McDarren (Abbot) on Oct 05, 2005 at 03:53 UTC
    Try this:
    #!/usr/bin/perl -w use strict; my @arr = qw(book dog cat); print "[", join("," , map {qq('$_')} @arr), "];\n";

    --Darren
Re: Printing Array with quote and comma
by Tanktalus (Canon) on Oct 05, 2005 at 04:05 UTC

    Ok, I think you're looking at this just a bit off. Besides the excellent suggestions to not reinvent the wheel, I encourage you, if you're going ahead anyway, to solve the problem in the domain of the problem rather than in the domain of programming.

    print "[", # leading bracket join(",", # items separated by commas map { "'$_'" } # each item surrounded by quotes @arr # the items ), "]\n"; # end bracket

    The map is the part I think is important here. Your elements aren't actually what you have in the array - they are derived from what you have in @arr by adding quotes on each side. Then you join them, and put brackets around them.

    The disadvantage here is that this probably takes up more memory than the other solutions. And is likely slower.

    The advantage is that as you need to deal with more types, you can just handle them inside that map as appropriate by checking ref and dealing with the object as appropriate. Because the solution is in the same domain as the problem, it is more extendable inside that domain. For example, maybe a string has a special character that needs to be expanded - such as the carriage return "\n". In that case, you need to use double quotes rather than single quotes if you want the \n to appear as two characters that can be reinterpreted back to a single character later. The join solutions above don't allow for this because they're solving the problem in the domain of the programmer. The map solution allows that type of switch on an element-by-element basis.

      Same thing (well, better quoting), but possibly easier to read:
      sub bracket { local $_ = @_ ? $_[0] : $_; return "[$_]"; } sub quote { local $_ = @_ ? $_[0] : $_; s/(['\\])/\\$1/g; return "'$_'"; } print map { "$_;\n" } # Add tail. bracket # Surround with brackets. join ',', # Seperate elements with commas. map quote, # Quote elements. @arr; # Elements.
      or
      sub quote { local $_ = @_ ? $_[0] : $_; s/(['\\])/\\$1/g; return "'$_'"; } print map { "[$_];\n" } # Add brackets and tail. join ',', # Seperate elements with commas. map quote, # Quote elements. @arr; # Elements.
Re: Printing Array with quote and comma
by davido (Cardinal) on Oct 05, 2005 at 03:54 UTC

    Just take a deep breath and walk through it piece by piece. It will become clear if you leave the keyboard for a few minutes and return with a fresh head.

    my @arr = qw(book dog cat); print "['" # Print the leading bracket and quote . join("','", @arr) # join array with quotes and commas . "'];\n"; # print the trailing quote, bracket, etc.

    Extra whitespace added for clarity.


    Dave

Re: Printing Array with quote and comma
by bobf (Monsignor) on Oct 05, 2005 at 03:52 UTC

    One way to do it:

    use warnings; use strict; my @arr = qw(book dog cat); print "['", join( "','", @arr), "'];\n";

    But I'm curious... why are you trying to reinvent the data dumper wheel?

    HTH

    Update: As reasonablekeith pointed out, the code above doesn't work as intended for empty arrays. While the map solutions are more elegant (IMO), this corrects the problem:

    print "[", ( @arr2 ? "'" . join( "','", @arr2) . "'" : ''), "];\n";

    Thanks and ++ for pointing out the error.

      This doesn't really work, as if the array contains no elements, your code will still print one empty element...
      [''];

      The map style solutions don't have this problem.

      As pointed out below, the map solutions would take more memory, as they are creating an extra copy of your array. If you don't mind updating your array however, you could quote the elements in-place before hand.

      my @arr = qw(book dog cat); s/.*/'$_'/ for @arr; print "[" . join(',', @arr) . "];\n";
      ---
      my name's not Keith, and I'm not reasonable.
Re: Printing Array with quote and comma
by pg (Canon) on Oct 05, 2005 at 03:57 UTC

    Or just use the existing functionality provided by Data::Dumper:

    use Data::Dumper; $Data::Dumper::Indent = 0; my @arr = qw(book dog cat); print Dumper(\@arr);

    If you want to do your way, then fix those ' and ":

    my @arr = qw(book dog cat); print "[" . join(',', @arr) . "];\n";

      As long as we're doing down the "other ways to do it" road...

      my @arr = qw(book dog cat); { local $" = "','"; print "['@arr'];\n"; }

      And if that one's not ugly enough, we can certanly take it down that path too...

      my @arr = qw(book dog cat); $"='\',\'';print"['@arr'];$/";

      ...just having fun, of course.


      Dave

Re: Printing Array with quote and comma
by ikegami (Patriarch) on Oct 05, 2005 at 04:48 UTC
Re: Printing Array with quote and comma
by gargle (Chaplain) on Oct 05, 2005 at 05:49 UTC

    Hi,

    In one line:

    perl -e '@a = qw(book dog cat); print "[".join(",",@a)."];\n";'
    --
    if ( 1 ) { $postman->ring() for (1..2); }
      This doesn't work according to spec, you're missing the single quotes round each value.

      It also refuses to run in a windows command shell...

      Can't find string terminator "'" anywhere before EOF at -e line 1.
      ---
      my name's not Keith, and I'm not reasonable.

        Hi,

        well, in linux and cygwin on win 2000 (cmd.exe & bash) it does work...

        Are you sure you copied the complete line?

        --
        if ( 1 ) { $postman->ring() for (1..2); }
Re: Printing Array with quote and comma
by Moron (Curate) on Oct 05, 2005 at 11:16 UTC
    Or perhaps just reformat the Dumper output:
    !/usr/bin/perl use Data::Dumper; my @arr = qw(book dog cat); print Reformat( Dumper ( \@arr ) ); sub Reformat { my @dmp = split( /\n/, shift ); # split lines and remove cr shift @dmp; # get rid of $varx=[ line $_ = join ( '', @dmp ); # put rest together s/\s+//g; # kill whitespace return "[$_\n"; # put back [ and add a cr }

    -M

    Free your mind