From ad3af58cb976a13a4a46b5a3ae6fac87c97e8288 Mon Sep 17 00:00:00 2001 From: James E Keenan Date: Wed, 27 Sep 2017 20:34:09 -0400 Subject: [PATCH] Document that POSIX::abs, ::alarm, ::atan2, ::chdir need explicit argument. Add tests which demonstrate that those functions, plus POSIX::localtime, perform same as equivalent core builtins provided they get an explicit argument (as they cannot rely on an implicit $_). For: RT #132145 --- ext/POSIX/lib/POSIX.pod | 36 ++++++++++++----- ext/POSIX/t/usage.t | 88 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 10 deletions(-) diff --git a/ext/POSIX/lib/POSIX.pod b/ext/POSIX/lib/POSIX.pod index 9d2c0320d62f..c520903358c2 100644 --- a/ext/POSIX/lib/POSIX.pod +++ b/ext/POSIX/lib/POSIX.pod @@ -81,8 +81,13 @@ if the handler does not return normally (it e.g. does a C). =item C -This is identical to Perl's builtin C function, returning -the absolute value of its numerical argument. +This is identical to Perl's builtin C function, returning the absolute +value of its numerical argument (except that C must be provided +an explicit value (rather than relying on an implicit C<$_>): + + $absolute_value = POSIX::abs(42); # good + + $absolute_value = POSIX::abs(); # throws exception =item C @@ -110,8 +115,13 @@ L. =item C -This is identical to Perl's builtin C function, -either for arming or disarming the C timer. +This is identical to Perl's builtin C function, either for arming or +disarming the C timer, except that C must be provided +an explicit value (rather than relying on an implicit C<$_>): + + POSIX::alarm(3) # good + + POSIX::alarm() # throws exception =item C @@ -203,8 +213,14 @@ integer value greater than or equal to the given numerical argument. =item C -This is identical to Perl's builtin C function, allowing -one to change the working (default) directory, see L. +This is identical to Perl's builtin C function, allowing one to +change the working (default) directory -- see L -- with the +exception that C must be provided an explicit value (rather +than relying on an implicit C<$_>): + + $rv = POSIX::chdir('path/to/dir'); # good + + $rv = POSIX::chdir(); # throws exception =item C @@ -960,13 +976,13 @@ POSIX.1-2008 and are only available on systems that support them. This is identical to Perl's builtin C function for converting seconds since the epoch to a date see L except that C must be provided an explicit value (rather than -relying an implicit C<$_>: +relying on an implicit C<$_>): - @localtime = POSIX::localtime(time); # Good + @localtime = POSIX::localtime(time); # good - @localtime = localtime(); # Good + @localtime = localtime(); # good - @localtime = POSIX::localtime(); # Throws exception + @localtime = POSIX::localtime(); # throws exception =item C diff --git a/ext/POSIX/t/usage.t b/ext/POSIX/t/usage.t index 4d900e7680a4..3719686368ab 100644 --- a/ext/POSIX/t/usage.t +++ b/ext/POSIX/t/usage.t @@ -45,4 +45,92 @@ foreach my $func (qw(printf sprintf)) { "POSIX::$func for 0 arguments gives expected error"); } +# Tests which demonstrate that, where the POSIX.pod documentation claims that +# the POSIX function performs the same as the equivalent builtin function, +# that is actually so (assuming that the POSIX::* function is provided an +# explicit argument). + +my $val; + +{ + # abs + $val = -3; + is(abs($val), POSIX::abs($val), + 'abs() and POSIX::abs() match when each is provided with an explicit value'); +} + +{ + # alarm + my ($start_time, $end_time, $core_msg, $posix_msg); + + $val = 2; + local $@; + eval { + local $SIG{ALRM} = sub { $end_time = time; die "ALARM!\n" }; + $start_time = time; + alarm $val; + + # perlfunc recommends against using sleep in combination with alarm. + 1 while (($end_time = time) - $start_time < 6); + alarm 0; + }; + alarm 0; + $core_msg = $@; + + local $@; + eval { + local $SIG{ALRM} = sub { $end_time = time; die "ALARM!\n" }; + $start_time = time; + POSIX::alarm($val); + + # perlfunc recommends against using sleep in combination with POSIX::alarm. + 1 while (($end_time = time) - $start_time < 6); + POSIX::alarm(0); + }; + POSIX::alarm(0); + $posix_msg = $@; + + is($posix_msg, $core_msg, + "alarm() and POSIX::alarm() match when each is provided with an explicit value"); +} + +{ + # atan2 + my ($y, $x) = (3, 1); + is(POSIX::atan2($y, $x), atan2($y, $x), + "atan2() and POSIX::atan2() match; need 2 args"); +} + +{ + # chdir + require File::Spec; + + my $curdir = File::Spec->curdir(); + my $tdir = File::Spec->tmpdir(); + + my ($coredir, $posixdir); + + chdir($tdir) or die "Unable to change to a different starting directory"; + chdir($curdir); + $coredir = File::Spec->curdir(); + + chdir($tdir) or die "Unable to change to a different starting directory"; + POSIX::chdir($curdir); + $posixdir = File::Spec->curdir(); + + is($posixdir, $coredir, + "chdir() and POSIX::chdir() match when each is provided with an explicit value"); +} + +{ + # localtime + my (@lt, @plt); + + $val = 300_000; + @lt = localtime($val); + @plt = POSIX::localtime($val); + is_deeply(\@plt, \@lt, + 'localtime() and POSIX::localtime() match when each is provided explicit value'); +} + done_testing();