Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

RFC: perl sub diff between two files

by bliako (Monsignor)
on Mar 26, 2018 at 12:24 UTC ( [id://1211734]=perlmeditation: print w/replies, xml ) Need Help??

Fellow Monks,

Recently, I was in need to compare two versions of the same perl module containing many subs. I was interested to see the difference between the contents of subs with the same name. This happened because I forked the same code in two different machines and made changes in the modules in both machines.

For this purpose I wrote the following basic script which I place here for public use but also for comments from the monastic community.

The simple script makes use of two excellent modules, namely PPI and Text::WordDiff. PPI parses perl code and is capable of extracting subs and their contents. Text::WordDiff outlines (and color-codes) the differences between two blocks of text (the contents of identically-named subs in two files).

Unix's diff is a fine tool in general, but code has a few idiosyngracies which make diffing sometimes impractical. For example when same-content subs have different order in their respective files.

That said, I wanted a quick tool to check my two versions of the perl module, find enhancements in either file I made and produce a final version.

Here is the script:

#!/usr/bin/env perl use strict; use warnings; use PPI; use Text::WordDiff; if( scalar(@ARGV) != 2 ){ print usage($0) . "\n"; exit(0); } my ($infile1, $infile2) = @ARGV; my $doc = PPI::Document->new($infile1); if( ! defined($doc) ){ print STDERR "$0 : call to ".'PPI::Document->ne +w()'." has failed for input file '$infile2'.\n"; exit(1); } my (%subs1, %subs2, $asub); for $asub ( @{ $doc->find('PPI::Statement::Sub') || [] } ) { # loop over all subs in file unless ( $asub->forward ) { # store sub's contents in hash keyed on sub's name $subs1{ $asub->name } = $asub->content; } } $doc = PPI::Document->new($infile2); if( ! defined($doc) ){ print STDERR "$0 : call to ".'PPI::Document->ne +w()'." has failed for input file '$infile2'.\n"; exit(1); } for $asub ( @{ $doc->find('PPI::Statement::Sub') || [] } ) { # loop over all subs in file unless ( $asub->forward ) { # store sub's contents in hash keyed on sub's name $subs2{ $asub->name } = $asub->content; } } my ($k, $v1, $v2, $res, $anitem); my @dont_exist = (); my %allkeys = map { $_ => 1 } (keys %subs1, keys %subs2); foreach $k (sort keys %allkeys){ if( ! defined($v1=$subs1{$k}) ){ push(@dont_exist, "$k : Does not exist in '$infile1'\n"); next } elsif( ! defined($v2=$subs2{$k}) ){ push(@dont_exist, "$k : Does not exist in '$infile2'\n"); next } # sub (same name) exists in both files, diff sub's contents in fil +es: $res = Text::WordDiff::word_diff( \$v1, \$v2, ); # print diff results print "----- begin '$k' -----\n" . $res . "\n----- end '$k' ------\n" ; } # and also print the subs which exist in one file but not the other fi +le print join("", @dont_exist); exit(0); sub usage { return "Usage : ".$_[0]." file1 file2\nColor output guide:\n\tRED +: file1\n\tGREEN: file2\n" }

bliako

Replies are listed 'Best First'.
Re: RFC: perl sub diff between two files
by stevieb (Canon) on Mar 26, 2018 at 15:07 UTC

    Good work!

    I do not have time today to review and play with what you've done here, but the diff aspect sounds like something that would be very beneficial to my Devel::Examine::Subs, so I will give it a good test and see if that Text::WordDiff functionality fits well into my project.

Re: RFC: perl sub diff between two files
by LanX (Saint) on Mar 26, 2018 at 15:47 UTC
Re: RFC: perl sub diff between two files
by Anonymous Monk on Mar 26, 2018 at 20:45 UTC
A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://1211734]
Approved by marto
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (8)
As of 2024-04-18 16:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found