ルモーリン

Perlサンプル29 forとwhileが受け取るものと挙動の違い

投稿:2021-02-13

#!/usr/bin/env perl

use v5.26;
use utf8;
use warnings;
use strict;

use DateTime;
use Encode::Locale;

use FindBin;
use lib $FindBin::Bin;
use MyDumper;

use feature "say";
use open IO => ":utf8";

binmode STDOUT, ":encoding(console_out)";
binmode STDERR, ":encoding(console_out)";

$| = 1;

say "ファイルっぽいデータを全部読んだ後に未定義値が来る場合";
while (<DATA>) {
	chomp;
	say;
}

say "whileが未定義値を返す関数を呼ぶとループ0回";
say "【注意】undefは未定義値を返す関数";
my $count = 0;
while (undef) {
	$count++;
	say $count;
}

say "forループはリストを受け取り、その要素1個ずつで1ループ";
for (1, 2, 3, 4, 5) {
	say;
}

say "forループと違い、whileループはスカラを受け取り偽ならループしないで終了";
while (0) {
	say "たこルカは俺の嫁";
}

say "whileループはスカラを受け取り真ならループ継続";
$count = 0;
while (1) {
	say "たこルカは俺の嫁";
	last if 5 < ++$count;
}

say "スカラを受け取る所にカンマで並べるとカンマ演算子が最後の項を返す";
say "最後が3の場合は常に真で常にループ";
$count = 0;
while (1, 2, 3) {
	say "ルカ姐さんも俺の嫁";
	last if 5 < ++$count;
}

say "最後が0の場合は常に偽でループは0回";
$count = 0;
while (1, 2, 3, 0) {
	say "ルカ姐さんも俺の嫁";
	last if 5 < ++$count;
}

say "スカラを受け取る所にリストを置いても最後の要素を返す";
$count = 0;
while ((1, 2, 3)) {
	say "ルカ姐さんも俺の嫁";
	last if 5 < ++$count;
}

say "最後の要素が0の場合";
$count = 0;
while ((1, 2, 3, 0)) {
	say "ルカ姐さんも俺の嫁";
	last if 5 < ++$count;
}

say "forループに配列を置くと要素1個ずつループ";
my @a = qw/ 1 2 3 /;
for (@a) {
	say;
}

say "whileループに配列を置くと要素の個数を真偽判定してループ";
say "要素が3個の配列の場合は常に真";
$count = 0;
while (@a) {
	say "たこルカは俺の嫁";
	last if 5 < ++$count;
}

say "要素が0個の配列の場合は常に偽";
@a = ();
$count = 0;
while (@a) {
	say "たこルカは俺の嫁";
	last if 5 < ++$count;
}

say "さて、ようやく肝心のケースを試す時が来ました";
say "もうお分かりですね、未定義値が1個の配列の場合は真";
@a = (undef);
$count = 0;
while (@a) {
	say "ルカ姐さんも俺の嫁";
	last if 5 < ++$count;
}

say "ここで初めに試したコードをおさらいしましょう。";
say "whileがスカラを受け取り未定義値の場合は偽";
$count = 0;
while (undef) {
	say "ルカ姐さんも俺の嫁";
	last if 5 < ++$count;
}

say "おしまい";

__DATA__
たこルカは俺の嫁
ルカ姐さんも俺の嫁
ファイルっぽいデータを全部読んだ後に未定義値が来る場合
たこルカは俺の嫁
ルカ姐さんも俺の嫁
whileが未定義値を返す関数を呼ぶとループ0回
【注意】undefは未定義値を返す関数
forループはリストを受け取り、その要素1個ずつで1ループ
1
2
3
4
5
forループと違い、whileループはスカラを受け取り偽ならループしないで終了
whileループはスカラを受け取り真ならループ継続
たこルカは俺の嫁
たこルカは俺の嫁
たこルカは俺の嫁
たこルカは俺の嫁
たこルカは俺の嫁
たこルカは俺の嫁
スカラを受け取る所にカンマで並べるとカンマ演算子が最後の項を返す
最後が3の場合は常に真で常にループ
ルカ姐さんも俺の嫁
ルカ姐さんも俺の嫁
ルカ姐さんも俺の嫁
ルカ姐さんも俺の嫁
ルカ姐さんも俺の嫁
ルカ姐さんも俺の嫁
最後が0の場合は常に偽でループは0回
スカラを受け取る所にリストを置いても最後の要素を返す
ルカ姐さんも俺の嫁
ルカ姐さんも俺の嫁
ルカ姐さんも俺の嫁
ルカ姐さんも俺の嫁
ルカ姐さんも俺の嫁
ルカ姐さんも俺の嫁
最後の要素が0の場合
forループに配列を置くと要素1個ずつループ
1
2
3
whileループに配列を置くと要素の個数を真偽判定してループ
要素が3個の配列の場合は常に真
たこルカは俺の嫁
たこルカは俺の嫁
たこルカは俺の嫁
たこルカは俺の嫁
たこルカは俺の嫁
たこルカは俺の嫁
要素が0個の配列の場合は常に偽
さて、ようやく肝心のケースを試す時が来ました
もうお分かりですね、未定義値が1個の配列の場合は真
ルカ姐さんも俺の嫁
ルカ姐さんも俺の嫁
ルカ姐さんも俺の嫁
ルカ姐さんも俺の嫁
ルカ姐さんも俺の嫁
ルカ姐さんも俺の嫁
ここで初めに試したコードをおさらいしましょう。
whileがスカラを受け取り未定義値の場合は偽
おしまい

Perl5.28は警告しませんが、Perl5.32は警告します。

Subroutine Data::Dumper::qquote redefined at /home/perlsample/sample/MyDumper.pm line 16.
Useless use of a constant (2) in void context at perlsample_029.pl line 62.
Useless use of a constant (2) in void context at perlsample_029.pl line 69.
Useless use of a constant (3) in void context at perlsample_029.pl line 69.
Useless use of a constant (2) in void context at perlsample_029.pl line 76.
Useless use of a constant (2) in void context at perlsample_029.pl line 83.
Useless use of a constant (3) in void context at perlsample_029.pl line 83.