0

I'm trying to get rid of a warning message, which has the following explanation in perldiag:

Bareword "%s" refers to nonexistent package (W bareword) You used a qualified bareword of the form "Foo::", but the compiler saw no other uses of that namespace before that point. Perhaps you need to predeclare a package?

(The problem is that I have a subroutine which blesses an object into a package which is declared later)

I want to follow the advice in the manual page, by "predeclaring" the package, but I can't figure out how to do this. What is the syntax to predeclare a package in Perl?

Metamorphic
  • 732
  • 6
  • 16
  • Can you provide a short working example of the failing code, for testing? – zdim Oct 08 '19 at 20:25
  • I don't know how to make that happen, `perl -Mstrict -wE'sub tt { return bless { one=>1 }, "PackName" }; my $obj = tt(); say ref $obj'` duly prints `PackName`. Otherwise, I'd imagine that `BEGIN { package PackName {}; }` should introduce it ... – zdim Oct 08 '19 at 20:29
  • @zdim `package` obviously has a compile-time effect, so no need for `BEGIN`. – ikegami Oct 08 '19 at 20:58
  • @ikegami heh, right. got lead astray by testing (here unrelated issues) in one unit (and in one-liner) – zdim Oct 08 '19 at 21:47

2 Answers2

2

Your problem is not predeclaring the package (which you can do by simply declaring the package in a scope by itself), but that bless just takes a string, and you don't need to use the uncommon bareword syntax Foo:: to create it (thus triggering the warning).

bless $obj, 'Foo';
Grinnz
  • 9,093
  • 11
  • 18
  • You may assume I am describing the same (human|parser) tokenization as in your recent post: https://stackoverflow.com/questions/58263206/how-does-perl-parse-unquoted-bare-words/58263207 – Grinnz Oct 08 '19 at 21:16
  • I believe a more precise definition of bareword based on its usage in the documentation and community would be simply "unquoted identifier". "bareword filehandles" being one of the more common examples, or the bareword taken by require/use rather than a string. – Grinnz Oct 08 '19 at 21:25
  • "identifier" implies it's a name or some other kind of identifier. "unquoted word" is what I used in the aforementioned question. I'll all for this more general use, because there really isn't any other word for it. – ikegami Oct 08 '19 at 21:27
  • 'identifier' is actually also a specific term defined here: https://perldoc.pl/perldata#Identifier-parsing - it is a little fuzzy on whether a sigil is considered part of the identifier, but the same grammar applies to many of these cases. – Grinnz Oct 08 '19 at 21:32
  • I adopt the same view of identifiers as I do of file names. Sometimes they're qualified, sometimes they're not, and the name can be used for either. – ikegami Oct 08 '19 at 21:34
2

Foo:: is identical to 'Foo' except that it warns if the package doesn't exist.

You could silence the warning by creating the package. Both of the following statements achieve this:

{ package Foo; }

package Foo { }   # 5.14+

But that's very hackish. Why use a syntax that performs a package check if you're just going to defy the check? It would be far better to use the following:

my $self = bless({}, 'Foo');

Another option is

no warnings qw( bareword );
my $self = bless({}, Foo::);

This signals to the reader that you know you are you are using a package that doesn't exist yet.

ikegami
  • 367,544
  • 15
  • 269
  • 518