アプリ版:「スタンプのみでお礼する」機能のリリースについて

main.cgi:
require './a.cgi';
RequireFile('./b.cgi');

a.cgi:
sub RequireFile {
require $_[0];
SubXXX;
}

b.cgi:
sub SubXXX {
return;
}
このような3つのcgiファイルがあったときサブルーチンの定義はうまく行われるでしょうか
main.cgiから処理が行われる順に説明を受けたいです
よろしくお願いします

質問者からの補足コメント

  • どう思う?

    main.pl:
    require './a.pl';
    RequireFile('./b.pl');

    a.pl:
    sub RequireFile {
    require $_[0];
    &SubXXX;
    }
    1;

    b.pl:
    sub SubXXX {
    print "sub SubXXX at b.pl\n";
    }
    1;

    これでうまくprint文が実行されました。しかしa.plの&SubXXXの&を取り除いてSubXXXを呼び出すとprint文は実行されませんでした。わかりませんでした。なぜなのか。
    require文というのはC言語の#include文のように実行前に展開されるのではなく、1行ずつ実行しながら展開しているのでしょうか?
    そのあたりの実行の仕組みを知りたいです。

    No.1の回答に寄せられた補足コメントです。 補足日時:2022/10/30 18:49

A 回答 (2件)

まず Perl では「スクリプトの読み込み」→「解析」→「実行」の順に処理が行われる. そして, require は, その require 文が実行されるときに指定したスクリプトを読み込む. だから, この例だと b.pl は RequireFile の中の


require $_[0];
を実行したときに読み込まれる... というか, そうでないと b.pl が読み込めない.

次に RequireFile の中の
&SubXXX;
なり
SubXXX;
なりだけど, これは Perl の歴史的な事情で解釈が違う. つまり, 「&SubXXX;」は「サブルーチン SubXXX を呼び出す」という意味であるのに対し, 「SubXXX;」は「解析の時点でサブルーチン SubXXX が定義されていればそれを呼び出す」という意味になる (定義されていないときには「bareword」として「単なる文字列」の扱いになる). 余談だけど, サブルーチンのリファレンスを作るときに \&subroutine のように書くのは「サブルーチンを呼び出すときに必ず & を付けていた」時代の名残りでもある.

ということで, &SubXXX; になっている場合は「実行がそこに到達する」までにサブルーチン SubXXX が (b.pl を読み込むことによって定義されるので) 期待通りに実行される. 一方で SubXXX; だと「解析をする = a.pl を読み込んだ」時点ではそのようなサブルーチンを知らないので, 「サブルーチン SubXXX の呼び出し」とは解釈されずその結果として print も実行されない, ということになる.

なお「じゃあ main.pl の RequireFile('./b.pl'); はどうなんだ」ということになる (解析の時点では RequireFile というサブルーチンを知らない) が, これは「かっこがあるのでサブルーチン呼び出しである」と解釈されたんだと思う.
    • good
    • 0
この回答へのお礼

助かりました

回答ありがとうございます
難しいですけどとてもわかりやすく理解できました
kansha;
sub kansha{
print "ありがとうございます¥n";
}

お礼日時:2022/10/31 21:58

「サブルーチンの定義」は「うまく」できるだろうけど....



RequireFile の
SubXXX;
のところで (設定によっては) 警告またはエラーが出るかもね.

まあ, 実際にやってみればいいんじゃないかな.
この回答への補足あり
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
そうですよね実際に試してみます

お礼日時:2022/10/30 18:11

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!