DaemonForums  

Go Back   DaemonForums > Miscellaneous > Programming

Programming C, bash, Python, Perl, PHP, Java, you name it.

Reply
 
Thread Tools Display Modes
  #1   (View Single Post)  
Old 6th February 2014
thirdm thirdm is offline
Spam Deminer
 
Join Date: May 2009
Posts: 248
Default double checks in pkg-config, openbsd

I'm looking at /usr/bin/pkg-config on OpenBSD. Is there a reason to write this ...

Code:
if (defined($ENV{PKG_CONFIG_LIBDIR}) && $ENV{PKG_CONFIG_LIBDIR}) {
	@PKGPATH = split(/:/, $ENV{PKG_CONFIG_LIBDIR});
} elsif (defined($ENV{PKG_CONFIG_PATH}) && $ENV{PKG_CONFIG_PATH}) {
	unshift(@PKGPATH, split(/:/, $ENV{PKG_CONFIG_PATH}));
}
... instead of this ...

Code:
if ($ENV{PKG_CONFIG_LIBDIR}) {
	@PKGPATH = split(/:/, $ENV{PKG_CONFIG_LIBDIR});
} elsif ($ENV{PKG_CONFIG_PATH}) {
	unshift(@PKGPATH, split(/:/, $ENV{PKG_CONFIG_PATH}));
}
?


As far as I can tell, in boolean context a hash entry that doesn't exist will yield false, as will an entry that's there but undef, as will one that's there but one of the other false values (0, "", "0"). Neither does it seem like referring to a non-existent element will either cause a warning or autovivify anything.
Reply With Quote
  #2   (View Single Post)  
Old 6th February 2014
jggimi's Avatar
jggimi jggimi is offline
More noise than signal
 
Join Date: May 2008
Location: USA
Posts: 7,977
Default

Disclaimer. I don't speak perl, and cannot answer the why question. I can, however, provide you with who, so that you can ask them directly, or send them both a patch for their consideration.

The original development was by Marc Espie (espie@), at revision 1.16:
Code:
Revision 1.16: download - view: text, markup, annotated - select for diffs
Thu Dec 14 10:23:34 2006 UTC (7 years, 1 month ago) by espie
Branches: MAIN
Diff to: previous 1.15: preferred, coloured
Changes since revision 1.15: +9 -7 lines
add PKG_CONFIG_LIBDIR, okay bernd@
Here is that patch:
Code:
--- src/usr.bin/pkg-config/pkg-config    2006/12/10 10:58:41    1.15
+++ src/usr.bin/pkg-config/pkg-config    2006/12/14 10:23:34    1.16
@@ -1,5 +1,5 @@
 #!/usr/bin/perl
-# $OpenBSD: pkg-config,v 1.15 2006/12/10 10:58:41 espie Exp $
+# $OpenBSD: pkg-config,v 1.16 2006/12/14 10:23:34 espie Exp $
 
 #$CSK: pkgconfig.pl,v 1.39 2006/11/27 16:26:20 ckuethe Exp $
 # Copyright (c) 2006 Chris Kuethe <ckuethe@openbsd.org>
@@ -24,17 +24,19 @@ use OpenBSD::PkgConfig;
 
 my @PKGPATH = qw(/usr/local/lib/pkgconfig /usr/X11R6/lib/pkgconfig );
 
-if (defined($ENV{'PKG_CONFIG_PATH'}) && $ENV{'PKG_CONFIG_PATH'}) {
-    push(@PKGPATH, split /:/, $ENV{'PKG_CONFIG_PATH'});
+if (defined($ENV{PKG_CONFIG_LIBDIR}) && $ENV{PKG_CONFIG_LIBDIR}) {
+    @PKGPATH = split /:/, $ENV{PKG_CONFIG_LIBDIR};
+} elsif (defined($ENV{PKG_CONFIG_PATH}) && $ENV{PKG_CONFIG_PATH}) {
+    push(@PKGPATH, split /:/, $ENV{PKG_CONFIG_PATH});
 }
 
 my $logfile = '';
-if (defined($ENV{'PKG_CONFIG_LOGFILE'}) && $ENV{'PKG_CONFIG_LOGFILE'}) {
-    $logfile = $ENV{'PKG_CONFIG_LOGFILE'};
+if (defined($ENV{PKG_CONFIG_LOGFILE}) && $ENV{PKG_CONFIG_LOGFILE}) {
+    $logfile = $ENV{PKG_CONFIG_LOGFILE};
 }
 
 my $allow_uninstalled = 
-    defined $ENV{'PKG_CONFIG_DISABLE_UNINSTALLED'} ? 0 : 1;
+    defined $ENV{PKG_CONFIG_DISABLE_UNINSTALLED} ? 0 : 1;
 my $found_uninstalled = 0;
 
 my $version = 0.19; # pretend to be this version of pkgconfig
@@ -45,7 +47,7 @@ my $variables = {};
 my $D = 0; # debug flag
 
 {
-    my $d = $ENV{'PKG_CONFIG_TOP_BUILD_DIR'};
+    my $d = $ENV{PKG_CONFIG_TOP_BUILD_DIR};
     if (defined $d) {
         $variables->{pc_top_builddir} = $d;
     } else {
The revision you question was 1.66, by Jasper Lievisse Adriaanse (jasper@):
Code:
Revision 1.66: download - view: text, markup, annotated - select for diffs
Thu Jun 16 08:38:30 2011 UTC (2 years, 7 months ago) by jasper
Branches: MAIN
Diff to: previous 1.65: preferred, coloured
Changes since revision 1.65: +18 -15 lines
- finally unconfuse emacs by using parentheses for split()
And here's that patch:
Code:
--- src/usr.bin/pkg-config/pkg-config    2011/06/16 09:33:54    1.65
+++ src/usr.bin/pkg-config/pkg-config    2011/06/16 09:38:30    1.66
@@ -1,5 +1,5 @@
 #!/usr/bin/perl
-# $OpenBSD: pkg-config,v 1.65 2011/06/16 08:33:54 jasper Exp $
+# $OpenBSD: pkg-config,v 1.66 2011/06/16 08:38:30 jasper Exp $
 # $CSK: pkgconfig.pl,v 1.39 2006/11/27 16:26:20 ckuethe Exp $
 
 # Copyright (c) 2006 Chris Kuethe <ckuethe@openbsd.org>
@@ -27,9 +27,9 @@ use OpenBSD::PkgConfig;
 my @PKGPATH = qw(/usr/lib/pkgconfig /usr/local/lib/pkgconfig /usr/X11R6/lib/pkgconfig);
 
 if (defined($ENV{PKG_CONFIG_LIBDIR}) && $ENV{PKG_CONFIG_LIBDIR}) {
-    @PKGPATH = split /:/, $ENV{PKG_CONFIG_LIBDIR};
+    @PKGPATH = split(/:/, $ENV{PKG_CONFIG_LIBDIR});
 } elsif (defined($ENV{PKG_CONFIG_PATH}) && $ENV{PKG_CONFIG_PATH}) {
-    unshift(@PKGPATH, split /:/, $ENV{PKG_CONFIG_PATH});
+    unshift(@PKGPATH, split(/:/, $ENV{PKG_CONFIG_PATH}));
 }
 
 my $logfile = '';
@@ -124,7 +124,7 @@ my $rc = 0;
 {
 my $p = join(' ', @ARGV);
 $p =~ s/^\s+//;
-@ARGV = split /\,?\s+/, $p;
+@ARGV = split(/\,?\s+/, $p);
 }
 
 if ($mode{myminvers}) {
@@ -211,9 +211,9 @@ if ($mode{variable}) {
 my $dep_cfg_list = simplify_and_reverse($cfg_full_list);
 
 if ($mode{cflags} || $mode{libs} || $mode{variable}) {
-    push @vlist, do_cflags($dep_cfg_list) if $mode{cflags};
-    push @vlist, do_libs($dep_cfg_list) if $mode{libs};
-    print join(' ', @vlist), "\n" if $rc == 0;
+    push @vlist, do_cflags($dep_cfg_list) if $mode{cflags};
+    push @vlist, do_libs($dep_cfg_list) if $mode{libs};
+    print join(' ', @vlist), "\n" if $rc == 0;
 }
 
 exit $rc;
@@ -256,7 +256,9 @@ sub handle_config
         }
     };
 
-    if (defined $mode{cflags} or $mode{static} or $mode{printrequiresprivate}) {
+    if (defined $mode{cflags}
+        or ($mode{static} && $mode{libs})
+        or $mode{printrequiresprivate}) {
         &$get_props("Requires.private");
     }
     &$get_props("Requires");
@@ -458,7 +460,8 @@ sub do_libs
         my $l = $configs{$pkg}->get_property('Libs', $variables);
         push(@$libs, @$l) if defined $l;
     }
-    
+
+    # Get the linker path directives (-L).
     my $a = OpenBSD::PkgConfig->compress($libs,
         sub {
             local $_ = shift;
@@ -476,7 +479,7 @@ sub do_libs
 
     if ($mode{libs} & 1) {
         my $b = OpenBSD::PkgConfig->rcompress($libs,
-            sub { shift =~ m/^-l/; });
+                sub { shift =~ m/^-l/; });
         return ($a, $b);
     } else {
         return $a;
@@ -533,7 +536,7 @@ Usage: $0 [options]
 --print-provides - print all the modules the given package provides
 --print-requires - print all the modules the given package requires
 --print-requires-private - print all the private modules the given package requires
---silence-errors - don't print error messages in case of error
+--silence-errors - don\'t print error messages in case of error
 --atleast-pkgconfig-version [version] - require a certain version of pkgconfig
 --cflags package [versionspec] [package [versionspec]]
 --cflags-only-I - only output -Iincludepath flags
@@ -560,8 +563,8 @@ sub self_version
     my ($v) = @_;
     my (@a, @b);
 
-    @a = split /\./, $v;
-    @b = split /\./, $version;
+    @a = split(/\./, $v);
+    @b = split(/\./, $version);
 
     if (($b[0] >= $a[0]) && ($b[1] >= $a[1])) {
         return 0;
@@ -593,8 +596,8 @@ sub compare
         $suffix_b[1] = $2;
     }
 
-    my @a = split /\./, $a;
-    my @b = split /\./, $b;
+    my @a = split(/\./, $a);
+    my @b = split(/\./, $b);
 
     while (@a && @b) { #so long as both lists have something
         if (!(@suffix_a || @suffix_b)) {
Reply With Quote
  #3   (View Single Post)  
Old 6th February 2014
thirdm thirdm is offline
Spam Deminer
 
Join Date: May 2009
Posts: 248
Default

The part that nagged me wasn't that there was an elsif, it was that it said...

if (defined(A) && A) ...

instead of just

if (A)

I think, for a check like this in boolean context, if it is the case that $ENV{SHELLVAR} is not in the hash or in the hash with an undefined value or in the hash with a blank or zero value, it's all the same as far as the condition and "if ($ENV{SHELLVAR})" covers it. My experiments seem to confirm this, but I could be missing something. Perl is pretty complicated when you try to analyze the dwim stuff.

It seems to have been this way since the first version by Chris Kuethe. Good of you to look to the history. I should have done that.

I'm a little wary sending this to misc. I've got this intuition this might be something that's really annoying for me to point out (though apparently not so annoying not to bother you guys with it ... sorry). The last person I want to annoy with novice Perl questions is Marc Espie. Pretty sure there's no practical harm or performance problem to the double check, it just bugs me reading it.

Maybe I could try the local Perl mongers see if they know why someone would write it this way.

Last edited by thirdm; 6th February 2014 at 07:18 PM. Reason: clarification
Reply With Quote
  #4   (View Single Post)  
Old 6th February 2014
ocicat ocicat is offline
Administrator
 
Join Date: Apr 2008
Posts: 3,318
Default

Quote:
Originally Posted by thirdm View Post
Maybe I could try the local Perl mongers see if they know why someone would write it this way.
My suggestion would be to post to http://perlmonks.org/.
Reply With Quote
  #5   (View Single Post)  
Old 6th February 2014
thirdm thirdm is offline
Spam Deminer
 
Join Date: May 2009
Posts: 248
Default

Quote:
Originally Posted by ocicat View Post
My suggestion would be to post to http://perlmonks.org/.
This post is kind of apropos to what I'm getting at: http://www.perlmonks.org/?node_id=680611

A difference between the code you've posted and the pkg-config case is that in your case you only need care if it's undefined before using the hash element. Had you wanted only to print "true" values and written ...

print "'$k'\t'$h{$k}'\n" if defined $h{$k} and $h{$k};

(or how about print "'$k'\t'$h{$k}'\n" if exists $h{$k} and defined $h{$k} and $h{$k}; )

... then I would be wondering why you hadn't simply written

print "'$k'\t'$h{$k}'\n" if $h{$k}

I can understand sprinkling extra defined checks around reflexively from getting yelled at by the Perl warnings. Maybe that's all it's about, plus C programmer instinct to guard against access to an undefined element, analogous to if (p && *p != '\0') ... . In which case, criticizing that practice might be annoying.

I'll look more closely at your script tonight, J65nko. My manager just got after me to make progress on what I'm supposed to be working on.
Reply With Quote
  #6   (View Single Post)  
Old 6th February 2014
ocicat ocicat is offline
Administrator
 
Join Date: Apr 2008
Posts: 3,318
Default

Quote:
Originally Posted by thirdm View Post
... then I would be wondering why you hadn't simply written

print "'$k'\t'$h{$k}'\n" if $h{$k}
Modify the posted code to the following:
Code:
$ cat test.pl                                                                                         
#!/usr/bin/env perl

use strict;
use warnings;
use Data::Dumper;

my %h = ( zero_value => 0, zero_string => '0', empty_string => '', undef_element => undef );

print Data::Dumper->Dump([\%h], [qw/h/]); 

print '=' x 4, $/;
for my $k (keys %h) {
    print "'$k'\t'$h{$k}'\n";
}

print '=' x 4, $/;
for my $k (keys %h) {
    print "'$k'\t'$h{$k}'\n" if $h{$k};
}
print '=' x 4, $/;
for my $k (keys %h) {
    print "'$k'\t'$h{$k}'\n" if defined $h{$k};
}
$ test.pl                                                                                             
$h = {
       'zero_value' => 0,
       'undef_element' => undef,
       'zero_string' => '0',
       'empty_string' => ''
     };
====
'zero_value'    '0'
Use of uninitialized value $h{"undef_element"} in concatenation (.) or string at ./autovivify.pl line 13.
'undef_element' ''
'zero_string'   '0'
'empty_string'  ''
====
====
'zero_value'    '0'
'zero_string'   '0'
'empty_string'  ''
$
Testing against the element's value all evaluates to false in these cases.

Last edited by ocicat; 6th February 2014 at 08:32 PM.
Reply With Quote
  #7   (View Single Post)  
Old 6th February 2014
J65nko J65nko is offline
Administrator
 
Join Date: May 2008
Location: Budel - the Netherlands
Posts: 4,128
Default

Right now, I don't have time to work on this anymore, but maybe somebody else has

A shell test program aptly called testit that sets the environment and calls that Perl snippet with some diagnostics:
Code:
#!/bin/sh

pkg_path='PKG_PATH=/home/p1:scp://j65nko@pkg_bulk.my.local:ftp://ftp.nluug.nl/pub/OpenBSD'
pkg_config_libdir='PKG_CONFIG_LIBDIR=/usr/bin/local/lib:/sbin/lib:/usr/sbin/lib'

env -i ${pkg_path} ${pkg_config_libdir}  ./wonder_why.pl
The wonder_why.pl program:
Code:
#!/usr/bin/perl

use warnings;
use strict;

my @PKGPATH;

sub show_env {
   print "The environment:\n===============\n";
   foreach my $key (sort keys %ENV) {
     print $key, '=', $ENV{$key}, "\n";
   } 
   print "===============\n\n";
}

sub pr_array {
    my $listref = shift;
    print "\n---- $listref -----\n";
    for (@$listref) {
       print;
       print " \n";
    }
    print "---- end of $listref -----\n";
}


sub orig {

        defined($ENV{PKG_CONFIG_LIBDIR}) ?  print "YES defined\n" : print "NOT defined\n"; 
        $ENV{PKG_CONFIG_LIBDIR} ? print "YES bare\n" : print "NO bare\n";

        if (defined($ENV{PKG_CONFIG_LIBDIR}) && $ENV{PKG_CONFIG_LIBDIR}) {
                print "\nPKG_CONFIG_LIBDIR test succeeded\n";
                @PKGPATH = split(/:/, $ENV{PKG_CONFIG_LIBDIR});
                pr_array(\@PKGPATH);
        } elsif (defined($ENV{PKG_CONFIG_PATH}) && $ENV{PKG_CONFIG_PATH}) {
                print "\nPKG_CONFIG_PATH test succeeded\n";
                unshift(@PKGPATH, split(/:/, $ENV{PKG_CONFIG_PATH}));
                pr_array(\@PKGPATH);
        }

}

sub new {
        if ($ENV{PKG_CONFIG_LIBDIR}) {
            @PKGPATH = split(/:/, $ENV{PKG_CONFIG_LIBDIR});
        } elsif ($ENV{PKG_CONFIG_PATH}) {
            unshift(@PKGPATH, split(/:/, $ENV{PKG_CONFIG_PATH}));
        }
}

show_env() ;
orig();
A test run:
Code:
$ ./testit
                                                                
The environment:
===============
PKG_CONFIG_LIBDIR=/usr/bin/local/lib:/sbin/lib:/usr/sbin/lib
PKG_PATH=/home/p1:scp://j65nko@pkg_bulk.my.local:ftp://ftp.nluug.nl/pub/OpenBSD
===============

YES defined
YES bare

PKG_CONFIG_LIBDIR test succeeded

---- ARRAY(0x1e4f00d83c88) -----
/usr/bin/local/lib 
/sbin/lib 
/usr/sbin/lib 
---- end of ARRAY(0x1e4f00d83c88) -----
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump
Reply With Quote
  #8   (View Single Post)  
Old 7th February 2014
thirdm thirdm is offline
Spam Deminer
 
Join Date: May 2009
Posts: 248
Default

Quote:
Originally Posted by J65nko View Post
Right now, I don't have time to work on this anymore, but maybe somebody else has
wonder_why.pl:
Code:
#!/usr/bin/perl

use warnings;
use strict;
use feature 'say';
my @PKGPATH = '/usr/lib/pkgconfig';

sub show_env {
   say "The environment:\n===============";
   foreach my $key (sort keys %ENV) {
     say $key, '=', $ENV{$key};
   } 
   say "===============\n";
}

sub orig {
        defined($ENV{PKG_CONFIG_LIBDIR}) ?  say "YES defined" : say "NOT defined"; 
        $ENV{PKG_CONFIG_LIBDIR} ? say "YES bare" : say "NO bare";

        if (defined($ENV{PKG_CONFIG_LIBDIR}) && $ENV{PKG_CONFIG_LIBDIR}) {
                say "\nPKG_CONFIG_LIBDIR test succeeded";
                @PKGPATH = split(/:/, $ENV{PKG_CONFIG_LIBDIR});
                { local $, = "\n"; say 'PKGPATH...', @PKGPATH }
        } elsif (defined($ENV{PKG_CONFIG_PATH}) && $ENV{PKG_CONFIG_PATH}) {
                say "\nPKG_CONFIG_PATH test succeeded";
                unshift(@PKGPATH, split(/:/, $ENV{PKG_CONFIG_PATH}));
                { local $, = "\n"; say 'PKGPATH...', @PKGPATH }
        }

}

sub new {
        defined($ENV{PKG_CONFIG_LIBDIR}) ?  say "YES defined" : say "NOT defined"; 
        $ENV{PKG_CONFIG_LIBDIR} ? say "YES bare" : say "NO bare";

        if ($ENV{PKG_CONFIG_LIBDIR}) {
	    say "\nPKG_CONFIG_LIBDIR test succeeded";
	    @PKGPATH = split(/:/, $ENV{PKG_CONFIG_LIBDIR});
	    { local $, = "\n"; say 'PKGPATH...', @PKGPATH }
        } elsif ($ENV{PKG_CONFIG_PATH}) {
	    say "\nPKG_CONFIG_PATH test succeeded";
	    unshift(@PKGPATH, split(/:/, $ENV{PKG_CONFIG_PATH}));
	    { local $, = "\n"; say 'PKGPATH...', @PKGPATH }
        }
}

show_env();
die unless @ARGV == 1;
#say 'running ', @ARGV;
no strict 'refs';
$ARGV[0]->();
say "\n";
testit
Code:
#!/bin/sh

pkg_config_libdir='PKG_CONFIG_LIBDIR=/usr/bin/local/lib:/sbin/lib:/usr/sbin/lib'
pkg_config_path='PKG_CONFIG_PATH=/usr/X11R6/lib/pkgconfig:/usr/X11R6/share/pkgconfig';

for fn in orig new; do
    {
	env -i ${pkg_config_libdir} ${pkg_config_path} ./wonder_why.pl $fn
	env -i ${pkg_config_path} ./wonder_why.pl $fn
    } | tee $fn.out
done

if cmp orig.out new.out; then
    echo Result: output identical
else
    diff -u orig.out new.out
fi
Output...
Code:
The environment:
===============
PKG_CONFIG_LIBDIR=/usr/bin/local/lib:/sbin/lib:/usr/sbin/lib
PKG_CONFIG_PATH=/usr/X11R6/lib/pkgconfig:/usr/X11R6/share/pkgconfig
===============

YES defined
YES bare

PKG_CONFIG_LIBDIR test succeeded
PKGPATH...
/usr/bin/local/lib
/sbin/lib
/usr/sbin/lib


The environment:
===============
PKG_CONFIG_PATH=/usr/X11R6/lib/pkgconfig:/usr/X11R6/share/pkgconfig
===============

NOT defined
NO bare

PKG_CONFIG_PATH test succeeded
PKGPATH...
/usr/X11R6/lib/pkgconfig
/usr/X11R6/share/pkgconfig
/usr/lib/pkgconfig


The environment:
===============
PKG_CONFIG_LIBDIR=/usr/bin/local/lib:/sbin/lib:/usr/sbin/lib
PKG_CONFIG_PATH=/usr/X11R6/lib/pkgconfig:/usr/X11R6/share/pkgconfig
===============

YES defined
YES bare

PKG_CONFIG_LIBDIR test succeeded
PKGPATH...
/usr/bin/local/lib
/sbin/lib
/usr/sbin/lib


The environment:
===============
PKG_CONFIG_PATH=/usr/X11R6/lib/pkgconfig:/usr/X11R6/share/pkgconfig
===============

NOT defined
NO bare

PKG_CONFIG_PATH test succeeded
PKGPATH...
/usr/X11R6/lib/pkgconfig
/usr/X11R6/share/pkgconfig
/usr/lib/pkgconfig


Result: output identical

$
Reply With Quote
  #9   (View Single Post)  
Old 6th February 2014
ocicat ocicat is offline
Administrator
 
Join Date: Apr 2008
Posts: 3,318
Default

Quote:
Originally Posted by thirdm View Post
As far as I can tell, in boolean context a hash entry that doesn't exist will yield false, as will an entry that's there but undef, as will one that's there but one of the other false values (0, "", "0"). Neither does it seem like referring to a non-existent element will either cause a warning or autovivify anything.
Unfortunately, I don't have as complete an answer as I would like, but I have probably coded similar ambiguities myself, & the following code demonstrates a common issue:
Code:
$ cat ./test.pl                                                                                         
#!/usr/bin/env perl

use strict;
use warnings;
use Data::Dumper;

my %h = ( zero_value => 0, zero_string => '0', empty_string => '', undef_element => undef );

print Data::Dumper->Dump([\%h], [qw/h/]); 

for my $k (keys %h) {
    print "'$k'\t'$h{$k}'\n";
}
print '=' x 4, $/;
for my $k (keys %h) {
    print "'$k'\t'$h{$k}'\n" if defined $h{$k};
}
$ chmod +x ./test.pl
$ ./test.pl                                                                                           
$h = {
       'zero_value' => 0,
       'undef_element' => undef,
       'zero_string' => '0',
       'empty_string' => ''
     };
'zero_value'    '0'
Use of uninitialized value $h{"undef_element"} in concatenation (.) or string at ./autovivify.pl line 12.
'undef_element' ''
'zero_string'   '0'
'empty_string'  ''
====
'zero_value'    '0'
'zero_string'   '0'
'empty_string'  ''
$
I agree that autovivification shouldn't be the issue (& those interested should review the documentation for defined()...), but I have been burnt by undefined hash elements before (as demonstrated by the example above...) which was alleviated by brute force use of defined().

So to further this hand-waving explanation, I would say that the practice is simply stylistic. Plus, I haven't taken the time to fully grok the CVS history.

Last edited by ocicat; 6th February 2014 at 07:40 PM. Reason: remove dangling articles... :)
Reply With Quote
Old 7th February 2014
J65nko J65nko is offline
Administrator
 
Join Date: May 2008
Location: Budel - the Netherlands
Posts: 4,128
Default

From the "Perl Cookbook" chapter about hashes by Christiansen and Torkington:

Quote:
... problems caused by confusing existence, definedness, and truth can multiply like rabbits.
They give the following example:
Code:
#!/usr/bin/perl

use warnings;
use strict;

my %age = ();
my $thing;

$age{'Toddler'} = 3;
$age{'Unborn'} = 0;
$age{'Phantasm'} = undef;

foreach $thing('Toddler', 'Unborn', 'Phantasm', 'Relic') { 
   print "$thing: ";
   print "Exists " if exists $age{$thing};
   print "Defined " if defined $age{$thing};
   print "True " if $age{$thing};
   print "\n";
}
The output:
Code:
Toddler: Exists Defined True 
Unborn: Exists Defined 
Phantasm: Exists 
Relic:
A summary of their explanation:

$age{'Unborn'} fails the truth test because the number 0 is one of Perl's false values.

$age{'Phantasm'} only exists because it has been given a value in the hash. Because that value is 'undef' it does not pass the test for definedness.
'undef' is also a Perl false value.
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump
Reply With Quote
Old 7th February 2014
thirdm thirdm is offline
Spam Deminer
 
Join Date: May 2009
Posts: 248
Default

Quote:
Originally Posted by J65nko View Post
A summary of their explanation:

$age{'Unborn'} fails the truth test because the number 0 is one of Perl's false values.

$age{'Phantasm'} only exists because it has been given a value in the hash. Because that value is 'undef' it does not pass the test for definedness.
'undef' is also a Perl false value.
And I'm saying that the pkg-config test's purpose is to look for toddlers to put in the pkg-path. That is, it spells out defined and not equal to blank (and also zero, so you can't put in a path of zero -- can't see that as a realistic need though) but if you view the cookbook example as a kind of truth table you can see that the defined test is redundant. It's only necessary to see if $ENV{VAR} is true before using it since not existing and existing as undef both evaluate to false.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
OpenBSD-5.4::PF config issue Atlantis OpenBSD Security 7 15th February 2014 01:30 PM
OpenBSD 5.3 X server config danielcrvg OpenBSD General 18 20th June 2013 01:03 AM
double nat routing giagni General software and network 5 22nd May 2009 07:10 PM
double posting? ocicat Feedback and Suggestions 6 26th May 2008 12:34 AM
openVPN 2.1_rc7 (server) on openBSD 4.3 config examples s2scott Guides 2 23rd May 2008 06:16 PM


All times are GMT. The time now is 09:38 PM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Content copyright © 2007-2010, the authors
Daemon image copyright ©1988, Marshall Kirk McKusick