in reply to (Golf) Warningless Comparison

There are a couple of problems with most of the solutions to this problem posted so far.

They look great when applied to $x and $y, but...

  1. Once you get the syntax for the hash references they don't look so golfed anymore,
  2. Unless I have translated them wrongly, they don't actually work. They all miss on the ff case because they don't test for the existance of the key in the old hash.

I couldn't get aristotle's to run, because of the error shown in the comment below his code.

I didn't test Jeurd's entry as I didn't have FreezeThaw installed. It seems like a complicated way of disabling warnings though?

The results:

C:\test>201391 Required: dd ff aa hh cc ------------------------------- BrowserUK golf: dd ff aa hh cc sauoq No warns: dd aa hh cc Sauoq golf: dd aa hh cc Elusion golf: aa cc dd BUK2 golf: dd ff aa hh cc

I attempted to translate the original code into a function where required and golf them all to an equal standard observing warnings, strict and safety. There maybe a few characters that could be trimmed from all of them without altering the original symantics.

The code:

#! perl -sw use strict; my %foo = ( aa => { O => 'zz', C => 'yy' }, bb => { O => 'xx', C => 'xx' }, cc => { O => undef, C => 'ww' }, dd => { O => 'vv', C => undef }, ee => { O => undef, C => undef }, ff => { C => undef }, gg => { O => 0, C => 0 }, hh => { O => undef, C => 0 }, ); sub BUK{ local($^W,$a)=(0,pop); grep{!exists$a->{$_}{O}or$a->{$_}{O}ne$a->{$_}{C}}keys %$a; } sub snw{ no warnings qw(uninitialized); my$h=pop; grep{$h->{$_}{O}ne$h->{$_}{C}}keys %$h; } sub sg_{ my$h=pop; # defined($x &&$y) &&$x eq$y grep{!(defined($h->{$_}{O}&&$h->{$_}{C})&&$h->{$_}{O}eq$h->{$_}{C} # ||!defined($x ||$y) ||!defined($h->{$_}{O}||$h->{$_}{C}))}%$h; } sub eg_{ my$h=pop; # (($x ||$;)eq($y ||$;)) grep{!(($h->{$_}{O}||$;)eq($h->{$_}{C}||$;))}%$h; } =pod sub ag_{ my$h=pop; grep sub{(1==grep defined,@_)or($_[0]ne$_[1])} ->(values @{$h->{$_}}['O','C']), keys %$h; } Type of arg 1 to values must be hash (not array slice) at C:\test\201391.pl line 26, near "])" =cut print " Required: dd ff aa hh cc\n"; print "-------------------------------\n"; print "BrowserUK golf: @{[BUK(\%foo)]}\n"; print "sauoq No warns: @{[snw(\%foo)]}\n"; print " Sauoq golf: @{[sg_(\%foo)]}\n"; print " Elusion golf: @{[eg_(\%foo)]}\n"; #print "Aristotle golf: @{[ag_(\%foo)]}\n"; =pod It seemed to me that the biggest problem with the original problem was + the method of recording the old versus changed hash--by adding an ex +tra key. Better I think to uses two hashes, %old and %change (or %o %o here). T +hat makes the problem of noting the changes somewhat clearer I think. + Though it does little better in the golf stakes. =cut my %o=(aa=>'zz', bb=>'xx', cc=>undef, dd=>'vv', ee=>undef, gg=>0, hh=> +undef,); my %c=(aa=>'yy', bb=>'xx', cc=>'ww', dd=>undef, ee=>undef, ff=>undef, +gg=>0, hh=>0,); sub comp{ local($^W, $a, $b)=(0, @_); grep{!exists$a->{$_} or $a->{$_} ne $b->{$_} } keys%$b; } print " BUK2 golf: @{[comp(\%o,\%c)]}\n";

Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring!

Replies are listed 'Best First'.
Re: Re: (Golf) Warningless Comparison
by demerphq (Chancellor) on Sep 29, 2002 at 19:31 UTC
    I went and updated your code to incorporate my solutions, and in the process added a bunch of cases. Unfortunately this also caused your solution to generate warnings. I find it a touch suprising that my longer solution is the only one that works correctly on all the cases. Guys youve got to be more thorough in your testing!
    use warnings; use strict; use Carp; local $SIG{__WARN__}=sub {die("\t@{[(caller(1))[3]]}() generated warni +ngs!\n")}; my $foo = { aa => { O => 'zz', C => 'yy' }, # bb => { O => 'xx', C => 'xx' }, cc => { O => undef, C => 'ww' }, # dd => { O => 'vv', C => undef }, # ee => { O => undef, C => undef }, ff => { C => undef }, gg => { O => 0, C => 0 }, hh => { O => undef, C => 0 }, # ii => { O => undef }, # jj => { O => 0, C => ' ' }, # kk => { O => ' ', C => 0 }, # ll => { O => undef, C => ' ' }, # mm => { O => ' ', C => undef }, # }; sub BUK{local($^W,$a)=(0,pop);grep{!exists$a->{$_}{O}or$a->{$_}{O}ne$a +->{$_}{C}}keys%$a} sub snw{no warnings qw(uninitialized);my$h=pop;grep{$h->{$_}{O}ne$h->{ +$_}{C}}keys %$h} sub sg_{my$h=pop;grep{!(defined($h->{$_}{O}&&$h->{$_}{C})&&$h->{$_}{O} +eq$h->{$_}{C}||!defined($h->{$_}{O}||$h->{$_}{C}))}%$h} sub eg_{my$h=pop;grep{!(($h->{$_}{O}||$;)eq($h->{$_}{C}||$;))}%$h} sub ddf{$a=pop;grep{$b=$$a{$_};defined$$b{O}!=defined$$b{C}||defined$$ +b{O}&&$$b{O}ne$$b{C}}keys%$a}#98 sub dex{$a=pop;grep{$b=$$a{$_};exists$$b{O}!=exists$$b{C}||defined$$b{ +O}!=defined$$b{C}||defined$$b{O}&&$$b{O}ne$$b{C}}keys%$a}#126 sub tad{my($h)=@_;grep{!exists($h->{$_}->{O})||(defined($h->{$_}->{O}) +?(defined($h->{$_}->{C})?($h->{$_}->{O}ne$h->{$_}->{C}):1):defined($h +->{$_}->{C}))}keys%$h}#162 print " Required: aa cc dd ff hh ii jj kk ll mm\n"; print "---------------------------------------------\n"; eval { print " tadman golf: @{[sort {$a cmp $b} tad($foo)]}\n"; }; print $@ if $@; eval { print "BrowserUK golf: @{[sort {$a cmp $b} BUK($foo)]}\n"; }; print $@ if $@; eval { print "sauoq No warns: @{[sort {$a cmp $b} snw($foo)]}\n"; }; print $@ if $@; eval { print " Sauoq golf: @{[sort {$a cmp $b} sg_($foo)]}\n"; }; print $@ if $@; eval { print " Elusion golf: @{[sort {$a cmp $b} eg_($foo)]}\n"; }; print $@ if $@; eval { print " Demerphq defd: @{[sort {$a cmp $b} ddf($foo)]}\n"; }; print $@ if $@; eval { print "Demerphq exist: @{[sort {$a cmp $b} dex($foo)]}\n"; }; print $@ if $@; __END__ Required: aa cc dd ff hh ii jj kk ll mm --------------------------------------------- tadman golf: aa cc dd ff hh jj kk ll mm main::BUK() generated warnings! sauoq No warns: aa cc dd hh jj kk ll mm Sauoq golf: aa cc dd hh jj kk ll mm Elusion golf: aa cc dd jj kk ll mm Demerphq defd: aa cc dd hh jj kk ll mm Demerphq exist: aa cc dd ff hh ii jj kk ll mm
    Hmm, maybe it isnt so suprising considering its the longest with the exception of only tadmans solution

    ;-)

    ---
    demerphq
    my friends call me, usually because I'm late....

      If you change the specs to the challenge, any thing is possible.

      My version does not produce warnings under the terms of the challenge. Note:the localisation and setting of $^W=0.


      Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring!
        If you change the specs to the challenge, any thing is possible.

        Advice you should take to heart. From the OP:

          Since warnings are supposed to be avoided, use strict; use warnings;

        My version does not produce warnings under the terms the unmodifies rules of the challenge. Note:the localisation and setting of $^W=0.

        The original terms of the challenge call for it to not produce warnings when run under use warnings. Yours does. The local $^W stuff doesnt have the effect you think it does when used under use warnings; It works the way you think it does when run under only "-w" but that isnt the same thing. It also doesnt work the way you think it does when run under both "-w" and use warnings;. From perllexwarn:

          If a piece of code is under the control of the warnings pragma, both the $^W variable and the -w flag will be ignored for the scope of the lexical warning.

        Also, next time try running the code before you get so insistant it works the way you think it does....

        --- demerphq
        my friends call me, usually because I'm late....

Re: Re: (Golf) Warningless Comparison
by Juerd (Abbot) on Sep 29, 2002 at 19:59 UTC

    I didn't test Juerd's entry as I didn't have FreezeThaw installed. It seems like a complicated way of disabling warnings though?

    I'm not interested in disabling warnings. I either avoid them, or don't care about them.

    I used FreezeThaw to demonstrate easier syntax.

    different if ( defined $x and defined $y and $x ne $y ) or not ( defined $x and defined $y );
    vs
    different if cmpStr($x, $y);

    - Yes, I reinvent wheels.
    - Spam: Visit eurotraQ.
    

      Firstly, sorry for mis-spelling your name.

      I also apologies for misunderstanding your intent. In the context of the thread, I looked at what FreezeThaw did, and couldn't see the difference between what it did in cmpStr($x,$y) and do{no warnings; $x eq $y). However, as I finally got FreezeThaw.pm installed on my system (actually just copied in as the install mechanism gave me inordanant troubles), I realise that it does more as my test script below shows.

      #! perl -sw use strict; use FreezeThaw qw(cmpStr freeze); sub asStr { return 'undef' if !defined $_[0]; return "''" if $_[0] eq ''; return '0' if $_[0] == 0; "$_[0]"; } my @x = (0,1,'',undef); my @y = (0,1,'',undef); print ' {$^W=0; ($x eq $y)', "\t", '!cmpStr($x,$y)', +$/; for my $x (@x) { for my $y (@y) { printf '%5s -v- %5s :', asStr($x), asStr($y); print "\t", do{local $^W=0;($x eq $y) ? 'Same' : 'Diff';}; print "\t\t",!cmpStr($x,$y) ? 'Same' : 'Diff', $/; } }

      Giving

      C:\test>test {$^W=0; ($x eq $y) !cmpStr($x,$y) 0 -v- 0 : Same Same 0 -v- 1 : Diff Diff 0 -v- '' : Diff Diff 0 -v- undef : Diff Diff 1 -v- 0 : Diff Diff 1 -v- 1 : Same Same 1 -v- '' : Diff Diff 1 -v- undef : Diff Diff '' -v- 0 : Diff Diff '' -v- 1 : Diff Diff '' -v- '' : Same Same '' -v- undef : Same Diff # Here! undef -v- 0 : Diff Diff undef -v- 1 : Diff Diff undef -v- '' : Same Diff # Here! undef -v- undef : Same Same 1:13:29.67 C:\test>

      Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring!