Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

prettyfy hashes

by morgon (Priest)
on Apr 03, 2016 at 01:38 UTC ( [id://1159396]=perlquestion: print w/replies, xml ) Need Help??

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

Hi

I want to transform a hash definition like this:

%some_hash = ( key => "value1", larger_key => "value2", even_larger_key => "value3", );
to something like this:
%some_hash = ( key => "value1", larger_key => "value2", even_larger_key => "value3", );
i.e. make the fat commas line up in perl source code.

By "transform" I mean a perl-script that takes the key-value lines from stdin and prints the prettyfied versions to stdout so I can call it from vim.

As this seems to be a quite natural requirement I assume some module does things like that already (lazyness is a virtue right).

So could someone please point me to such a modules (I am NOT looking for someone to code this for me).

Replies are listed 'Best First'.
Re: prettyfy hashes
by james28909 (Deacon) on Apr 03, 2016 at 01:49 UTC

    Not sure if it is what you specifically want, but you could check out perltidy. It cleans up source code pretty good and is configurable.

Re: prettyfy hashes
by BrowserUk (Patriarch) on Apr 03, 2016 at 02:13 UTC

    #! perl -sw use strict; use List::Util qw[ max ]; my $first = <>; my @ugly = <>; my $last = pop @ugly; my @bits = map[ m[(^\s+)(\S+)\s*=>\s*(\S+),\n] ], @ugly; my $largest = max( map{ length( $_->[1] ) } @bits ); print $first; printf "%s%-${largest}s => %s,\n", @$_ for @bits; print $last;

    Output:

    C:\test>1159396 C:\test>1159396 %some_hash = ( key => "value1", larger_key => "value2", even_larger_key => "value3", ); ^Z %some_hash = ( key => "value1", larger_key => "value2", even_larger_key => "value3", );

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    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". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: prettyfy hashes
by choroba (Cardinal) on Apr 03, 2016 at 02:07 UTC
    > so I can call it from vim.

    What a pity! In Emacs, you can use align-regex , which I usually bind to C-x l . I can then just select the region and press C-x l => Enter and voilą!

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      I normally move the cursor to the last => and type M-x align-current .

      One day I'll automatise it to happen with each auto indent. ..

      FWIW I seem to remember that perltidy can't do this.

      Cheers Rolf
      (addicted to the Perl Programming Language and ☆☆☆☆ :)
      Je suis Charlie!

        It aligns the assignment symbol = for me, too, which I don't want. Do you have any special align-rules-alist to prevent that?

        # here, instead of here # v V my %periods = (Mercury => { orbital => 0.24, rotation => +58.64 }, Venus => { orbital => 0.62, rotation => -243.02 }, Earth => { orbital => 1.00, rotation => 1.00 }, Mars => { orbital => 1.88, rotation => 1.03 }, Jupiter => { orbital => 11.86, rotation => 0.41 }, Saturn => { orbital => 29.46, rotation => 0.43 }, Uranus => { orbital => 84.01, rotation => -0.72 }, Neptune => { orbital => 164.8, rotation => 0.67 }, );

        Moving the structure from the assignment line doesn't help:

        my %periods = ( Mercury => { orbital => 0.24, rotation => 58.64 }, Venus => { orbital => 0.62, rotation => -243.02 }, # ...

        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      > In Emacs, you can use align-regex , which I usually bind to C-x l . I can then just select the region and press C-x l => Enter and voilą!

      There is room for much improvement...

      1. selecting the region:

      a combination of backward-up-list and mark-sexp will select the surrounding structure (repeating will extend the selection till statement (ie. ';') boundary.

      (please note that cperl-mode injects here some semantic knowledge about the code's structure which can't be reflected in a simple regexp rule)

      2. the rule for align-current has the advantage to harmonize the surrounding whitespaces too. And align-regexp seems to allow the same extended logic.

      So combining both steps bound to a key should make alignment of fat-commas quite easy.

      I experimented with a kmacro and it seemed quite nice. :)

      Cheers Rolf
      (addicted to the Perl Programming Language and ☆☆☆☆ :)
      Je suis Charlie!

Re: prettyfy hashes
by 1nickt (Canon) on Apr 03, 2016 at 18:18 UTC

    You could use Data::Dumper::Perltidy which uses a default perltidy config, but can be configured to use your own .perltidy.rc:

    perl -MData::Dumper::Perltidy -E' $href = { foo => "bar", longer => "baz", longest => "qux" }; say Dumper $href; '
    Output:
    $VAR1 = { 'foo' => 'bar', 'longer' => 'baz', 'longest' => 'qux' };

    Hope this helps!


    The way forward always starts with a minimal test.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2024-03-19 04:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found