Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Compare CODE

by PetaMem (Priest)
on Dec 11, 2012 at 11:22 UTC ( #1008270=perlquestion: print w/ replies, xml ) Need Help??
PetaMem has asked for the wisdom of the Perl Monks concerning the following question:

Hi!

Given two coderefs. Is there an (elegant) way to compare the code they're pointing to?

No, I don't need any fancy stuff like solving the halting problem. ;-) I do not even need to know if the code is equivalent. It would be completely sufficient if these

my $cr1 = sub { $foo = $bar * $baz; } my $cr2 = sub { $foo = $bar * $baz; }

Would be considered "same". Ideally with the whitespaces being irrelevant. All mutations, invariants etc. can safely be considered 'different'. i.e.

my $cr3 = sub { $mul = $op1 * $op2; } my $cr4 = sub { $foo = $baz * $bar; }

To sum up: It would be sufficient to have a function that - for two given coderefs (pointing to different addresses) - would just return "identic" if they'd be the same list of opcodes.

Howto? B:: something?

Thank you for your guidance.

Bye
 PetaMem
    All Perl:   MT, NLP, NLU

Comment on Compare CODE
Select or Download Code
Re: Compare CODE
by Athanasius (Abbot) on Dec 11, 2012 at 11:44 UTC

    I think you pretty much answered your own question: B::Deparse seems to do just what you want:

    #! perl use Modern::Perl; my ($foo, $bar, $baz, $mul, $op1, $op2); my $cr1 = sub { $foo = $bar * $baz; }; my $cr2 = sub { $foo = $bar * $baz; # Note whitespace differences }; my $cr3 = sub { $mul = $op1 * $op2; }; my $cr4 = sub { $foo = $baz * $bar; }; compare_subs($cr1, $cr2); compare_subs($cr3, $cr4); sub compare_subs { my ($s1, $s2) = @_; use B::Deparse; my $deparse = B::Deparse->new("-p", "-sC"); my $body1 = $deparse->coderef2text($s1); my $body2 = $deparse->coderef2text($s2); if ($body1 eq $body2) { say 'Identical'; } else { say 'Different'; } }

    Output:

    21:39 >perl 427_SoPW.pl Identical Different 21:40 >

    So, the initial results look promising, at least!

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      The only problem is closed-over variables...

      use strict; use warnings; use B::Deparse; sub make_multiplier { my $n = shift; return sub { $n * $_[0] }; } my $double = make_multiplier(2); my $treble = make_multiplier(3); print "double and treble clearly do different things...\n"; print "double 5: ", $double->(5), "\n"; print "treble 5: ", $treble->(5), "\n\n"; my $deparse = B::Deparse->new; $deparse->ambient_pragmas(strict => 'all', warnings => 'all'); print "yet, here is the B::Deparse output for double...\n"; print $deparse->coderef2text($double), "\n\n"; print "and here is the B::Deparse output for treble...\n"; print $deparse->coderef2text($treble), "\n"; __END__ double and treble clearly do different things... double 5: 10 treble 5: 15 yet, here is the B::Deparse output for double... { $n * $_[0]; } and here is the B::Deparse output for treble... { $n * $_[0]; }
      perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (9)
As of 2015-07-02 01:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (25 votes), past polls