忘れた頃に出てくるPerlのエラーメッセージのコーナー。
今回は
今回は
"our" variable %s is redeclaredである。
これはSVCの形式の英文だ。
(S:主語)"our" variable %s/our変数%sは
(V:動詞)is/である
(C:補語)redeclared/再定義された
redeclaredは動詞redeclareの過去分詞系である。
redeclareはdeclare(定義する)にreを付けたもので、再定義された、という意味になる。
Perlではuse strict "vars"を書かないと、宣言なしに変数を登場させることが出来る。
しかし、use strict "vars"を書いて、変数について厳しい姿勢でプログラミングに臨むことを宣言すると、変数は以下のいずれかである必要がある。
・$_、@INCのようにmainパッケージにもともと備え付けの変数
・myで宣言されたレキシカル変数
・ourで宣言されたグローバル変数
・$Find::File::nameのような完全修飾名
なお、use strictには他にuse strict "refs"(シンボリックリンクの禁止)、use strict "subs"(裸のワードの禁止)がある。
単にuse strict;と書くと"vars"、"refs"、"subs"が一挙に禁止される。
プログラムを書くときは常にuse strict;およびuse warnings;(ちょっとしたことでも警告する)を常にオンにして、あらゆる診断メッセージを出すようにしておくのがおすすめだ。
さて、ourで宣言されたグローバル変数とはなんだろう。
プログラム例を挙げる。
実行するとこうである。
答は55だ。
便利だなー。
sumNumbers.plはメインプログラム、MyNumUtil.pmはモジュールファイルである。
簡単のため、これら2つのファイルは両方ともC:\Perl\perlという同じフォルダーに入れるとする。
(上のプログラム表記は全角スペースでインデントを表現しているので注意)
さて、上のプログラムには、先に述べた変数の4パターンがすべて入っている。
まず、
・$_、@INCのようにmainパッケージにもともと備え付けの変数
は
いずれもPerlの設計によって備え付けられている変数である。
・myで宣言されたレキシカル変数
はメインプログラム、モジュールの両方で定義された$sumがそうだ。
これらはそれぞれ、自分が定義されたスコープの中でしか参照できない。
メインプログラムの$sumはファイルsumNumbers.pl全体である。
モジュールの$sumはサブルーチンMyNumUtil::sumNumbersの中である。
これらは同じ名前だが赤の他人であり、別のメモリ空間に格納される。
だから安心して使えるのである。
さて、
・ourで宣言されたグローバル変数
・$Find::File::nameのような完全修飾名
はペアで使う。
モジュールファイルで宣言した変数をメインプログラムでも使いたいとき、モジュールファイルの中ではour宣言して、メインプログラムではそれを完全修飾名(FQN:Fully Qualified Name)で参照する。
上のプログラムでは、MyNumUtil.pmの中で
これでMyNumUtilモジュールの変数を、useするプログラムに露出することが出来る。
では今日のお題のエラーメッセージはどうやったら出せるだろうか。
(別にエラーメッセージなんか出したくないが・・・)
こうしてみる。
実行してみる。
これは警告で、プログラムはちゃんと実行され、計算結果55と共に、2回目の方のバージョン番号1.1が表示されている。
こんな失敗するのかいなという気もするが、長い複雑なプログラムを書けば、そういうことも起きるかもしれない。
(S:主語)"our" variable %s/our変数%sは
(V:動詞)is/である
(C:補語)redeclared/再定義された
redeclaredは動詞redeclareの過去分詞系である。
redeclareはdeclare(定義する)にreを付けたもので、再定義された、という意味になる。
Perlではuse strict "vars"を書かないと、宣言なしに変数を登場させることが出来る。
しかし、use strict "vars"を書いて、変数について厳しい姿勢でプログラミングに臨むことを宣言すると、変数は以下のいずれかである必要がある。
・$_、@INCのようにmainパッケージにもともと備え付けの変数
・myで宣言されたレキシカル変数
・ourで宣言されたグローバル変数
・$Find::File::nameのような完全修飾名
なお、use strictには他にuse strict "refs"(シンボリックリンクの禁止)、use strict "subs"(裸のワードの禁止)がある。
単にuse strict;と書くと"vars"、"refs"、"subs"が一挙に禁止される。
プログラムを書くときは常にuse strict;およびuse warnings;(ちょっとしたことでも警告する)を常にオンにして、あらゆる診断メッセージを出すようにしておくのがおすすめだ。
さて、ourで宣言されたグローバル変数とはなんだろう。
プログラム例を挙げる。
#! /usr/local/bin/perl
# sumNumbers.pl --- 数字を加算する
use strict;
use warnings;
use MyNumUtil;
use 5.10.0;
my @num = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
my $sum = &MyNumUtil::sumNumbers(@num);
say "配列の合計は", $sum;
say "MyNumUtilのバージョンは", $MyNumUtil::version;
# MyNumUtil.pm --- 数字のユーティリティ関数集(現状は1個)
package MyNumUtil;
use strict;
use warnings;
our $version = "1.0";
sub sumNumbers {
my $sum = 0;
for (@_) {
$sum += $_;
}
return $sum;
}
1;
実行するとこうである。
C:\Perl\perl>sumNumbers.plモジュールMyNumUtil.pmに入っている数字を加算するサブルーチンsumNumbersを使って、1から10まで加算してみた。
配列の合計は55
MyNumUtilのバージョンは1.0
答は55だ。
便利だなー。
sumNumbers.plはメインプログラム、MyNumUtil.pmはモジュールファイルである。
簡単のため、これら2つのファイルは両方ともC:\Perl\perlという同じフォルダーに入れるとする。
(上のプログラム表記は全角スペースでインデントを表現しているので注意)
さて、上のプログラムには、先に述べた変数の4パターンがすべて入っている。
まず、
・$_、@INCのようにmainパッケージにもともと備え付けの変数
は
for (@_) {の中で@_(サブルーチンの引数を参照する変数)、$_(いろいろな用途があるが、ここではforループの制御変数を省略したときに制御変数になる)を使っている。
$sum += $_;
}
いずれもPerlの設計によって備え付けられている変数である。
・myで宣言されたレキシカル変数
はメインプログラム、モジュールの両方で定義された$sumがそうだ。
これらはそれぞれ、自分が定義されたスコープの中でしか参照できない。
メインプログラムの$sumはファイルsumNumbers.pl全体である。
モジュールの$sumはサブルーチンMyNumUtil::sumNumbersの中である。
これらは同じ名前だが赤の他人であり、別のメモリ空間に格納される。
だから安心して使えるのである。
さて、
・ourで宣言されたグローバル変数
・$Find::File::nameのような完全修飾名
はペアで使う。
モジュールファイルで宣言した変数をメインプログラムでも使いたいとき、モジュールファイルの中ではour宣言して、メインプログラムではそれを完全修飾名(FQN:Fully Qualified Name)で参照する。
上のプログラムでは、MyNumUtil.pmの中で
our $version = "1.0";とour宣言したのを、sumNumbers.plの中で
say "MyNumUtilのバージョンは", $MyNumUtil::version;とFQNで使っている。
これでMyNumUtilモジュールの変数を、useするプログラムに露出することが出来る。
では今日のお題のエラーメッセージはどうやったら出せるだろうか。
(別にエラーメッセージなんか出したくないが・・・)
こうしてみる。
# MyNumUtil.pm --- 数字のユーティリティ関数集(現状は1個)太字の部分が余計である。
package MyNumUtil;
use strict;
use warnings;
our $version = "1.0";
our $version = "1.1";
sub sumNumbers {
my $sum = 0;
for (@_) {
$sum += $_;
}
return $sum;
}
1;
実行してみる。
C:\Perl\perl>sumNumbers.plMyNumUtil.pmの中のour変数$versionが、2回定義されたので2回目が警告されている。
"our" variable $version redeclared at MyNumUtil.pm line 9.
配列の合計は55
MyNumUtilのバージョンは1.1
これは警告で、プログラムはちゃんと実行され、計算結果55と共に、2回目の方のバージョン番号1.1が表示されている。
こんな失敗するのかいなという気もするが、長い複雑なプログラムを書けば、そういうことも起きるかもしれない。