Perlのエラーメッセージのコーナー。
Perlのエラーメッセージが表示される最小のプログラムを書いて、どういうときにどう怒られるかを研究する。
家庭の事情が終息するまで、困ったときのエラーメッセージ頼みで進行します。
今回のお題は
ちなみにラクダ本の原著では「Ambigous use of %s resolved as %s」であったが%s1、%s2のように区別した。
いずれにも何らかの文字列が入る。
%sというのはprintfのテンプレートなので、本来%s1などと書くべきではないが、大目に見てください。

Perlのエラーメッセージが表示される最小のプログラムを書いて、どういうときにどう怒られるかを研究する。
家庭の事情が終息するまで、困ったときのエラーメッセージ頼みで進行します。
今回のお題は
Ambigous use of %s1 resolved as %s2である。
ちなみにラクダ本の原著では「Ambigous use of %s resolved as %s」であったが%s1、%s2のように区別した。
いずれにも何らかの文字列が入る。
%sというのはprintfのテンプレートなので、本来%s1などと書くべきではないが、大目に見てください。
これはSVの第1文型の英文で、受動態のbe動詞が略されている。
S(主語)Ambigous use of %s1
V(動詞)(is) resolved
M(修飾語)as %s
訳すと「%s1を曖昧に使っているが、これは %2のように解釈した」ということである。
あいまいなプログラムなんか書くのは結構たいへんである。
プログラミング言語は、常に人間の言うことを1つの意味で解釈する。
Perlなど、コンテキストがあるから適当に解釈してくれているんだろうと過大評価(あるいは過小評価)されているが、実際にはコンテキストの適用にも規則があって、それに従っているに過ぎない。
他にも、人間の書いたプログラムで曖昧な点があれば、Perlは「一応こう解釈してみました」と報告してくれる、というのがこのメッセージの趣旨だ。
いろいろなケースでこのメッセージが出るだろうが、ここではネットをサーチして分かった1件だけ述べる。
見るからにダメそうだが、ダメなりに実行していいですか。
二重引用符の中で$xというスカラーとkgという単位のつもりの文字列が融合してしまったのである。
解決法にはいくつかあるが、${x}と名前をブレース囲みにするのがその1つだ。
ところで、この$xのことを${x}と書く記法を、最初の代入文にも適用してみる。
これは、${x}という式には複数の解釈が成り立つが、一応$xとして解釈しておきましたよと告げてくれている。
use warningsプラグマを使わないと表示されない。
これは、xという演算子があることが原因である。
xというのは文字列を繰り返す演算子で、たとえば $foo = 'bar' x 3 と書くと $foo には「barbarbar」が入る。
この演算子が、引数なしに現れたのかもしれないけど、そんなのありえそうにはないから、その解釈は取らなかった、ということだ。
警告さえ無視すれば動くところではあるけど、警告は警告で気持ち悪いから、では直してみよう。
カンタンなのはxではなくもっと意味のあるワードにすることだ。
でも、よく考えたら、${weight}という記法は二重引用符の外でわざわざ使うことはない。
プログラムとしての完成版は
ともかく、xという文字1字だと、Perlは文字列反復演算子と紛れてまぎらわしいことが分かった。
この警告は珍しく、もっと他のパターンもあるだろうが把握していない。
また他で遭遇したらここで紹介する。
エラーメッセージが出たら、そのエラーメッセージが出る最小のコードと共に、自分のエラーメッセージコレクションとして取っておくことが大事だと思う。
関数や演算子や正規表現のサンプルコード(成功例)を取っておくことはよくやるが、失敗例も取っておくといいと思う。
ただ発表しないとリキが出ないのでその場合はこういうブログが有効だろう。
S(主語)Ambigous use of %s1
V(動詞)(is) resolved
M(修飾語)as %s
訳すと「%s1を曖昧に使っているが、これは %2のように解釈した」ということである。
あいまいなプログラムなんか書くのは結構たいへんである。
プログラミング言語は、常に人間の言うことを1つの意味で解釈する。
Perlなど、コンテキストがあるから適当に解釈してくれているんだろうと過大評価(あるいは過小評価)されているが、実際にはコンテキストの適用にも規則があって、それに従っているに過ぎない。
他にも、人間の書いたプログラムで曖昧な点があれば、Perlは「一応こう解釈してみました」と報告してくれる、というのがこのメッセージの趣旨だ。
いろいろなケースでこのメッセージが出るだろうが、ここではネットをサーチして分かった1件だけ述べる。
#! /usr/bin/perl上のプログラムは、$xというスカラーにぼくの体重82キロを書いて、最後にkgという単位を付けて表示している。
#
# weightControl.pl
use 5.10.0;
use warnings;
$x = 82;
say "Hello, I'm Perl! The number is $xkg";
見るからにダメそうだが、ダメなりに実行していいですか。
$ weightControl.pl要するに$xというスカラーと$xkgというスカラーが現れてしまっている。
Name "main::x" used only once: possible typo at ./weightControl.pl line 8.
Name "main::xkg" used only once: possible typo at ./weightControl.pl line 9.
Use of uninitialized value $xkg in concatenation (.) or string at ./weightControl.pl line 9.
Hello, I'm Perl! The number is
[perl]$
二重引用符の中で$xというスカラーとkgという単位のつもりの文字列が融合してしまったのである。
解決法にはいくつかあるが、${x}と名前をブレース囲みにするのがその1つだ。
#! /usr/bin/perl実行してみる。
#
# weightControl.pl
use 5.10.0;
use warnings;
$x = 82;
say "Hello, I'm Perl! The number is ${x}kg";
$ weightControl.plOKだ。
Hello, I'm Perl! The number is 82kg
ところで、この$xのことを${x}と書く記法を、最初の代入文にも適用してみる。
#! /usr/bin/perl実行してみる。
#
# weightControl.pl
use 5.10.0;
use warnings;
${x} = 82;
say "Hello, I'm Perl! The number is ${x}kg";
$ weightControl.pl確かに警告が出た。
Ambiguous use of ${x} resolved to $x at ./weightControl.pl line 8.
Hello, I'm Perl! The number is 82kg
これは、${x}という式には複数の解釈が成り立つが、一応$xとして解釈しておきましたよと告げてくれている。
use warningsプラグマを使わないと表示されない。
これは、xという演算子があることが原因である。
xというのは文字列を繰り返す演算子で、たとえば $foo = 'bar' x 3 と書くと $foo には「barbarbar」が入る。
この演算子が、引数なしに現れたのかもしれないけど、そんなのありえそうにはないから、その解釈は取らなかった、ということだ。
警告さえ無視すれば動くところではあるけど、警告は警告で気持ち悪いから、では直してみよう。
カンタンなのはxではなくもっと意味のあるワードにすることだ。
#! /usr/bin/perl実行してみる。
#
# weightControl.pl
use 5.10.0;
use warnings;
${weight} = 82;
say "Hello, I'm Perl! The number is ${weight}kg";
$ weightControl.plOKだった。
Hello, I'm Perl! The number is 82kg
でも、よく考えたら、${weight}という記法は二重引用符の外でわざわざ使うことはない。
プログラムとしての完成版は
#! /usr/bin/perlであろう。
#
# weightControl.pl
use 5.10.0;
use warnings;
$weight = 82;
say "Hello, I'm Perl! The number is ${weight}kg";
ともかく、xという文字1字だと、Perlは文字列反復演算子と紛れてまぎらわしいことが分かった。
この警告は珍しく、もっと他のパターンもあるだろうが把握していない。
また他で遭遇したらここで紹介する。
エラーメッセージが出たら、そのエラーメッセージが出る最小のコードと共に、自分のエラーメッセージコレクションとして取っておくことが大事だと思う。
関数や演算子や正規表現のサンプルコード(成功例)を取っておくことはよくやるが、失敗例も取っておくといいと思う。
ただ発表しないとリキが出ないのでその場合はこういうブログが有効だろう。