第68回 関数ではなくforで処理を共通化する

いま、

###############
中西
###############
###############
木村
###############
###############
田中
###############
###############
山本
###############

と出力するソースを考えるとする。

へたくそに書く

なにも考えずにとてもへたくそに書くと、

use strict;

print q{###############}, "\n";
print q{中西},            "\n";
print q{###############}, "\n";

print q{###############}, "\n";
print q{木村},            "\n";
print q{###############}, "\n";

print q{###############}, "\n";
print q{田中},            "\n";
print q{###############}, "\n";

print q{###############}, "\n";
print q{山本},            "\n";
print q{###############}, "\n";

こうなる。

共通部分を見つける

ここから共通部分をみつけてみる。

みんな、

print q{###############}, "\n";
print q{なまえ},          "\n";
print q{###############}, "\n";

という構造をしていることに気づくと、
その部分を関数化して、

use strict;

sub template{
  my $name = shift;
  print q{###############}, "\n";
  print qq{$name},          "\n";
  print q{###############}, "\n";
}

template('中西');
template('木村');
template('田中');
template('山本');

こういうソースが書ける。
関数化したことですっきりしたが、まだ、template関数の呼び出し部分が多くうっとうしい。

forで名前をあたえる

そこでforを使って、

use strict;

sub template{
  my $name = shift;
  print q{###############}, "\n";
  print qq{$name},          "\n";
  print q{###############}, "\n";
}

for my $n ('中西', '木村', '田中', '山本'){
  template($n);
}

というソースが書ける。

本当に関数は必要だったか?

だが、ちょっとまってほしい。
本当に templateなんていう関数は必要だったのだろうか?
いや必要ない!
はじめからforを使って、つぎのようにしてしまえばよいのだ。

use strict;

for my $n ('中西', '木村', '田中', '山本'){
  print q{###############}, "\n";
  print $n,                 "\n";
  print q{###############}, "\n";
}

たったこれだけで、望みの結果を得られるのである。
通化というとすぐ関数を考えるのは間違いだ。
forの中に共通処理を書くことでも共通化は行えるのである。

今回は、あまりにも簡単な例だが、もっと大きなソースになると、
なぜ、わざわざ関数を用意しているのだろう?という現場に出くわすことがある。