Astro-satpass
view release on metacpan or search on metacpan
lib/Astro/Coord/ECI/Utils.pm view on Meta::CPAN
true for a successful load. Results are cached, and subsequent attempts
to load the same module simply give the cached results.
=cut
{ # Local symbol block. Oh, for 5.10 and state variables.
my %error;
my %rslt;
sub load_module {
my ($module) = @_;
exists $error{$module} and croak $error{$module};
exists $rslt{$module} and return $rslt{$module};
# I considered Module::Load here, but it appears not to support
# .pmc files. No, it's not an issue at the moment, but it may be
# if Perl 6 becomes a reality.
$rslt{$module} = eval "require $module"
or croak( $error{$module} = $@ );
return $rslt{$module};
}
} # End local symbol block.
=item print local_strftime( $format, $epoch, $places )
This subroutine takes as input a strftime-compatible format and an
epoch, and returns the local time, formatted per the format.
Optional argument C<$places> is the default number of decimal places for
seconds. If defined, it must be either C<''> or an unsigned integer.
You can also specify an optional C<'.d'> (where the 'd' is one or more
decimal digits) before any format specification that generates seconds.
Examples include C<'%.3S'> or C<'%.6T'>. Such a specification overrides
the C<$places> argument, if any.
=cut
sub local_strftime {
my ( $format, $epoch ) = _pre_strftime( @_ );
return POSIX::strftime( $format, localtime $epoch );
}
=item $boolean = looks_like_number ($string);
This subroutine returns true if the input looks like a number. It uses
Scalar::Util::looks_like_number if that is available, otherwise it uses
its own code, which is lifted verbatim from Scalar::Util 1.19, which in
turn leans heavily on perlfaq4.
=cut
unless (eval {require Scalar::Util; Scalar::Util->import
('looks_like_number'); 1}) {
no warnings qw{once};
*looks_like_number = sub {
local $_ = shift;
# checks from perlfaq4
return 0 if !defined($_) || ref($_);
return 1 if (/^[+-]?[0-9]+$/); # is a +/- integer
return 1 if (/^([+-]?)(?=[0-9]|\.[0-9])[0-9]*(\.[0-9]*)?([Ee]([+-]?[0-9]+))?$/); # a C float
return 1 if ($] >= 5.008 and /^(Inf(inity)?|NaN)$/i)
or ($] >= 5.006001 and /^Inf$/i);
return 0;
};
}
=item $maximum = max (...);
This subroutine returns the maximum of its arguments. If List::Util can
be loaded and 'max' imported, that's what you get. Otherwise you get a
pure Perl implementation.
=cut
unless (eval {require List::Util; List::Util->import ('max'); 1}) {
no warnings qw{once};
*max = sub {
my $rslt;
foreach (@_) {
defined $_ or next;
if (!defined $rslt || $_ > $rslt) {
$rslt = $_;
}
}
$rslt;
};
}
=item $minimum = min (...);
This subroutine returns the minimum of its arguments. If List::Util can
be loaded and 'min' imported, that's what you get. Otherwise you get a
pure Perl implementation.
=cut
unless (eval {require List::Util; List::Util->import ('min'); 1}) {
no warnings qw{once};
*min = sub {
my $rslt;
foreach (@_) {
defined $_ or next;
if (!defined $rslt || $_ < $rslt) {
$rslt = $_;
}
}
$rslt;
};
}
=item $theta = mod2pi ($theta)
This subroutine reduces the given angle in radians to the range 0 <=
$theta < TWOPI.
=cut
sub mod2pi {return $_[0] - floor ($_[0] / TWOPI) * TWOPI}
=item $theta = mod360( $theta )
( run in 0.589 second using v1.01-cache-2.11-cpan-a49fcb8fa48 )