Perl 初心者です。初めて質問します。
test_sub.pl で宣言した変数を test_main.pl から参照したくて悩んでいます。
環境 : WindowsXP / ActivePerl 5.14.2
--------------------
* test_sub.pl
--------------------
#!/usr/bin/perl
use strict;
our $hoge = 'HOGE';
1;
--------------------
* test_main.pl
--------------------
#!/usr/bin/perl
use strict;
require 'test_sub.pl';
print "Content-type: text/html\n\n";
print $hoge;
--------------------
これを実行すると、
Global symbol "$hoge" requires explicit package name at C:/public_html/cgi-bin/test_main.pl line 7.\r
というエラーが出ます。
require する前に、test_main.pl のほうで our($hoge); と宣言したり
参照する際に print $main::hoge; とパッケージを指定したりすればいけるのですが、
これらをしないとできないものなのでしょうか。
use strict; を書かなければ最初のソースでも動くのですが use strict は書きたい…
継承のようなことをしたいのです。
ちなみに以下試してみたソースです。
--------------------
* test_main.pl
--------------------
#!/usr/bin/perl
########################################
# NG
use strict;
require 'test_sub.pl';
print "Content-type: text/html\n\n";
print $hoge;
########################################
# OK our変数を宣言しておくといける
=pod
use strict;
our ($hoge);
require 'test_sub.pl';
print "Content-type: text/html\n\n";
print $hoge;
=cut
########################################
# OK 参照する際にパッケージ名を指定すればいける
=pod
use strict;
require 'test_sub.pl';
print "Content-type: text/html\n\n";
print $main::hoge;
=cut
########################################
########################################
# NG
=pod
use strict;
use base qw(test_sub);
print "Content-type: text/html\n\n";
print $hoge;
=cut
########################################
--------------------
* test_sub.pm
--------------------
#!/usr/bin/perl
package test_sub;
use strict;
our $hoge = 'HOGE';
1;
--------------------
NG パタンはどちらも Global symbol "$hoge" requires explicit package name のエラーとなります。
もしご存じの方がいらっしゃいましたら教えてください。
よろしくお願いします。
No.1ベストアンサー
- 回答日時:
端的に言えば「our するなりパッケージで修飾するなりしてください」となります.
詳細はこんな感じ:
このエラーはコンパイル時のエラーであって実行時のエラーではありません. つまり, 実行に先立つコンパイルのときに「use strict が有効なのに my も our も state もされていない (かつパッケージ名での修飾もされていない) 変数 $hoge が現れた」というエラーです.
「require されたファイルの中に our がある」のは確かですが, 次の 2つの理由によりそれは影響しません:
・use とは異なり, require によるファイルの取り込みは実行時に行われます. つまり
require 'test_sub.pl';
とあってもコンパイラは test_sub.pl の中は見ません. したがって「test_sub.pl の中の our」はコンパイル時には影響を与えません.
・また, our の有効範囲はレキシカルスコープに制限されています. そして「1つのソースファイル」はレキシカルスコープとなりますから, require をコンパイル時に行っても「test_sub.pl の中の our」は test_sub.pl の中 (もちろん our 以降の) でしか有効ではありません.
余談ですが, use strict もレキシカルスコープで有効となります. つまり, 「test_sub.pl の中の use strict」はそれを require した test_main.pl では無効です (し, 逆に require する前に test_main.pl で use strict してもそれは test_sub.pl には影響しません)
> 端的に言えば「our するなりパッケージで修飾するなりしてください」となります.
やはりそうですか… ありがとうございます。
# パッケージで装飾のほうが良いかな… test_sub のほうで変数名変えられたりすると危ないし
# どうせパッケージで装飾するなら main じゃなくてちゃんと package 宣言しようかな
説明していただいた内容もすごくわかりやすかったです。
> use とは異なり, require によるファイルの取り込みは実行時に行われます
これについてはちらっと見かけたので use test_sub; にしてみたりもしたのですが
エラーが取れずもやもやしていました。が
> また, our の有効範囲はレキシカルスコープに制限されています.
> そして「1つのソースファイル」はレキシカルスコープとなりますから ...
この辺が絡んでくるのですね。理解しました。
とても助かりました。ありがとうございます m(_ _)m
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- JavaScript Javascript初心者|jQueryの.val()で値を取得し複数の要素を連結させる方法知りたい 2 2022/06/02 12:06
- その他(プログラミング・Web制作) VScodeでpythonプログラムの関数を実行したい 2 2022/07/13 19:24
- PHP PHPでCookieを使った訪問回数について 1 2023/05/28 14:10
- AJAX JavascriptからPHPへのAjax通信でnullが返ってくる 3 2022/08/03 22:00
- Java java final 1 2022/06/10 22:49
- C言語・C++・C# プログラミングのペーパーテスト 実行結果を表示せよ #include <stdio.h> int h 1 2022/07/09 15:27
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- PHP PostgreSQLからCSV形式でエクスポートする際にカラム内の改行をとる方法 1 2023/02/22 10:05
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
foreach 回数制限
-
Application.ScreenUpdating = ...
-
JSONで文字列が長い時
-
セレクトメニューで2つの項目...
-
メモリをアドレスを直接指定し...
-
文字の横にプルダウンを表示さ...
-
テーブル内でドロップダウンメ...
-
[Ruby] irbにおける文字化け
-
数値かどうかの判定方法
-
実行時エラー 3020の対策
-
エクセルVBA シート名の部分一...
-
変数名に変数を使用
-
formで特定のinputを送信しない...
-
phpでボタンを押したときに変数...
-
Python - Excel で Webからデー...
-
文字のカラーとフォントの指定...
-
子windowsからsubmit()後にclos...
-
【至急!!!】python言語で本を見...
-
FindFirst を複数条件で検索
-
16進の10進変換について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CLispのloop内の挙動について
-
Perlで自分自身の関数名を知る...
-
Net::Telnetでタイムアウト時間...
-
print <<"_HTML_"の中でサブル...
-
Rubyのgets関数について
-
10進数→2進数
-
CGI初心者です
-
Perlで複数の値を返す良い方法...
-
作業域が消える(ように見える)
-
検索機能の作成で困っています
-
Pythonのマルチプロセスでの並...
-
ハノイの塔の問題で困っており...
-
LISPで連想配列の操作?
-
PERLの「!=」と「=~」 or...
-
PerlでCabochaを呼び出すには(...
-
foreach 回数制限
-
シェルでawkを使い行数を取り出...
-
Wコロン
-
HASH(0xほげほげ)
-
プロトタイプ宣言のワーニング...
おすすめ情報