Perlの「Bareword "%s" not allowed while "strict subs" in use~」というエラーについて
Perlの「Bareword "%s" not allowed while "strict subs" in use~」というエラーについて紹介します。
1.はじめに
下記のようなコードがあります。
#!/usr/bin/perl
use strict;
my $data;
$data->{foo-1} = "bar";
このコードを実行したところ次のエラーが出力されました。
Bareword "foo" not allowed while "strict subs" in use at test.pl line 5.
このエラーについて、perldoc.jpのエラー一覧には次のように記されていますが、書かれている意味が分かりません。
"strict subs" が有効の場合、裸の単語はサブルーチンの識別子、 中かっこの中、シンボル "=>" の左側でのみ許されます。 おそらくサブルーチンを先行宣言する必要があるのでは?
ということでエラーの原因も分かりません。
2.エラーの原因
まずサンプルコードに、
use strict;
と書かれてあります。
strictは「安全ではないコンストラクトを制限するプラグマ」で、記述したコードを厳格にチェックしてくれるものです。
この1行を記述することで、下記の3つが機能します。
use strict "vars";
use strict "refs";
use strict "subs";
エラーメッセージに表示されている「strict subs」は、上記3つめの「use strict "subs"」を指しています。
perldoc.jpの説明では、「use strict "subs"」は
詩的な最適化を禁止し、サブルーチン以外の裸の識別子を使おうとしたときか、 (コロンのない)単純な識別子や中括弧の中 => シンボルの左側に無いときにコンパイル時エラーを出します。
となっています。
「詩的な最適化」とは「use strict; を使う理由」からの引用で、
Perlのコンパイル中にトークン(文字列、数値、演算子、関数、変数などなど)に分類できない文字の並びに出くわしたとき、適当に解釈してくれる機能です。
ということらしいです。
ひとつ前の説明にある「裸の識別子」は意味が分かりにくいのですが、エラーメッセージの「Bareword」がこれにあたると思われます。
「Bareword」は「引用符で括られていない単語」を指します。
上記より「Bareword "foo" not allowed while "strict subs" in use~」は、
引用符が付かないワード「foo」は、「use strict "subs"」を使っている間は使用が許されない
といった意味になります。
3.対処
つまり、サンプルコードを次のようにfooに引用符をつけることでエラーが解消します。
#!/usr/bin/perl
use strict;
my $data;
$data->{'foo'-1} = "bar";
エラーは解消しますが、このサンプルでは「foo-1」という名前をハッシュのキーにしたいと思われるので、実際には下記のように「foo-1」全体に引用符をつけるのが正しい対処です。
#!/usr/bin/perl
use strict;
my $data;
$data->{'foo-1'} = "bar";
ということで、use strictを使っている場合、ハッシュのキーにハイフンが含まれるときは必ず引用符で括る必要があります。
2021/12/23追記
ハッシュのキーにピリオドが含まれる場合も、同様のエラーが発生します。こちらも引用符で括る必要があります。
#!/usr/bin/perl
use strict;
my $data;
$data->{'foo.1'} = "bar";
- Perlでansibleライブラリを作成する方法
- perlのCPANモジュールからRPMを作成する方法
- Perlで「Subroutine permission redefined at~」を抑止する方法
- XML::Simpleのインストールでエラーになる場合の対処
- YAML::Tinyで「YAML::Tiny found bad indenting in line~」というエラーになる場合の対処
- Perlの正規表現を使って文字列をまとめて取得する方法
- Perlのハッシュでキーの有無を調べる方法
- perlで配列の途中の要素を削除する方法
- YAML::Tinyでコロンを利用する方法
- Perlで改行コードがCRのファイルを読み込む方法
- Perlで「Possible precedence issue with control flow operator」という警告の対処
- PerlのLWPで「Can't verify SSL peers without knowing which Certificate Authorities to trust」というエラーになったときの対処
- Perl+Windowsでファイルを再帰的にリネームする方法
- Perlプログラムの中でファイルの一部を書き換える方法
- Perlで文字列結合しながらs///演算子で置換する方法