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

数年間とりあえず普通に動いている自作のプログラムを眺めていたらおかしな部分を見つけました。これは修正しないでそのまま使えますか?
また、このプログラムを見て疑問に思ったのですが、★の部分、nextとreturnはどちらでもこの場合同じ挙動になりますか?
なお、以下コードをテストして見る限り同じような挙動に見えます。


use strict;
$| = 1;
for(1..50){
print ;
&Test($_);
sleep 1;
}
sub Test(){
my $a = shift @_;
for(1..2){
print ".";
}
if($a % 2 == 0){
print "2";
# next; #★
# return ; #★
}
print "*\n";
}

A 回答 (2件)

通常は使えません。


next は「現在のループを中段して次のループへ移動する」もの
returnは「現在の関数を終了して呼び出し側に戻る」もの
と、動作はまったく違います。

http://perldoc.jp/func/next%20LABEL
> ブロック自身は一回だけ実行されるループと文法的に同一であることに 注意してください。
> 従って、next はそのようなブロックから早く抜けるのに使えます。

とあるので、

next で、 sub(){} のブロック(=1回だけのループ)の次のループに移行する
→ 2回目は無いのでループから抜ける(=sub(){}のブロックから抜ける=subを終了する)

という動作をしていて、見掛け上は subを終了する return と同じに見えるのでしょう。

ですが、

{
if($a % 2 == 0){
print "2";
# next; #★
# return ; #★
}
}
print "*\n";

と、一つブロックを深くすると
next : 一番違いブロックを抜ける: print "*\n"; が実行される
return : subを抜ける : print "*\n"; は実行されない
と違いが出てきます。

また
> next は eval {}, sub {}, do {} のように値を返す ブロックから抜けるのには使えません;

とマニュアルに書いてあります。
今回は値を返さないsubなので影響はありませんが。
    • good
    • 0
この回答へのお礼

回答いただきありがとうございます。
とても、とても勉強になりました!
これは酷い誤作動を招きますね。
逆に今この状態で長年動いているということはこの誤作動でうまく回っている可能性もありますし慎重に修正しようと思います。

お礼日時:2018/12/30 08:50

こんばんは。

Perlを勉強している者です。
質問のプログラムを実行して見ると、確かに、同じ動作をしていますね。
next if の様な使い方でなく、単に、nextとreturnだったので、
同じ挙動になってくれたのではないでしょうか?。

勉強になりました。有難う御座います。m(_ _)m
    • good
    • 1
この回答へのお礼

コメントいただきありがとうございます。ただ、間違った使い方ですし副作用がないものか不安で質問させていただいています。ただ、大昔に書いた動いているプログラムを直すのは怖いです^^

お礼日時:2018/12/29 18:21

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