さて今日はエラー メッセージをあえて出すコーナー、今日のお題は「"our" variable is redeclared」です。「our変数が再定義された(のはおかしい)」という意味です。
 エラー メッセージをABC順に制覇しているのですが、今日も『かんたんPerl』レベルでは出なくて、『すぐわかるオブジェクト指向Perl』レベルの警告です。
 (まあ、警告なんか出さないに越したことはないんですが…)

ペンギンは つつきます 手を出さないで下さい (18206891344)
 use strict宣言をすると、use strict "refs"(シンボリック リンクの禁止)、use strict "subs"(裸のワードの禁止)、use strict "vars"(無修飾の変数の禁止"という3つの禁止が同時に行われています。
 use strict "vars"で禁止されるのは、以下のようなプログラムです。
#! /usr/local/bin/perl
# lonelyVar.pl -- 修飾のない変数

#use strict; # あえて無効化
use warnings;
use 5.010;

$i = 3;
say "\$iは$iです!";

 実行します。

[sample]$ ./lonelyVar.pl
$iは3です!

 今はuse strictではないので怒られません。
 怒られてみます。

#! /usr/local/bin/perl
# lonelyVar2.pl -- 修飾のない変数(エラーになります)

use strict; # 有効化
use warnings;
use 5.010;

$i = 3;
say "\$iは$iです!";

 どうでしょう。

[sample]$ ./lonelyVar2.pl
Global symbol "$i" requires explicit package name at ./lonelyVar2.pl line 8.
Global symbol "$i" requires explicit package name at ./lonelyVar2.pl line 9.
Execution of ./lonelyVar2.pl aborted due to compilation errors.

 ちゃんと怒られました。

 $iはパッケージ修飾されていない、ということですね。
 どうすれば直るでしょう。
 そう、myですね。

#! /usr/local/bin/perl
# lonelyVar3.pl -- 修飾のない変数(OK)

use strict; # 有効化
use warnings;
use 5.010;

my $i = 3;
say "\$iは$iです!";

 どうだ。

[sample]$ ./lonelyVar3.pl
$iは3です!

 さて、プログラムはデフォルトでmainというパッケージに入っているので、こうしても動いたんです。

#! /usr/local/bin/perl
# lonelyVar4.pl -- 修飾のない変数(FQN)

use strict; # 有効化
use warnings;
use 5.010;

$main::i = 3;
say "\$iは$main::iです!";

 どうでしょうか。

[sample]$ ./lonelyVar4.pl
$iは3です!
[sample]$

 へぇー。
 ちなみに、my宣言しなくても、パッケージ修飾しなくても怒られない変数があって、それは$_、@_、@ARGV、$/、$a、$bなどのPerl組み込みの変数です。
 ($a、$bって何に使う変数か分かりますか?)

 それ以外の名前で、mainパッケージ以外で使うにはどうすればいいでしょうか。ここでは、よくあるパターンで、ファイルが2個に分けます。
 メインプログラムである

#! /usr/local/bin/perl
# ourVar.pl -- パッケージ変数を使う

use strict; # 有効化
use warnings;
use 5.010;

use makeVar;

say "\$makeVar::iは$makeVar::iです!";

と、パッケージモジュールである

#! /usr/local/bin/perl
# makeVar.pm -- パッケージ変数を作る

use strict;
use warnings;
use 5.010;

package makeVar;

our $i = 3;

say "パッケージ", __PACKAGE__, "において\$iを宣言しました。値は$iです";

です。実行します。

[sample]$ ./ourVar.pl
パッケージmakeVarにおいて$iを宣言しました。値は3です
$makeVar::iは3です!

 解説します。
 makeVar.pmでは最初にmakeVarパッケージを宣言しています。
 この中でour宣言をすると、そのパッケージに属する変数を定義できます。
 そのパッケージの中では、修飾無しでそれを使えます。

 ourVar.pmでは、makeVar.pmをuseし、その中のパッケージ変数$iを参照しています。
 その場合は、$makeVar::iと、パッケージ修飾しなければ使えません。
 パッケージ修飾を忘れて怒られてみてもいいですか。

#! /usr/local/bin/perl
# ourVar2.pl -- パッケージ変数を無修飾で使う(とエラー)

use strict; # 有効化
use warnings;
use 5.010;

use makeVar;

say "\$iは$iです!";

 どうですか。

[sample]$ ./ourVar2.pl
パッケージmakeVarにおいて$iを宣言しました。値は3です
Global symbol "$i" requires explicit package name at ./ourVar2.pl line 10.
Execution of ./ourVar2.pl aborted due to compilation errors.

 そのエラーさっきも見たわ!
 予定の行動ですね。

 さて、今日のお題のエラーは、our宣言がダブったというやつです。

#! /usr/local/bin/perl
# makeVar2.pm -- パッケージ変数を作る(エラー

use strict;
use warnings;
use 5.010;

package makeVar2;

our $i = 3;
our $i = "ROBOT"; # ここが怒られる!

say "パッケージ", __PACKAGE__, "において\$iを宣言しました。値は$iです";

 さっきうまくいったプログラムから、このpmを呼び出して実行してみます。

#! /usr/local/bin/perl
# ourVar3.pl -- パッケージ変数を使う

use strict; # 有効化
use warnings;
use 5.010;

use makeVar2; # ourを2回やってるやつ

say "\$makeVar2::iは$makeVar2::iです!";

 どうですか。

[sample]$ ./ourVar3.pl
"our" variable $i redeclared at makeVar2.pm line 11.
パッケージmakeVar2において$iを宣言しました。値はROBOTです
$makeVar2::iはROBOTです!

 わーいちゃんと怒られましたね。(マゾ…)
 怒られながらもちゃんと実行はされていて、2回めのour宣言とともに代入した値が入っています。