Reputation: 1
I want to know how to force the resolution of subs at compile time.
For some background, with perl, I can resolve package symbols strictly at compile-time using a ::
affixed to the end of the package name. For example.
perl -wE'use warnings FATAL => "bareword"; die 7; Foo::; die 42'
Bareword "Foo::" refers to nonexistent package at -e line 1.
You'll notice in the above code, we didn't die with 7 or 42. We died before the run-time phase. This only works to resolve the package name. I can use a method resolution operator (->
) with the above syntax and resolve a function name in run-time,
perl -E'use warnings FATAL => "bareword"; die 7; Foo::->bar(); die 42'
Bareword "Foo::" refers to nonexistent package at -e line 1.
But this isn't exactly what I want,
If I declare a package Foo
that lacks a sub bar
and I want to call the non-existent function bar
inside that package, I will no longer get a compile-time error,
perl -E'package Foo {}; use warnings FATAL => "bareword"; die 7; Foo::->bar(); die 42'
7 at -e line 1.
You can see here, when ()
is affixed to the end of the symbol it resolves in run-time; but, when ::
is affixed to the end of a symbol though it's assumed to be a package name it's resolved in compile-time.
The ->
operator is using run-time method resolution. It searches @ISA
, and also provides a first argument of the class.
What I would like is to die if Foo
doesn't have bar
sub in compile-time.
Upvotes: 0
Views: 270
Reputation: 9231
Calling a function without parentheses will attempt to resolve the symbol in the parsing phase, this also includes fully-qualified symbols. The tricky part is what happens when it doesn't resolve. Under use strict 'subs', it will die due to bareword strings being disallowed.
use strict;
use warnings;
Foo::bar; # Bareword "Foo::bar" not allowed while "strict subs" in use
This gets trickier when there are arguments. It still attempts to parse it as a bareword string, and so may report a syntax error when it's followed by something that wouldn't make sense there.
use strict;
use warnings;
Foo::bar 42; # Number found where operator expected
Other times it parses it as an indirect method call, which then postpones the error to runtime, or may even end up doing something you didn't expect.
use strict;
use warnings;
my $foo;
Foo::bar $foo; # Can't call method "bar" on an undefined value
Basically, Perl tries really hard to figure out what the syntax was supposed to mean and so doesn't always end up with a useful error message when it doesn't work.
Upvotes: 3