Perl/CGIプログラムのサブルーチン
今回の学習は、サブルーチンについてです。
編集前記
今回の編集前記は、前回の続きで「プログラムのイメージ」についてお話ししたかったのですが…。
この後の内容を読んでいただければわかりますが、今回は学習内容がいつもより少し多いため、その話は次回に回したいと思います。
楽しみにされていましたら、すいません。
紙面の関係上、泣く泣く次回にまわさせていただきました。
そんなのどうでもいいと思っている場合は、あまり関係ないことですが(苦笑)。
それでは早速、今回のPerl/CGIプログラミング学習に移りましょう。
サブルーチンとは?
サブルーチンとは、ある特定の動作を行う Perl/CGIプログラム の塊をひとまとめにしたブロックのことです。
ある一定の動作を行うプログラムをブロック化して管理することにより、ひとつのプログラム内で行われる処理を分割して作成管理することができるようになります。
例えば、入力された数値をすべて足し合わせて合計を算出するような、Perl/CGIプログラムがあったとします。
その場合、以下のようにプログラム処理をブロック化できます。
1、入力エリアと計算結果またはエラーの表示
足し合わせたい数値を入力するフォーム、計算結果が出ていればその数値と、何らかのエラーがあればメッセージを表示する部分です。
2、入力データを受け取る
受け取ったデータの分だけ、すべて違う 変数 に格納する部分です。
3、入力データのチェック
変数に格納された値が、本当にすべて数値なのかどうかや、足し算なので数値が2つ以上あるかなどをチェックする部分です。
4、入力データを足し合わせる
変数内の数値をすべて足し合わせて答えを出す部分です。
1→2→3→4の順で実行されます。
4までいったら、再び1に戻ります。
つまり、1→2→3→4→1で、プログラム動作1回分だということです。
もし、1以外の処理でエラーが出た場合は、1に戻りエラーメッセージを表示しプログラムを強制終了します。
プログラムの流れと各ブロックの関係はこんな感じだとします。
もちろん、分け方は自由なのでこの限りではありませんが、だいたいこんな感じになると思います。
ではこの例を使って、プログラムをブロック化つまり、サブルーチン化するメリットについて説明していきます。
1つ目は、プログラミング作業を分担できるというところです。
複数のプログラマーで作業する場合、ひとりひとり作成するサブルーチンをあらかじめ決めておけば、効率的に開発が進みますよね。
前述の例では、1から4はすでにそれぞれの役割が決まっていますから、複数人でそれぞれ分担して作り最後につなぎ合わせるようなイメージです。
2つ目は、プログラムの再利用ができるというところです。
サブルーチン部分をコピーして、別のプログラムに組み込んで再利用することにより、開発時間を短縮できます。
前述の例では、3の「入力データのチェック」部分をコピーして、別のプログラムでも利用するといったイメージです。
3つ目は、デバックが効率的に行われるというところです。
デバックとは、プログラムコードのミスを修正する作業のことです。
前述の例では、ちゃんと2つ以上数値を入力しているのに、常にエラーが出てプログラム処理が先に進まなかったとします。
その場合は、いきなりプログラムの全体を見て修正しようとするのではなく、サブルーチンごとにチェックし修正していきます。
そうするとチェックする量も少なくて済みますし、なにより、正常に動作している部分を誤って書き換えてしまう可能性が減少します。
4つ目は、改造が簡単にできるというところです。
役割ごとにサブルーチン化されていると、改造する部分のプログラムコードが見つけやすくなるだけでなく、作業時間も短縮できます。
前述の例では、1の「入力エリアと計算結果またはエラーの表示」という部分がありましたよね。
この部分は、1回のプログラム動作で2回呼び出されますよね。
もし、入力エリアの表示を変更したい場合、サブルーチン化されていなければ2か所改造しなくてはいけませんが、サブルーチン化されていれば1か所で済みます。
このように同じプログラムでも、サブルーチン化されているのといないのとではかなり違いが出ることがわかっていただけたかと思います。
次は、Perl/CGIプログラムでサブルーチンを使う方法について解説していきます。
<戻る>
サブルーチンの基礎
まずは、Perl/CGIプログラミングでサブルーチンを使用する基礎から学習していきましょう。
サブルーチンの定義
Perl/CGIプログラムでサブルーチンを使う時には、以下のように記述します。
sub サブルーチン名 {
処理
}
サブルーチンを宣言する「sub」を付け、その後にサブルーチン名を書きます。
サブルーチン名の付け方のルールは、変数名のつけ方と同じだと考えてください。
忘れてしまった場合は読み返して復習しておいてください。
サブルーチンの中身は、サブルーチン名の後の「{」から「}」までです。
この中に書かれているプログラムコードは、すべてサブルーチンが呼び出されたときに実行される命令であると解釈されます。
実際のPerl/CGIプログラムで書くと、以下のようになります。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
$a = 10;
sub view {
print $a;
}
exit;
このPerl/CGIプログラムでは、サブルーチン名に「view」という名前を使用しています。
そしてその中には、「print $a;」があり、変数「$a」の中身を出力させています。
Perl/CGIプログラム全体を解説すると…。
最初に「print "Content-type: text/html\n\n";」で、HTML形式でテキスト文書を出力すると宣言します。
次に「$a = 10;」で、変数「$a」に10を代入します。
最後に、サブルーチンviewで、変数「$a」の中身を出力させていますから、「10」と表示されると思いますよね。
しかし、このPerl/CGIプログラムを実行させても、実は何も表示されません。
実行する環境によっては、エラーが出る場合もあります。
なぜかというと、通常Perl/CGIプログラムというのは、上から順に実行されていきます。
しかし、サブルーチンがコーディングされている部分というのは、プログラムとして認識はされますが、実際に実行されることなく飛ばされます。
なぜかというと、前述のサブルーチンを使用する利点について解説したところを思い出していただければわかります。
サブルーチンを利用する利点のひとつに、「サブルーチンは何度でも呼び出して使用することができる」というようなところがありましたよね。
サブルーチンの解説の一番最初のところで、入力された複数の数値の合計を計算するプログラム作成の例を出しました。
ちょうど、1の「入力エリアと計算結果またはエラーの表示」という部分が、1回のプログラム実行で2回呼び出されていましたよね。
このような性質を持っているので、サブルーチン本体を書いただけでは、プログラムとして認識はされても実際に実行はされないという仕組みになっているというわけなのです。
では、どうすればよいかというと…。
Perl/CGIプログラムでサブルーチンを実行させるには、メイン処理の部分で、サブルーチンの呼び出しを宣言する必要があります。
これはちょうど、パソコンのキーボードを思い浮かべていただければわかりやすいかと思います。
どのキーでもよいのですが、キーボードって、そのキーが押されない限りは何も起こりませんよね。
でも、一度でも何らかのキーが押されれば、あらかじめ用意されていたそのキーに対応した動作が実行されますよね。
サブルーチンもそれと同じで、プログラムを実行するサブルーチン本体部分と、それを呼び出すスイッチ部分があるというわけなのです。
サブルーチンの呼び出し
ここでは、Perl/CGIプログラミングでの、サブルーチンの呼び出し方について学習していきます。
サブルーチンを呼び出すには、呼び出したいサブルーチン名の前に、「&」をつけるだけです。
例えばこんな感じです。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
$a = 10;
&view;
sub view {
print $a;
}
exit;
このPerl/CGIプログラムを実行すると、「10」と表示されます。
先ほどのPerl/CGIプログラムに、サブルーチン「view」を呼び出す「&view;」を追加しました。
「&view;」部分でサブルーチンが呼び出され、「print $a;」が実行されます。
また、サブルーチン本体部分は、プログラムのどこに書いても実行されます。
サブルーチン本体部分は、Perl/CGIプログラム実行時に一緒に読み込まれますが、呼び出しがない限りは実行されないことはもうおわかりですよね。
乱暴に言ってしまえば、無いものとして通り過ぎるわけですから、例えば、1行目のPerlのパスの下つまり、2行目から書いてもよいのです。
大切なのは、サブルーチンを呼び出すタイミングです。
プログラム全体の動きを理解して呼び出すべきタイミングでサブルーチンを呼び出さないと、動きがめちゃくちゃになってしまうというわけです。
サブルーチンの終了
続いて、Perl/CGIプログラムのサブルーチンの終了について学習していきましょう。
サブルーチンの終了方法は大きく分けて3種類あります。
それを今から学習していきましょう。
自然終了
サブルーチン内に書かれているプログラムコードがすべて実行された場合、自然にそのサブルーチンは終了し、処理がサブルーチンの呼び出し元まで戻ります。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
$a = 'A';
$b = 'B';
&view;
print $b;
sub view {
print $a;
}
exit;
このPerl/CGIプログラムを実行すると、「AB」と表示されます。
この実行結果からも、サブルーチンのプログラムコードが最後まで実行し終わると、処理がサブルーチンの呼び出し元まで戻ることがわかりますよね。
return終了
return関数を使うとただちにサブルーチンを強制終了し、処理をサブルーチンの呼び出し元に戻すことができます。
もちろん、サブルーチンの途中でも終了させることができます。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
$a = 'A';
$b = 'B';
&view;
print $b;
sub view {
return;
print $a;
}
exit;
このPerl/CGIプログラムを実行すると、「B」と表示されます。
「A」は表示されません。
サブルーチンに入った瞬間、return関数でメイン処理に戻されるからですね。
exit終了
exit関数を使うと、Perl/CGIプログラム自体の動きを強制的に終了させることができます。
exit関数の場合は、実行場所がサブルーチン内であろうがなかろうが、プログラムを強制終了させます。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
$a = 'A';
$b = 'B';
&view;
print $b;
sub view {
print $a;
exit;
}
exit;
このPerl/CGIプログラムを実行すると、「A」と表示されます。
「B」は表示されません。
サブルーチンが終了しメイン処理に戻される前に、exit関数が実行され、サブルーチンの中でプログラムが終了するからですね。
exit関数は、毎回プログラム例で使っていますから、いまさら解説しなくてもわかりますよね。
これでサブルーチンの基本は以上です。
サブルーチンの独立
ここでは、Perl/CGIプログラミングでのサブルーチンの独立処理について学習していきます。
最初のサブルーチンを利用する利点のところで、サブルーチン本体部分をコピーして、別のPerl/CGIプログラムに組み込むことが可能であると説明しましたよね。
ですが、今まで学習してきましたサブルーチンの基本で登場したプログラム例では、メイン処理で使用した変数を、そのままサブルーチンでも使用していましたよね。
これでは、サブルーチン部分をコピーして別のプログラムで使用するといったことができなくなってしまいます。
なぜなら、単純に変数の値が変わってしまうからですね。
Perl/CGIプログラムでは、いつでもどこでも変数を宣言して利用することができます。
ということは、複数のサブルーチンをよせ集めて順番に動かした場合、たがいに悪影響を与えてしまう可能性があるわけです。
そうなってしまっては、もうプログラム作成どころではありませんよね。
このような困った現象を回避する方法として、常にプログラム全体で変数名が重複していないかどうかをチェックするというのがあります。
新しく追加するサブルーチン内で使われている変数名と、プログラム全体で使われている変数名が重複していないかどうかを調べるわけです。
でもこれは、かなり強引な手段ですよね。
根性ありきの力技といった感じで、スマートではありません。
ではどうすればよいかというと、サブルーチン本体のプログラムコードの部分だけを、別世界という扱いで作成していくという方法を使います。
今までは、メイン処理で使っていた変数とおなじものを、そのままサブルーチン内でも使っていましたが、これからはバラバラに変数を用意します。
たとえ変数名が同じでも、別の変数であるという扱いをさせることができますから、本当に別世界という感覚でプログラミングすることができます。
ようするに、メイン処理でのみ使用する変数と、各サブルーチンでのみ使用する変数があるわけですね。
そして、変数に格納されている値については、サブルーチンに処理が移る段階や、メイン処理に帰ってくる段階で、値の受け渡しを行うようにします。
それではひとつひとつ解説していきます。
変数の局所化
まず、サブルーチンの中でのみ使用できるような変数を定義するには、その変数が一番最初に登場する前に、「my」や「local」をつけます。
わかりやすく言うと、myやlocalを変数の頭に付けると、「この変数は限られたエリア(サブルーチンなど)限定で使いますよ」と宣言しているということになるわけです。
例えば、以下のプログラムを見てください。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
$a = 'A';
&view;
print $a;
sub view {
$a = 1;
print $a;
}
exit;
このPerl/CGIプログラムを実行すると、「11」と表示されます。
「$a = 'A';」という処理が無視されていますよね。
なぜこうなるかについては、もうおわかりですよね。
メイン処理で実行した「$a = 'A';」が、サブルーチン内の「$a = 1;」により、値が上書きされてしまったからですね。
それでは、このような現象を回避するために、「my」を使ってみます。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
my $a = 'A';
&view;
print $a;
sub view {
my $a = 1;
print $a;
}
exit;
このPerl/CGIプログラムを実行すると、「1A」と表示されます。
同じ変数名「$a」でも、「my」を使用したことにより、コンピューター側では別の変数という扱いになりました。
これで、メイン処理とサブルーチン部分が、別世界という扱いになったわけです。
今回はたまたまスカラ変数でしたが、配列変数や連想配列でも同じです。
サブルーチンを別世界扱いさせたいときには、配列や連想配列の場合にも、最初にその変数が登場したときには「my」や「local」を付けます。
でも、少し注意しなくてはいけないことがあります。
それは「my」と「local」では、多少Perlプログラムの動きが異なるからです。
今からPerlプログラミングを学習する場合には、「my」の方のみを使うようにしてください。
詳しくは次回説明します。
で、別世界扱いでプログラミングしていくと、メイン処理部分とサブルーチン処理部分で、データの受け渡しが必要になってくる場面が出てきます。
次は、そのあたりのルールについて解説していきますね。
まずは、サブルーチンへのデータの受け渡しに関する用語ですが…。
サブルーチンに値のデータをわたすことを引数といいます。
逆に、サブルーチンから値のデータを受け取ることを、戻り値といいます。
実際のプログラミングではやりとりする値はほぼすべて、変数に格納されその中の値がやりとりされることになります。
そのやりとりの方法にも、2つの方法がありますから、ここで一緒に紹介しておきます。
ひとつは、変数に格納された値を実際にやり取りする方法。
もうひとつは、値が格納された変数の記憶領域のアドレス番号のみをやり取りする方法。
後者はリファレンスと呼ばれ、どんなタイプの変数でも複数自由にやり取りすることができます。
しかし、ここでリファレンスについて学習していくとわけわからなくなると思うので、また別の機会に説明します。
今回は、前者の値そのものをやり取りする方法についてのみ学習していきます。
この方法は、やりとりすることのできる変数に限りがあるものの、わかりやすいです。
それではまず、引数について学習していきましょう。
サブルーチンの引数
Perl/CGIプログラムでサブルーチンに値をわたすときは、サブルーチン名の後に、「( ~ )」のように、カッコで値をくくります。
「&サブルーチン名(値)」という感じです。
値は、ひとつでも複数でもわたすことができます。
複数の値をわたすときは、値と値のあいだに、「,」を使用します。
「&サブルーチン名(値1, 値2)」という感じです。
サブルーチンにわたされる値は、最終的に「@_」という特殊変数に格納されてわたされます。
ですから、サブルーチン側で引数を受け取る場合には、「@_」から値を受け取るようにコーディングすればよいわけです。
そのコーディングについては、大きく3つの方法がありますから、順番に解説していきますね。
引数の受け取り方法1
サブルーチンの引数に指定された値を、特殊変数「@_」から受け取る1つ目の方法について解説します。
その1つ目の方法とは、「@_」に代入されている値を、配列もしくは、配列状態に並べたスカラ変数で受け取る方法です。
文章だけではわかりにくいと思うので、以下のプログラムを見てください。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
my $a = 'A';
&view($a);
sub view {
my ($a) = @_;
print $a;
}
exit;
このPerl/CGIプログラムを実行すると、「A」と表示されます。
サブルーチンに引数を渡している部分は、「&view($a);」という部分です。
メイン処理部分で変数を使わずに、「&view('A');」と書くこともできます。
仮に、複数のスカラ変数を引数にするときは「&view($a, $b);」のように、引数をカンマで区切ります。
さらに、最終的には「@_」という形でサブルーチンに渡されることさえ理解していれば…。
「&view(@ab);」のように配列にすることや、「&view(%ab);」のように連想配列にすることもできます。
サブルーチン内で引数を受け取っている部分は、「my ($a) = @_;」という部分です。
引数は「@_」という配列に格納されていますから、スカラ変数で受け取るときは、たとえ引数が1つでもカッコでくくり配列状態にして受け取ります。
引数が2つあるときは、「my ($a, $b) = @_;」のように、スカラ変数をカンマで区切ります。
さらに、引数の値は「@_」という配列に格納されていますから、「my @ab = @_;」のように、配列で受け取ることもできます。
この場合はスカラ変数を配列状態にしたのではなく、配列そのもので受け取っていますから、カッコはあってもなくてもかまいません。
連想配列で受け取る場合は、「my (%ab) = @_;」という感じになります。
引数の受け取り方法2
サブルーチンの引数に指定された値を、特殊変数「@_」から受け取る2つ目の方法について解説します。
その2つ目の方法とは、「@_」を要素に分解し、そこから直接値を受け取る方法です。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
my $a = 'A';
&view($a);
sub view {
my $a = $_[0];
print $a;
}
exit;
このPerl/CGIプログラムを実行すると、「A」と表示されます。
サブルーチン内で引数を受け取っている部分は、「my $a = $_[0];」という部分です。
「@_」は配列ですから、その配列を構成している要素に直接アクセスしています。
「@_」に格納されている引数の値が複数ある場合には、「$_[添え字]」の添え字部分の数字が上がっていきます。
「$_[0]」「$_[1]」「$_[2]」…、といった感じです。
これなら引数の順番に関係なく値を取り出すことができますね。
引数の受け取り方法3
サブルーチンの引数に指定された値を、特殊変数「@_」から受け取る3つ目の方法について解説します。
その3つ目の方法とは、「@_」は配列であるということから、shiftやpopといった関数を使う方法です。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
my $a = 'A';
&view($a);
sub view {
my $a = shift;
print $a;
}
exit;
このPerl/CGIプログラムを実行すると、「A」と表示されます。
サブルーチン内で引数を受け取っている部分は、「my $a = shift;」という部分です。
省略しないで書くと「my $a = shift @_;」という感じになります。
引数の値「@_」の先頭の要素つまり、「$_[0]」を切り取って代入させています。
shiftやpopといった配列操作関数 についてはわかりますよね。
以前詳しく解説してありますから、忘れてしまったという場合は読み返しておいてください。
shift関数は、配列先頭の要素を切り取り、それ以降の添え字をひとつずつ繰り上げます。
pop関数はその逆で、配列最後の要素を切り取ります。
ですから、shift関数を何度も使うと、引数の値を順番に取得していくことができます。
逆に、pop関数を何度も使うと、引数の後ろの値から順に取り出すことができます。
今回のプログラム例では、引数はひとつですから、shiftでもpopでも関係ないですが(苦笑)。
これで、「@_」に格納されている引数の受け取り方法については以上です。
サブルーチンの戻り値
今度は逆に、サブルーチンから値を返す方法と、それを受け取る方法について解説します。
サブルーチンから値を返すには、前述しましたreturn関数に戻り値をつけるだけです。
つまり、returnの後に値を記述するだけです。
戻り値も前述しました引数と同じように、値が複数ある時には配列状態で値がやりとりされます。
つまり、複数のスカラ変数でも、配列または連想配列でも、配列感覚で扱う必要があるということです。
次に、サブルーチンから戻り値を受け取る方法についてです。
サブルーチンから値を受け取るには、通常の代入と同じ方法で値を受け取ることができます。
このあたりの記述ルールは、前述しました引数から値を取り出す方法と同じです。
違うところは引数のように、常に「@_」という特殊変数が出てくるわけではないところです。
戻り値の場合は、返される値の数によって配列扱いのように考えることもありますが、基本的に「@_」という特殊変数では考えません。
戻り値の場合は、返される値がひとつなのか、複数なのかによってコーディング方法が変わってきます。
それではひとつひとつ見ていきましょう。
ひとつの戻り値
まずは、値がひとつだった場合です。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
my $a = &view;
print $a;
sub view {
my $a = 'A';
return $a;
}
exit;
このPerl/CGIプログラムを実行すると、「A」と表示されます。
サブルーチンから戻り値を出している部分は「return $a;」ですね。
サブルーチン内で変数を使わずに、「return 'A';」と書いても同じです。
サブルーチンから戻り値を受け取っている部分は「my $a = &view;」です。
やりとりする値がひとつしかないので、通常のスカラ変数への代入と同じですね。
複数の戻り値
次に、複数の値を戻り値にした場合のプログラミング方法についてです。
戻り値が複数ある場合は、そこにどんなタイプの変数が使われていようと、配列扱いでやりとりします。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
my @ab = &view;
print @ab;
sub view {
my $a = 'A';
my $b = 'B';
return ($a, $b);
}
exit;
このPerl/CGIプログラムを実行すると、「AB」と表示されます。
サブルーチンから戻り値を出している部分は「return ($a, $b);」ですね。
return関数で戻す値全体をカッコでくくりながら、値ごとにカンマで区切ることにより、配列扱いで返しています。
サブルーチンから戻り値を受け取っている部分は「my @ab = &view;」です。
ここは普通に配列で受けていますから、カッコはなくてもかまいません。
今回はたまたま複数のスカラ変数から配列に値を渡しましたが、この関係は、逆にすることもできますからね。
次は、同じ配列扱いでも、今度は連想配列を使ってみます。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
my (%abc) = &view;
print $abc{a};
sub view {
my %abc = ('a' => 1);
return (%abc);
}
exit;
このPerl/CGIプログラムを実行すると、「1」と表示されます。
サブルーチンから戻り値を出している部分は「return (%abc);」ですね。
サブルーチンから戻り値を受け取っている部分は「my (%abc) = &view;」です。
どちらも、値全体をカッコでくくり配列扱いにしています。
これで今回の学習テーマ、「サブルーチンの考え方とその基本」の学習は以上です。
編集後記
今回学習しましたサブルーチンはいかがだったでしょうか?
サブルーチンはとても便利な仕組みですから、必ず使えるようにしておきましょう。
今回は最後に、引数にした数値の合計を戻り値にするサブルーチンを作ってみました。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
my $x = &answer(10, 25);
print $x;
sub answer {
my @number = @_;
my $x = 0;
for(my $i=0 ; $i<=$#number ; $i++) {
$x += $number[$i];
}
return $x;
}
exit;
このPerl/CGIプログラムを実行すると、「35」と表示されます。
指定した数値を引数とし、合計を戻り値としているのは以下の部分ですね。
my $x = &answer(10, 25);
サブルーチン「&answer」では、受け取った引数の合計を出して戻り値にしています。
「return $x;」という部分がそうですね。
サブルーチンを作るうえでのポイントとして、サブルーチンは、なるべく柔軟に作るようにしましょう。
なぜなら、別のPerl/CGIプログラムファイルで利用する可能性があるからです。
このサブルーチン「&answer」は、いくつでも数値をわたすことができます。
例では2つですが、3つでも5つでも数値を渡せば、その合計を返してくれます。
なぜそうなのかは、見ればわかりますよね。
それは、メイン処理からの値を受け取るために、配列を使用しているからですね。
そして、メイン処理から受け取った配列の要素がいくつあろうと、 for関数でループ させています。
したがって、メイン処理からいくつ変数をわたされても、すべて受け取ることができ、すべて足しあわせることができるというわけです。
もちろん前述してきたPerl/CGIプログラムのように、スカラー変数を使って引数を受けても問題ないです。
場合によっては、そちらの方が有利なときもあります。
しかし、今回のような「引数を足した答えを返す」というようなときには、いくつでも引数を受け取れるように配列を使った方が、柔軟なサブルーチンとなるわけです。
もし、別のPerl/CGIプログラムファイルで、このサブルーチンを再利用することになったら、当然引数の数というのは変わるはずですから…。
まぁ、そのへんの感覚は自由ですけどね(笑)。
これで、今回の学習は以上です。
ありがとうございました。
<戻る>