sironekotoroの日記

Perl で楽をしたい

マンツーマンで教えを乞うてきた

id:xtetsuji さんありがとう

  • 金曜日は雨の中、id:xtetsuji さんに協力してもらって、Perlの疑問点・不明点などを聞いてきた
  • なお、以下に書いたのは自分の理解の及ぶ範囲。

クロージャはどんなとき使うのか?

  • Q.サンプルにあるのはカウンタだが、Perlの現場ではどのような使われ方があるのか?
# サンプル
{
    my $count = 0;
    sub count_up  { ++$count };
    sub count_num { $count};
}

print count_up() , "\n"; # 1
print count_up() , "\n"; # 2
print count_up() , "\n"; # 3
print count_up() , "\n"; # 4

print count_num() , "\n" ; #4
  • A.たとえばコスト削減。関数やデータベース接続を何度も繰り返す場合、都度呼び出しやデータベース接続を行うとコスト(時間、CPU負荷)がかかる。

    • 一回一回は微量のコストでも、数万回重なれば遅くなる
    • クロージャを利用したサブルーチンを使うことでそのコストを1回に削減できる
  • コスト!全く思いもつかなかった。

  • ってことで、「Perl クロージャ コスト」で検索。出てくる出てくる

文字列の変換

  • Q.あるファイルをネットからダウンロードすると、ファイル名が「\u65b0\u6a2a\u6d5c」となる。これを日本語に戻したい。
  • 自作スクリプトを作ってみたが、2段階の操作が必要になる
    • 以下が自作スクリプト。一度出力して、その内容を途中のヒアドキュメント部に貼付けて再度実行(かっこわるい
use strict;
use warnings;
use utf8;
use feature 'say';
use Encode;

# 謎の文字列
my $unknown_string = '_u65b0_u6a2a_u6d5c';

# 区切り文字らしい _ で分けて配列に入れる
my @chr_array = split /_/ , $unknown_string;

# 配列にいれた文字を整形?して配列に入れる
my @exchange_array;
foreach my $chr (@chr_array){
    next if $chr eq '';
    $chr =~ s/u/\\N\{U+/;
    $chr .= '}';
    push @exchange_array , $chr;
}

# 配列の文字を展開して表示する
say @exchange_array; # \N{U+65b0}\N{U+6a2a}\N{U+6d5c}

# 配列の文字をエンコードして展開して表示するが、そのまま表示されてしまう
say encode ('utf8' , "@exchange_array"); # \N{U+65b0} \N{U+6a2a} \N{U+6d5c}

# 出力された文字列をヒアドキュメント内にコピペすると日本語で表示される
my $doc = <<EOF;
\N{U+65b0}\N{U+6a2a}\N{U+6d5c}
EOF

say encode ('utf8' , $doc); #新横浜
  • A.hex,chrを使う
use strict;
use warnings;
use utf8;
use feature 'say';
use Encode;

# 謎の文字列
my $unknown_string = '_u65b0_u6a2a_u6d5c';

$unknown_string =~ s/_(u\w{4})/\\$1/g;
say $unknown_string;  # \u65b0\u6a2a\u6d5c

$unknown_string =~ s/\\u(\w{4})/chr(hex($1))/eg;
say encode_utf8 $unknown_string;  # 新横浜
  • 圧倒的短さ
  • 置換でマッチした文字列を置換対象のところでも使う「パターン参照」
  • 置換式オプションの e (eval)の使い方、繰り返し判別の g
    • forとかで1文字ずつ切り離しとかしない
  • 文字列を16進数から10進数にするhex関数、それを文字として解釈するchr関数

  • 他に、エディタ上で表示されている文字と、perlが解釈する文字は異なる、など文字コードの話

    • もちろん理解が及ばないが、「書いてあるままにPerlが解釈する訳ではない」「use utf8 と書けば良い訳ではない」ことを理解
  • ところで、できる人のコードと自分のコード見比べるとほんと死にそうになる

サブルーチンの返り値について

  • Q.返り値は配列リファレンスやハッシュリファレンスにしてスカラーで返すのがよいのか、それとも配列のまま、ハッシュのまま返すべきか
  • A.どちらでもいい、場合による。気をつけなくてはならないのは、返り値に「偽」がある場合
    • 例えば、配列が「偽」になるのは、配列内の要素が0の場合。しかし、配列の中にundefがあると、それも要素の一つとなり「正」となる。帰ってきた「値の評価」が重要
    • また、自然にかける方、コード量が減る方を選択するという判断基準もある

質問前提で考えることの有益性

  • 質問するからには、自分が「何が解っていないか」をはっきりさせておかないといけない
    • そうでなくては適切な答えは期待できない
  • 疑問点を整理しているうちに、まだ試していない方法を見つけたり、答えそのものが見つかったりもした

id:xtetsujiさん自身の話

  • 業界の最前線で戦ってきた id:xtetsujiさんの話、めちゃ面白かった
  • 生まれついてのプログラミング野郎だと思っていたんだけど、聞く限りでは思いっきり叩き上げ。現場で生き抜くための手段として使っていた感
    • そんな話が面白くない訳がない、引き込まれる。
  • YAPC::Asia 2014 Rejectcon でもそうだったけど、話力高くてほんと楽しく聞けた
    • なお、内容は凄まじかった
  • あと、地方の話をするときにiPadでgooglemapとかみながらするの楽しい。

    • 臨場感がある
  • (2015/08/29)下書きに置きっぱなしになっていたので公開