@kyanny's blog

My life. Opinions are my own.

Perl Quiz やってみた

Perl Quiz に挑戦して負けました(追記有り) - だるろぐ
寄せられたPerl Quizの回答と解説 - だるろぐ

どんだけ遅れてるんだよ、って感じだけど、さっきピン立ててた記事開いたところだったので、やってみた。一応、答えとかはみずに20分くらいでできたと思う。いまから記事の本文を読む。

http://github.com/kyanny/perl-quiz

本文を読んだ。 $ref の中身がもっと深くなった場合とか考慮しないといけないのかー。問題からそこまで読み取れなかった。少し前ゴルファーのひとに「とにかく例にあがってるテストだけパスすればおk」てきなことを聞いたので(違ったかもしれないけど、生真面目に一般解を求めたりしなくていいよ的なニュアンスだったと思う)そういう風に考えてしまった。

(my @m = split(/\./,$key)) && ... とかやって @m を使おうとすると Global Symbol になってしまう。なんでそうなるのか詳しいことはわからない。なので、 $key を分割した配列を無名関数の引数に渡してみた。

こっちが先に書いた正規表現でやるやつ

use strict;
use Test::More;

sub foo {
    my ($a_ref, $key, $value) = @_;
    (sub { $a_ref->{$_[0]}{$_[1]}{$_[2]} = $value })->($key =~ /([^.]+)/g);
    return $a_ref;
}

my $ref = {
    foo => {
        bar => {
            baz => 1,
        },
    },
};

my $expects = {
    foo => {
        bar => {
            baz => 100,
        },
    },
};

$ref = foo($ref, 'foo.bar.baz', 100);
is_deeply($ref, $expects);

done_testing();

こっちは split を使ったほう

use strict;
use Test::More;

sub foo {
    my ($a_ref, $key, $value) = @_;
    (sub { $a_ref->{$_[0]}{$_[1]}{$_[2]} = $value })->(split /\./, $key);
    return $a_ref;
}

my $ref = {
    foo => {
        bar => {
            baz => 1,
        },
    },
};

my $expects = {
    foo => {
        bar => {
            baz => 100,
        },
    },
};

$ref = foo($ref, 'foo.bar.baz', 100);
is_deeply($ref, $expects);

done_testing();