おつかれさまです・・むっちゃ多忙です。が、精神の喜びを求めて更新してみます、Perl入学式レポートの続き。
前回の記事はこちらです。
Perl入学式2013年度第5回補講・参加レポート vol.4 - the code to rock
ええと、とりあえず前回までにどこまで来ていたかっていうと、この日(2013年度#5補講)の内容って大きく以下の2つなのですが、
- 復習系: map, grep, whileなどこれまでの落穂ひろい
- 新規系: Mojolicious導入, package, テストなどカリキュラム大詰めな感じ
今ちょうどその前者の終わりの方ですね。
ということで、今回はwhile, next, last, 後置if/forです。
https://github.com/perl-entrance-org/workshop-2013-05/blob/master/slide.md#while
と言いつつ、基本的には内容はもう上記のリンクを見て頂くとして、こちらの記事ではいつものとおり、練習問題に行ってしまいましょう。
まず僕の回答を書いて、その後papixさん(校長)の回答を並べたいと思います。
(長くなったら校長のぶんは次回に回しますが・・どうなるか)
では練習問題。
引数として与えられた文字列が, 数値A 演算子 数値Bという文字列であれば, その値を計算して, 結果を返すような関数calc_stringを書いてみましょう
- 「数値A」は任意の桁の正・負の整数とします. また, 演算子は+-*/%が使えるものとします.
- 但し, 引数が与えられなかった場合(空の文字列の場合)は, undefを返します
- また, 数値A 演算子 数値Bというフォーマットと一致しない場合もundefを返します
関数calc_stringとwhile文を使って, Ctrlキーとdキーを押すまでの間標準入力から文字列を受け取り, 文字列に書かれた式を計算するようなコードを書いてみましょう
はい。では私の回答、まず前者の方(while使う前まで)。
#!/usr/bin/env perl use strict; use warnings; sub calc_string { my $str = shift; unless ($str =~ /^(-?\d+) (.) (-?\d+)$/) { return undef; } else { if ($2 eq '+') { return $1 + $3; } elsif ($2 eq '-') { return $1 - $3; } elsif ($2 eq '*') { return $1 * $3; } elsif ($2 eq '/') { return $1 / $3; } elsif ($2 eq '%') { return $1 % $3; } } } print calc_string('10 - 5')."\n"; print calc_string('-3 * 5')."\n"; print calc_string('hi * 5')."\n";
実行結果はこちら。
5 -15 Use of uninitialized value in concatenation (.) or string at calc_string.pl line 26.
ん、ん〜、最後のエラーの出方がなんか、ずばり「undef」と出てほしかったのですが、そんな感じでもないですね・・
でも以前にundef出したときは、この方法(return undef;)で行けたんだけど・・これの校長の回答とか。
http://note103.hateblo.jp/entry/2014/01/19/153450
これだったら普通に「ERROR!」とか出るほうがいいかな・・
ま、一旦続けます。
上記の内容に、whileと標準入力を取り入れろということで、こうなりました。
#!/usr/bin/env perl use strict; use warnings; print "Input \'numeric operator numeric\'. For example, \'1 + 2\'\. \nIf finish, put <C-d>.\n"; while (my $input =<STDIN>) { print calc_string($input)."\n"; } sub calc_string { my $str = shift; unless ($str =~ /^(-?\d+) (.) (-?\d+)$/) { return "Error! Please input \'numeric operator numeric\'. For example, \'1 + 2\'\."; } else { if ($2 eq '+') { return $1 + $3; } elsif ($2 eq '-') { return $1 - $3; } elsif ($2 eq '*') { return $1 * $3; } elsif ($2 eq '/') { return $1 / $3; } elsif ($2 eq '%') { return $1 % $3; } } }
実行・・はこの形態だと掲載できないですが(対話型の内容なので)、まあ入力を促すところと、エラーの出方はちょっと工夫してみました。英語はめちゃくちゃですが・・
一応、手元ではいい感じに動いています。
ではこの続き、校長の解答を見ながらの答え合わせ編は次回にします!