出力形式を指定するあれこれ

こんにちは！
みなさんPerl書いてますか？

今回は、出力形式を指定するあれこれについて書いていきます。
(書きたいことをポンポン書いているのであまりまとまってないです・・・)←

早速ですが、下記の様な出力をしたいときについて考えます。

```
honda supercub 110cc
kawasaki h2sx 1000cc   
yamaha vino 50cc
```

perlにはいろいろな方法がありますよね？

「TMTOWTDI」ですよ！「TMTOWTDI」！！

~~正解はひとつ！じゃない！！~~
やり方はひとつじゃない

> TMTOWTDIとは - はてなキーワード
> http://d.hatena.ne.jp/keyword/TMTOWTDI

というわけでいろいろご紹介します。
※他にもいい方法があったら教えてください

さて本題へ・・・

まずは表示したいものをデータ化して、
フォーマット指定子で表示形式を指定して表示していきます。

* 配列を使う

```perl
use strict;
use warnings;
use utf8;

my @list = (
    ["honda", "supercub", 110],
    ["kawasaki", "h2sx", 1000],
    ["yamaha", "vino", 50],
);

foreach my $data (@list) {
    my ($maker, $bike, $engine) = @{$data};
    printf "%s %s %dcc\n", $maker, $bike, $engine;
}
```
```text:出力結果
honda supercub 110cc
kawasaki h2sx 1000cc
yamaha vino 50cc
```

* ハッシュを使う

```perl
use strict;
use warnings;
use utf8;

my @list = (
    {
        maker  => "honda",
        bike   => "supercub",
        engine => 110,
    },
    {
        maker  => "kawasaki",
        bike   => "h2sx",
        engine => 1000,
    },
    {
        maker  => "yamaha",
        bike   => "vino",
        engine => 50,
    },
);

foreach my $data (@list) {
    printf "%s %s %dcc\n", $data->{maker}, $data->{bike}, $data->{engine};
}
```
```text:出力結果
honda supercub 110cc
kawasaki h2sx 1000cc
yamaha vino 50cc
```
上記の2つは同じフォーマット形式`"%s %s %dcc\n"`で指定しています。

出力結果も問題なさそうです。

しかしその指定する形式が長くなってくると、
`%s`だらけになったりしてわからなくなってしまいますね・・・

* 引数を増やすとき -> 一体何個目の`%s`に入るのか？
* あとからプログラムを見たとき -> ここ(`%s`)には一体何の変数がはいるのか？

そんなときには、直接書いてしまえばいいんです。

```perl
printf "${maker} ${bike} ${engine}cc\n";
```

配列のときの例を使うと、こんな感じ↓

```perl
use strict;
use warnings;
use utf8;

my @list = (
    ["honda", "supercub", 110],
    ["kawasaki", "h2sx", 1000],
    ["yamaha", "vino", 50],
);

foreach my $data (@list) {
    my ($maker, $bike, $engine) = @{$data};
    printf "${maker} ${bike} ${engine}cc\n"; # 変数を指定
}
```

```text:出力結果
honda supercub 110cc
kawasaki h2sx 1000cc
yamaha vino 50cc
```

あと文字数がバラバラだと見にくいし、長さ合わせたくなりますよね

```text:こんなふうにしたい！
honda    supercub  110cc
kawasaki h2sx     1000cc
yamaha   vino       50cc
```

そんなときはフォーマット指定子に数字を挟めばいいですね

```perl
use strict;
use warnings;
use utf8;

my @list = (
    ["honda", "supercub", 110],
    ["kawasaki", "h2sx", 1000],
    ["yamaha", "vino", 50],
);

foreach my $data (@list) {
    my ($maker, $bike, $engine) = @{$data};
    printf "%-8s %-8s %4dcc\n", $maker, $bike, $engine; # 数字を挟んだ
}
```

```text:出力結果
honda    supercub  110cc
kawasaki h2sx     1000cc
yamaha   vino       50cc
```

今回は決め打ちしちゃいましたが、可変するものとかには対応できませんよね・・・

そんなときには下記の方法で、外にある変数から指定することができますよ

```perl
use strict;
use warnings;
use utf8;

# 表示の長さを指定する
my $engine_strlen = 4;

my @list = (
    ["honda", "supercub", 110],
    ["kawasaki", "h2sx", 1000],
    ["yamaha", "vino", 50],
);

foreach my $data (@list) {
    my ($maker, $bike, $engine) = @{$data};
    printf "%-8s %-8s %${engine_strlen}dcc\n", $maker, $bike, $engine; # 変数を使って長さを設定 
}

```
```text:出力結果
honda    supercub  110cc
kawasaki h2sx     1000cc
yamaha   vino       50cc
```

あとは引数側からも入れる方法(`%*d`)もあったり・・・

```perl
use strict;
use warnings;
use utf8;

my $engine_strlen = 4;

my @list = (
    ["honda", "supercub", 110],
    ["kawasaki", "h2sx", 1000],
    ["yamaha", "vino", 50],
);

foreach my $data (@list) {
    my ($maker, $bike, $engine) = @{$data};
    # 3番目の引数が「長さ」と「値」に変わる
    printf "%-8s %-8s %*dcc\n", $maker, $bike, $engine_strlen, $engine;
}
```

```text:出力結果
honda    supercub  110cc
kawasaki h2sx     1000cc
yamaha   vino       50cc
```

(いろいろ)ありますねぇ！

見やすい・わかりやすいコードを選んで書いてみてくださいね～。