masatoの日記

やっていきます

初めてのPerl 6章ハッシュ 練習問題1

プログラミングの参考書をなるほどなるほど、と読みすすめてみても、本を置き、書こうとすると出てこない。 本当に。

なので、まず書いてみようということで、どんどん手を動かしていこう。打ちながら、わからなくなったら本を開けばいい。

ということで、「初めてのPerl」第6章ハッシュからの問1。自分用のメモを残しておく。

use strict;
use warnings;

## 姓名を標準入力で入力してもらって、その人の姓を表示するプログラム
## あいだを半角スペースで区切ってね
print "Input your name:(Finish with type 'q')";

my %fullnames;

while (my $fullname = <STDIN>) {
    chomp($fullname);
    if ($fullname eq 'q') { last; }
    
    my ( $first_name, $last_name ) = split(/ /, $fullname);
    print "$first_name $last_name";

    # 名をハッシュのキー、姓を値とする
    $fullnames{$first_name} = $last_name;

    print "Input next name:";
}

for my $last_name (keys %fullnames) {
    print $fullnames{$last_name},"\n";
}

やりたいこと

標準入力から姓名をスペース区切りで入力すると、名字だけを表示する。

入力と結果

Input your name:(Finish with type 'q')Kondo Satoshi
Input next name:Suzuki Munenori
Input next name:q
Munenori
Satoshi

つまったところ

ハッシュに要素を追加する方法でつまづいた。 はじめにやった方法は

%fullnames = (
    first_name => $first_name,
    last_name  => $last_name,
};

これだと、ループのたびに上書きされるので、最終的に一つの要素しか作れない。 この場合、キーがfirst_namelast_nameで固定されているので、値を追加しても自動的に要素が生成されないのだった。

上記は普通のハッシュだった。

これをハッシュレフでやったのが以下だ。

my $fullnames_ref;

while (my $fullname = <STDIN>) {
    chomp($fullname);
    if ($fullname eq 'q') { last; }
    
    my ( $first_name, $last_name ) = split(/ /, $fullname);

    # 名をハッシュのキー、姓を値とする
    $fullnames_ref->{$first_name} = $last_name;

    print "Input next name:";
}

for my $last_name (keys %$fullnames_ref) {
    print $fullnames_ref->{$last_name},"\n";
}

ハッシュのシジル(%→$)を変更したのと、参照方法を変えただけでOK。

ハッシュの値参照: $fullnames{$first_name} #$first_nameに対応する$last_nameが取り出せる

ハッシュレフの値参照: $fullnames_ref->{$first_name} #上に同じ