Perlのエラーメッセージのコーナー。
Perlのエラーメッセージが表示される最小のプログラムを書いて、どういうときにどう怒られるかを研究する。
今回のお題は
Perlのエラーメッセージが表示される最小のプログラムを書いて、どういうときにどう怒られるかを研究する。
今回のお題は
Bad evalled substitution patternである。
evalledという言葉は英和辞典にはない。
evalならある。
これはevaluation(評価)の略語であると書いている。
evaluate(評価する)という言葉は、あるもののvalue(価値)を計る、ということだろう。
Perlにはevalという関数がある。
これは、引数(文字列)をPerlプログラムとして評価し、その戻り値を返す。
最も簡単な使い方は、引数を評価して戻り値を印字する。
$ARGV[0]というのはプログラムの第1引数だが、eval関数はそれをPerlのプログラムとして評価する。
1+2という式を評価すると3になる。
(1+2)*3を評価すると9になる。
sqrt 1+2は、sqrt 3で、3の平方根だから、人並みにおごれやで1.73205080756888になる。
前から思ってたけど「人並みにおごれや」ってどういう時に使うセリフだろう。
さて、正規表現のオプションにも/eというのがある。
正規表現によるマッチ、置換の後ろに付けるオプションを修飾子(しゅうしょくし、modifier)と言う。
修飾子と打ち間違えないように注意しよう。
/eという修飾子を置換演算子s///で使うと、置換側がプログラムとして評価される。
まず、/eを使わないプログラムを実験する。
今、下のようなプログラムがあったとする。
s///演算子は、置換(substitution)を行う。
\dは数字(digit)1桁(0〜9)にマッチする。
+は量指定子(りょうしていし、quantifire。漁師停止と誤変換しないように注意)というもので、\d+と書くと1桁以上の数字列(数値)にマッチする。
パターンの中に()と書くと、$1、$2、$3。。という変数にマッチした部分が捕獲(キャプチャー)される。
ということで、長々と書いたが、
だから、__DATA__の下の
この時点で十分便利という気がするが、やはり数式を計算した答えを出したい。
この場合は、s///演算子をこう変える。
これは、置換側の文字列「$1*1.08」、たとえばチョコレートの場合は「200*1.08」を、プログラムとして評価した値にする。
よって、計算結果で置換されたのである。
では、おまちかね、このプログラムで人工的なエラーを発生させてみよう。
置換文字列の中に、余計な}が入っていたために、見事エラーになった。
なお、プログラムの間違いの場合によってはこのエラーにならず、余計な}の場合このエラーになるとラクダ本に書いてある。
ラクダ本はつくづく親切だ。
evalならある。
これはevaluation(評価)の略語であると書いている。
evaluate(評価する)という言葉は、あるもののvalue(価値)を計る、ということだろう。
Perlにはevalという関数がある。
これは、引数(文字列)をPerlプログラムとして評価し、その戻り値を返す。
最も簡単な使い方は、引数を評価して戻り値を印字する。
#! /usr/bin/perl使ってみる。
#
# calc.pl --- 最も安易な電卓プログラム
say eval $ARGV[0];
$ calc.pl 1+21+2、(1+2)*3、√3という式が計算されて表示される。
3
$ calc.pl '(1+2)*3'
9
$ calc.pl 'sqrt 1+2'
1.73205080756888
$ARGV[0]というのはプログラムの第1引数だが、eval関数はそれをPerlのプログラムとして評価する。
1+2という式を評価すると3になる。
(1+2)*3を評価すると9になる。
sqrt 1+2は、sqrt 3で、3の平方根だから、人並みにおごれやで1.73205080756888になる。
前から思ってたけど「人並みにおごれや」ってどういう時に使うセリフだろう。
さて、正規表現のオプションにも/eというのがある。
正規表現によるマッチ、置換の後ろに付けるオプションを修飾子(しゅうしょくし、modifier)と言う。
修飾子と打ち間違えないように注意しよう。
/eという修飾子を置換演算子s///で使うと、置換側がプログラムとして評価される。
まず、/eを使わないプログラムを実験する。
今、下のようなプログラムがあったとする。
#! /usr/bin/perl実行する。
#
# eTest.pl --- 消費税を計算したい
use 5.010;
use strict;
use warnings;
while (<DATA>) {
s/(\d+)/$1*1.08/;
print;
}
__DATA__
チョコレートは200円です。
ガムは100円です。
建売住宅は20000000円です。
$ eTest.plこのように、__DATA__の下に書いた文の金額部分が「数値*1.08」という数式に変わっている。
チョコレートは200*1.08円です。
ガムは100*1.08円です。
建売住宅は20000000*1.08円です。
s/(\d+)/$1*1.08/;がキモだ。
s///演算子は、置換(substitution)を行う。
s/パターン/置換文字列/;のように書くと、デフォルト変数$_の中で、正規表現パターンにマッチした文字列を、置換文字列で変換する。
\dは数字(digit)1桁(0〜9)にマッチする。
+は量指定子(りょうしていし、quantifire。漁師停止と誤変換しないように注意)というもので、\d+と書くと1桁以上の数字列(数値)にマッチする。
パターンの中に()と書くと、$1、$2、$3。。という変数にマッチした部分が捕獲(キャプチャー)される。
ということで、長々と書いたが、
s/(\d+)/$1*1.08/;は、$_の中の1桁以上の数字列を、その数字列の後ろに「*1.08」を付けたもので置換する。
だから、__DATA__の下の
チョコレートは200円です。という文字列は、
チョコレートは200*1.08円です。と置換された。
この時点で十分便利という気がするが、やはり数式を計算した答えを出したい。
この場合は、s///演算子をこう変える。
s/(\d+)/$1*1.08/e;実行してみる。
$ eTest.plあははうまくいった。
チョコレートは216円です。
ガムは108円です。
建売住宅は21600000円です。
これは、置換側の文字列「$1*1.08」、たとえばチョコレートの場合は「200*1.08」を、プログラムとして評価した値にする。
よって、計算結果で置換されたのである。
では、おまちかね、このプログラムで人工的なエラーを発生させてみよう。
#! /usr/bin/perl実行してみる。
#
# eTest.pl --- /e修飾子
use 5.010;
use strict;
use warnings;
while (<DATA>) {
s/(\d+)/$1*1.08}/e;
print;
}
__DATA__
チョコレートは200円です。
ガムは100円です。
建売住宅は20000000円です。
$ eTest.plこれが見たかった!
Bad evalled substitution pattern at ./eTest.pl line 10.
置換文字列の中に、余計な}が入っていたために、見事エラーになった。
なお、プログラムの間違いの場合によってはこのエラーにならず、余計な}の場合このエラーになるとラクダ本に書いてある。
ラクダ本はつくづく親切だ。