Is there an inf constant in Perl? - perl

I'm initialising a list with infinities for an algorithm. Writing $x = 9**9**9 feels unintuitive, and also, I might want to use BigInt in the future. 1/0 throws an error.
What's the canonical way to get inf?

You can use the special string "inf":
perl -E'say "inf" + 1'
inf
perl -E'say 1 / "inf"'
0
et cetera.
Other special strings include +inf, -inf, nan. Of course this also works with bignum or bigint pragmas. However, these pragmas export equivalent functions inf and NaN so that you can use barewords.
Edit
As #ikegami pointed out, there doesn't seem to be a portable way of accomplishing true infinities without a module. I just waded through this interesting perlmonks thread, but it doesn't get less confusing. Perhaps the best solution would be to accept the performance penalty and use big{num,int,rat} from the start, but use no big{num,int,rat} in scopes where they aren't required.

I've used bigrat to do this. It's hard to tell what features -E is enabling.
use bigrat;
use feature qw(say);
say inf + inf;
say 9**99 / -inf(); #Perl doesn't always like "-inf" by itself
use bigrat; has been around for a long time, so it should be pretty portable.

Related

perl: log rounding weirdness

How can I tell perl that:
print (log(1000)/log(10)."\n");
print int(log(1000)/log(10))."\n";
should both give 3 (and not 2 which the last one surprisingly gives)?
I know why this happens (binary floats are not decimal floats). So I am not asking WHY it happens. I am asking HOW to tell perl to "do the right thing".
Neither log(1000) nor log(10) can be accurately represented by a floating point number, so you end up with something a little less than 3.
$ perl -e'CORE::say sprintf "%.20f", log(1000)/log(10)'
2.99999999999999955591
You want to round instead of truncating.
A solution is to abuse stringification.
say int("".(log(1000)/log(10)));
say int("".(log(1000000)/log(10)));
Or you could use sprintf (slower than stringification above).
say sprintf("%.0f", log(1000)/log(10));
say sprintf("%.0f", log(1000000)/log(10));

perl: what is the right way to call a function stored in a variable?

What is the right way to call a function stored in a variable?
my $f = sub () { ... };
&$f(); # 1st
$f->(); # 2nd
Both appear to work, and the first probably worked in perl4.
However, I was wondering what the "official perl5 way" was.
Also, are there any performance implications?
Both are the right way. Perl is not about forcing any special style down your throat.
Style #1 &$f()
Pro:
Emphasizes that we are using a subroutine
Con:
Looks like line noise
Overrides function templates
Seems a bit perl4-ly to me
Caveats:
In the dark ages of perl4, there were no references. One could simulate references by passing around variable names (*shudder*). This also works with subs, so this code runs:
sub f { (shift == 0) ? 1 : 0 }
$g = "f";
print &$g(1); # prints 0;
print &$g(0); # prints 1;
Please use strict 'refs' to guard against this horror.
Style #2 $f->()
Pro:
Emphasizes that we are handling a reference
Looks cleaner
Con:
can be confused with objects and hashrefs
Caveats:
Same as with the other syntax, as they are the same under the hood. But the dereference operator is not misused as often.
Performance implications
Lets face it, if we were all about performance, we would be writing assembler. If you want to optimize Perl, first optimize the algorithm, then code everything in C/XS, throw away any objects and modules, and finally discuss dereferencing syntax.
I would guess style #1 is faster in theory, but I doubt it would have serious implications in real life.
I sincerely doubt there are any differences performance, since both methods result in the same code:
$ perl -MO=Deparse -e'&$f()'
&$f();
-e syntax OK
$ perl -MO=Deparse -e'$f->()'
&$f();
-e syntax OK

Evaluating escape sequences in perl

I'm reading strings from a file. Those strings contain escape sequences which I would like to have evaluated before processing them further. So I do:
$t = eval("\"$t\"");
which works fine. But I'm having doubt about the performance. If eval is forking a perl process each time, it will be a performance killer. Another way I considered to do the job were regex, where I have found related questions in SO.
My question: is there a better, more efficient way to do it?
EDIT: before calling eval in my example $t is containing \064\065\x20a\n. It is evaluated to 45 a<LF>.
It's not quite clear what the strings in the file look like and what you do to them before passing off to eval. There's something missing in the explanation.
If you simply want to undo C-style escaping (as also used in Perl), use Encode::Escape:
use Encode qw(decode);
use Encode::Escape qw();
my $string_with_unescaped_literals = decode 'ascii-escape', $string_with_escaped_literals;
If you have placeholders in the file which look like Perl variables that you want to fill with values, then you are abusing eval as a poor man's templating engine. Use a real one that does not have the dangerous side effect of running arbitrary code.
$string =~ s/\\([rnt'"\\])/"qq|\\$1|"/gee
string eval can solve the problem too, but it brings up a host of security and maintenance issues, like # in string
oh gah don't use eval for this, thats dangerous if someone provides it with input like "system('sync;reboot');"..
But, you could do something like this:
#!/usr/bin/perl
$string = 'foo\"ba\\\'r';
printf("%s\n", $string);
$string =~ s/\\([\"\'])/$1/g;
printf("%s\n", $string);

What is the CORE:match (opcode) subroutine in Perl profiling?

I previously wrote some utilities in Perl, and I am now rewriting them in order to give some new/better features. However, things seem to be going much more slowly than in the original utilities, so I decided to run one with the NYTProf profiler. Great profiler btw, still trying to figure out all its useful features.
So anyway, it turns out that 93% of my program's time is being spent on calls to the GeneModel::CORE:match (opcode) subroutine, and I have no idea what this is. Most Google hits point to NYTProf profiles others have posted. I indeed wrote the GeneModel class/package, but I don't know what this subroutine is, why it was called so many times, or why it's taking so long. Any ideas?
CORE:match is a call to a regular expression -- in this case, within your GeneModel package.
For example, if we profile this script, Devel::NYTProf reports 1000 calls to Foo::CORE:match.
use strict;
use warnings;
package Foo;
my $s = 'foo foo';
$s =~ /foo/ for 1 .. 1000;
Perl is compiled to opcodes. The match operator results in a match opcode.
> perl -MO=Terse -e'm//'
LISTOP (0x8c4b40) leave [1]
OP (0x8c4070) enter
COP (0x8c4780) nextstate
PMOP (0x8c4260) match
This is not a subroutine, but merely represented that way as opcode profiling is a recent addition and the UI hasn't been overhauled yet to take that into account. In simple words, the profiler is telling you that most time is spent in the regex engine.

Perl version string: why use EVAL EXPR?

I just took notice to this generated by Catalyst.pl. It is obviously some sort of unannotated hack. What is the advantage of setting up a version string like this? I can't even figure out what they're trying to do.
our $VERSION = '0.01';
$VERSION = eval $VERSION;
Version numbers are complex in Perl. Here's an excellent overview for those looking for the gory details. It might surprise you how many subtle ways there are to get things wrong...
The direct answer to your question though, is that different things expect different formats. For CPAN, you care about development versions for example, as a string. For runtime, you care about them as a number.
Consider the case of $VERSION = "0.01_001". eval converts it to the number 0.01001 correctly.
From perlmodstyle: Version numbering
If you want to release a 'beta' or
'alpha' version of a module but don't
want CPAN.pm to list it as most recent
use an '_' after the regular version
number followed by at least 2 digits,
eg. 1.20_01. If you do this, the
following idiom is recommended:
$VERSION = "1.12_01";
$XS_VERSION = $VERSION; # only needed if you have XS code
$VERSION = eval $VERSION;
With that trick MakeMaker will only
read the first line and thus read the
underscore, while the perl interpreter
will evaluate the $VERSION and convert
the string into a number. Later
operations that treat $VERSION as a
number will then be able to do so
without provoking a warning about
$VERSION not being a number.
The eval converts the string "0.001_001" to a number, following the rules for Perl numeric literals (which allow underscores for legibility). The result is the number 0.001001.
Without the eval, the string is converted to a number following the rule for converting strings, which stops at the first non-numeric character.
E.g.: perl -e 'print "0.001_001" + 0'
I may be misremembering this, but I think some automated code parsers like to see the line of code:
our $VERSION = '0.01';
But you really want $VERSION to hold a float instead of a string.
You may want to read this article, I know I am going to.
Oh, dear god, now I remember why I use
our $VERSION = 20100903;
style version numbers. That is just insane. I love Perl, but that is pure, refined, concentrated insanity. I won't try to summarize David Golden's article. You just have to read it and cry.