BrowserUk has asked for the wisdom of the Perl Monks concerning the following question:
I have six chunks of 52 lines of very similar code that I need to isolate all the differences in.
I've been tackling it by eye, and have it mostly working, but there remains some small difference that I'm not seeing; and I'm going bug-eyed for looking.
Anyone any thoughts how to do a six-way diff?
I settled for a low tech solution that worked surprisingly well.
First, I put the six chunks of code into separate files. Then I wrote the following simple Perl script that loaded the lines of those files in to an AoAs: all the line 1s in to one array, all line 2s in to another; and so on; and then printed them to standard out:
#! perl -slw use strict; use Data::Dump qw[ pp ]; my @lines; for my $file ( qw[ x1.js x2.js y1.js y2.js z1.js z2.js ] ){ open FH, '<', $file or die $!; push @{ $lines[ $. ] }, $_ while <FH>; close FH; } for my $l ( @lines ) { next unless defined $l; print @$l; }
What I got after normalising the files and lines -- which was surprisingly quick by referencing the output -- was stuff that looked like this:
E:\Chart>diff6 | more gg = _GetGrid( this.Min.y / this.Parent.Zoom.y, this.Max.y / this.Pare +nt.Zoom.y, this.Scale.y ); gg = _GetGrid( this.Min.z / this.Parent.Zoom.z, this.Max.z / this.Pare +nt.Zoom.z, this.Scale.z ); gg = _GetGrid( this.Min.x / this.Parent.Zoom.x, this.Max.x / this.Pare +nt.Zoom.x, this.Scale.x ); gg = _GetGrid( this.Min.z / this.Parent.Zoom.z, this.Max.z / this.Pare +nt.Zoom.z, this.Scale.z ); gg = _GetGrid( this.Min.x / this.Parent.Zoom.x, this.Max.x / this.Pare +nt.Zoom.x, this.Scale.x ); gg = _GetGrid( this.Min.y / this.Parent.Zoom.y, this.Max.y / this.Pare +nt.Zoom.y, this.Scale.y ); if( this.GridDelta.y != 0 ) gg[1] = this.GridDelta.y; if( this.GridDelta.z != 0 ) gg[1] = this.GridDelta.z; if( this.GridDelta.x != 0 ) gg[1] = this.GridDelta.x; if( this.GridDelta.z != 0 ) gg[1] = this.GridDelta.z; if( this.GridDelta.x != 0 ) gg[1] = this.GridDelta.x; if( this.GridDelta.y != 0 ) gg[1] = this.GridDelta.y; var ii = 0; var ii = 0; var ii = 0; var ii = 0; var ii = 0; var ii = 0; for( var jj = gg[2]; jj >= gg[0]; jj -= gg[1] ) { for( var jj = gg[2]; jj >= gg[0]; jj -= gg[1] ) { for( var jj = gg[2]; jj >= gg[0]; jj -= gg[1] ) { for( var jj = gg[2]; jj >= gg[0]; jj -= gg[1] ) { for( var jj = gg[2]; jj >= gg[0]; jj -= gg[1] ) { for( var jj = gg[2]; jj >= gg[0]; jj -= gg[1] ) { pp.y = jj * this.Parent.Zoom.y; pp.z = jj * this.Parent.Zoom.z; pp.x = jj * this.Parent.Zoom.x; pp.z = jj * this.Parent.Zoom.z; pp.x = jj * this.Parent.Zoom.x; pp.y = jj * this.Parent.Zoom.y; pp.z = this.Min.z; pp.y = this.Min.y; pp.z = this.Min.z; pp.x = this.Min.x; pp.y = this.Min.y; pp.x = this.Min.x; var vv = this.Parent.ScreenPos( pp ); var vv = this.Parent.ScreenPos( pp ); var vv = this.Parent.ScreenPos( pp ); var vv = this.Parent.ScreenPos( pp ); var vv = this.Parent.ScreenPos( pp ); var vv = this.Parent.ScreenPos( pp ); fromOV( this.Line[4][ii], vv.x, vv.y ); fromOV( this.Line[5][ii], vv.x, vv.y ); fromOV( this.Line[2][ii], vv.x, vv.y ); fromOV( this.Line[3][ii], vv.x, vv.y ); fromOV( this.Line[0][ii], vv.x, vv.y ); fromOV( this.Line[1][ii], vv.x, vv.y ); ...
I piped that into a file, wrapped it into a subroutine and eliminated the duplicates, then went through the sets of lines with differences and parameterised them one at a time. The result is:
diff6( this, 'x', 'y', 'z', 4, ( this.Parent.Th < 0 ), ( this.Parent.F +i >= 180 ), pp ); diff6( this, 'x', 'z', 'y', 5, ( this.Parent.Fi >= 180 ), ( this.Paren +t.Th < 0 ), pp ); diff6( this, 'y', 'x', 'z', 2, ( this.Parent.Th < 0 ), ( ( this.Parent +.Fi < 90 ) || ( this.Parent.Fi >= 270 ) ), pp ); diff6( this, 'y', 'z', 'x', 3, ( ( this.Parent.Fi < 90 ) || ( this.Par +ent.Fi >= 270 ),), ( this.Parent.Th < 0 ), pp ); diff6( this, 'z', 'x', 'y', 0, ( this.Parent.Fi >= 180 ), ( ( this.Par +ent.Fi < 90 ) || ( this.Parent.Fi >= 270 ) ), pp ); diff6( this, 'z', 'y', 'x', 1, ( ( this.Parent.Fi < 90 ) || ( this.Par +ent.Fi >= 270 ) ), ( this.Parent.Fi >= 180 ), pp ); function diff6( me, plane, primary, secondary, idx, cond1, cond2, pp ) + { var gg = _GetGrid( me.Min[primary] / me.Parent.Zoom[primary], me.M +ax[primary] / me.Parent.Zoom[primary], me.Scale[primary] ); var uu = 0; if( me.GridDelta[primary] != 0 ) gg[1] = me.GridDelta[primary]; var ii = 0; for( var jj = gg[2]; jj >= gg[0]; jj -= gg[1] ) { pp[primary] = jj * me.Parent.Zoom[primary]; pp[secondary] = me.Min[secondary]; var vv = me.Parent.ScreenPos( pp ); fromOV( me.Line[idx][ii], vv.x, vv.y ); var xx = vv.x, yy = vv.y; pp[secondary] = me.Max[secondary]; vv = me.Parent.ScreenPos( pp ); toOV( me.Line[idx][ii], vv.x, vv.y ); _OAV( me.Line[idx][ii], "stroke", me.StrokeColor ); _OAV( me.Line[idx][ii], "visibility", "visible" ); if( cond1 ) { _OAV( me.Text[idx][ii], "x", Math.floor( xx + ( vv.x - xx +) * 1.06 ) - 50 * uu ); _OAV( me.Text[idx][ii], "y", Math.floor( yy + ( vv.y - yy +) * 1.06 ) - 7 * uu ); } else { _OAV( me.Text[idx][ii], "x", Math.floor( vv.x + ( xx - vv. +x ) * 1.06 ) - 50 * uu ); _OAV( me.Text[idx][ii], "y", Math.floor( vv.y + ( yy - vv. +y ) * 1.06 ) - 7 * uu ); } colorOV( me.Text[idx][ii], me.StrokeColor ); _OAV( me.Text[idx][ii], "visibility", "visible" ); if( ( ii == 1 ) && ( me.Label[primary] ) ) innerTextOV( me.Text[idx][ii], me.Label[primary] ); else { if( isNaN( me.Scale[primary] ) ) { if( me.Scale[primary].substr( 0,9 ) == "function " ) { ff = eval( "window." + me.Scale[primary].substr( 9 + ) ); if( ff ) innerTextOV( me.Text[idx][ii], ff( _Scale +String( jj, gg[1] ) ) ); } else innerTextOV( me.Text[idx][ii], _ScaleString( jj, +gg[1] ) + me.Scale[primary] ); } else { if( me.Scale[primary] < 1 ) innerTextOV( me.Text[idx] +[ii], "" ); if( me.Scale[primary] == 1 ) innerTextOV( me.Text[idx] +[ii], _ScaleString( jj, gg[1] ) ); if( me.Scale[primary] > 1 ) innerTextOV( me.Text[idx] +[ii], _DateFormat( jj, gg[1], me.Scale[primary] ) ); } } ii++; } if( me.Min[primary] < me.Max[primary] ) { if( cond2 ) { if( me.Min[primary] / me.Parent.Zoom[primary] > gg[0] - gg +[1] / 3 ) innerTextOV( me.Text[idx][ii-1], "" ); } else { if( me.Max[primary] / me.Parent.Zoom[primary] < gg[2] + gg +[1] / 3 ) innerTextOV( me.Text[idx][0], "" ); } } while( ii < 11 ) { _OAV( me.Line[idx][ii], "visibility", "hidden" ); _OAV( me.Text[idx][ii], "visibility", "hidden" ); ii++; } }
Where first six lines are the call sites and the rest the fully parameterised function.
And the best bit: IT WORKS!
The names need work, but that's true for all the names in the library. And a job for tomorrow.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Six way diff?
by bitingduck (Deacon) on Apr 24, 2015 at 22:53 UTC | |
by Anonymous Monk on Apr 24, 2015 at 23:46 UTC | |
by SuicideJunkie (Vicar) on Apr 24, 2015 at 23:58 UTC | |
|
Re: Six way diff?
by tonto (Friar) on Apr 24, 2015 at 23:25 UTC | |
by Anonymous Monk on Apr 24, 2015 at 23:47 UTC | |
by tonto (Friar) on Apr 25, 2015 at 00:13 UTC | |
by Anonymous Monk on Apr 25, 2015 at 01:01 UTC | |
by MidLifeXis (Monsignor) on Apr 25, 2015 at 11:55 UTC | |
| |
|
Re: Six way diff? (gvim 4 way)
by Anonymous Monk on Apr 24, 2015 at 23:24 UTC | |
|
Re: Six way diff?
by Marshall (Canon) on Apr 25, 2015 at 01:06 UTC |