2015-02-09 Hatena Engineer Seminar #4 に行ってきました


2/7 に開催された、Hatena Engineer Seminar #4というイベントに 参加してきました。

Go からインフラっぽい話からモバイルっぽい話から、フロントまで、幅広くいろいろな話が聞けてよかったと思います。 その話も、割と現場寄りな、泥臭い話が多くて、とても面白かった。

astj さんの、レガシーな環境に CPAN モジュールを入れるためにほげほげ、とか僕も最近悩んでたやつで、はてなさんでも 決して完全に解決しているとは思えないけど、参考になるし、何より勇気がもらえる。

と、言うわけでとても楽しいイベントでした。懇親会も楽しかった。また(無事当選できたら)是非参加したいです。

以下は雑なメモ。(聴講中にメモってたやつ) だいたいスライドは公開されているっぽいので、そっち見た方がいいと思います。

Goで書かれたmackerel-agentのOSS化や自動化にまつわるあれこれ(songmuさん)

  • サーバサイドは Scala、エージェントは Golang
  • エージェントはユーザが使うものだから、ソースを公開。エンジニア的にも嬉しいし
  • ソースをオープンにするだけじゃだめで、p-r をちゃんと取り込んでいける体制になっていないといけない
  • CI があると公平になるし、パッチのクオリティが担保できる
    • travis 慣れているのと、tag にフックできるのがよい
    • コードフォーマットの検査(go vet golint)
  • Windows 対応もやってる (AppVeyor。インストーラとかも作れるらしい)
  • レビュー体制はこれから(今は気付いた時にやってる)
  • mackerel-agent-plugins(Nginx の接続数をとるとか)
  • リリースプロセスがオープンに(リリース用のp-rを作るmake, travis でビルドしてリリースタグを打ってリリース)
  • どこでも入っていて、テストも書けるので、better shellscript としての Perl は良い
  • tag は github token でやると権限のコントロールが大変なので travis にしている
  • 社内で検証できないプラグインはどうするか

はてなのサービスの開発環境(astjさん)

  • ブログ、ブックマークなどいろいろなサービスやってた
  • 開発者やデザイナーの手元で環境が使えるとよい
  • ブクマはレガシーな環境やミドルウェアの構築とかが面倒なので、仮想マシン使う(Vagrant)
  • ブログはそうでもないので、仮想マシンを使わず環境構築(plenv/Carton)
  • 5.8.8/Ridge/Moco/mod_perl/TS(部分的)/gulp/LESS(部分的)いろいろあったけど今はgulp
  • apache+nginex/MySQL/memd/Elasticsearch(2014/06から)
  • Cent/chef/rpm(社内ビルド)/CPANも
  • サービスはProcletであげてる
  • cpanm だと昔のモジュールとかをうまく管理できない
  • Vagrant + Chef でやる。秘伝のタレ化を防止
  • うまくインストールできないCPANモジュールはChefのクックブックで頑張る
  • サーバ(DBなど)は一部別の開発環境を共有。テスト時は手元に建てたものを使う
  • apt がobsoluteになったり、CPANが非互換になったりして、困る
  • 管理コストを減らすためにUbuntu->Cent(本番と同じ)にしたい
  • bento(chef official な Base Box)
  • B!KUMA は最初はエンドポイントを手で叩いていたが、つらいので、Nginxたてて reproxyするようにした
  • Hatena Blogの開発環境は Solr 以外は全部立つように

はてなブックマークの新機能における自然言語処理の活用(skozawaさん)

  • 10周年
  • トピックページ2/5リリース
  • クラスタリングの精度の問題とタイトル生成
  • クラスタリングは重要語抽出ベース(Elasticsearch)
  • タイトル生成は自然言語処理
  • Elasticsearch の Significant Terms Aggregation(重要語を取得できる機能)
  • 普段現れないような単語を取れる => 盛り上がってる話題
    • スコア計算はいろいろあるが、jlh scoreというのを使っている
    • 最近の単語のスコアが高くなる計算方法
  • トピックのどれかが含まれるだと、関係のないエントリも取れてしまう
  • スコアの合計8割以上になるようなエントリをとっている
  • トピックのタイトルは、記事のタイトルと本文1行目
  • キーワードの羅列では厳しい => どれかの記事を使うとうまくいきそう => どれでもいいわけではないので、重要文を取る
  • 媒体名が入ると困るが、辞書を作るのはコストが高い => 重要な部分をとれば自然と媒体名はなくなるはず
  • 重要語抽出 Elasticsearch -> TopicSum
  • 重要語のスコアが最大の記事のタイトルを抽出
  • かかり受け解析(Cabocha&ipadic)
  • 重要語を含む戦闘文節から末尾の文節まで。非文にならないように、品詞関係をみるヒューリスティックルールを一部採用
  • タイトルは全角スペースが文境界になっていたりするので、前処理をかける

はてなのiOSアプリとSwift(yashiganiさん)

  • はてなブックマークShare Extension で使用
  • ほぼ全てSwift(実験プロジェクト的位置付け)
  • アプリの規模として小さいので、試すのにちょうど良かった
  • 今後は標準的に Swift を採用
  • 同じコードが Objective-C->Swiftに書き換えるとシンプルになる
    • Generics のおかげで、安全なコードが楽にかける
    • 関数型っぽい記述(map, filter, sort etc.)
    • Closure Objective-C の Blocks だとつらい(慣れれば読める、慣れても書けない)
  • 言語は良いが過去の資産が使えない
    • Cで書かれたものの一部が使えない
    • C++
  • 最適化で壊れることがある
    • β配布まで気づかないことが多い
    • デバッグ実行時でも最適化レベルを上げれば再現する
    • 一時変数を使ったり、Swiftの機能を排除する(structを使わない、NSObjectを継承)
  • 型推論が微妙なのとリフレクションがまだない
  • JSON はOptional と相性が悪い Mantle 使うと良い
  • スマート会。チームを横断で技術共有

TypeScriptで実現するMVPアーキテクチャパターン(nanto_viさん)

  • 動的な部分は少ないが、投稿ツールやビューワでJSを使用
  • TSを使っている。Angular などのフレームワークは使わず、外部ライブラリは JQuery のみ
  • 型が使えて、型推論もある。関数の引数と戻り値の型を指定しておけば、追加の指定はほぼ不要
  • gulp-typescript でコンパイル
  • 開発環境はコンパイルしたJSをそのまま使用。本番はminifyや 結合したもの(CI環境を使用)
  • テストは QUnit/Sinon.js(モック)
  • ローカルではブラウザ、CIでは gulp-qunit
  • 最初は JS を書いていたが規模が大きくなると辛いので TS に移行
  • 移行は5行書き換えただけだった(外部宣言の追加、any型へのキャスト、typoの修正)
  • 徐々にTSのクラス、モジュールを使って書き直し(8000行のうちの半分くらいがTSらしいコードに)
  • AngularJS は学習コストが高いのと、チューニングが辛そうなので見送り
  • Vue.js は Android 2.3 で動かないので見送り
  • Alux/React.js 当時は情報が少なかったので見送り
  • プレゼンテーション層をテスタブルにしたいけど、フレームワークは上記の理由で厳しいし、データバインディングを自作するのは嫌
    • MVP アーキテクチャパターン(Model-View-Presenter)
  • MVVM と違って、View のIFを知っていて、自身の変更をViewに反映される(自前でやる)
  • DOM の変化する部分を View の Interface に定義(例: 場所、可視性、ページ番号)
  • Presenter は DOM の処理に依存しない形でロジックを実装
  • アニメーションは JQuery の animate を使用。Presenter の値が変わるたびに View に通知して表示を更新
  • テストは空のView(モック)を作って、Presenter のみテストしている(View は DOM を触るのでテストできていない)


2015-01-31 hachioji.pm #46 に行ってきた


本日 1/31 は hachioji.pm #46でした。

タイ料理を食べつつ、技術的な話とか、技術的じゃない話とかいろいろしていた気がします。

僕のスライドはこちら

以前 Perl Beginners ではなしたやつの続編、というか完結編みたいな感じです。

前々から、まとめたいなー、でもめんどくさいなー、と思っていたので、ちょうどいい機会でした。と、いうわけで、Otogiri の最新版(>=0.15) からは自動再接続入っているので、よろしくお使いください & 自動再接続まわりのコードを読む際に、この資料が参考になれば幸いです。

hachioji.pm は技術的なガチっぽい話から、ゆるふわな話から、ミルキィホームズの話まで、幅広く色んな話題が出てきて楽しいですね。今年もよろしくお願いします。



2015-01-27 DB プログラミングの話を社内向けにしたやつを、差し支えない範囲で公開します


表記の通りで、もともと社内向けに話すのに使った DB プログラミングに関するスライドを公開します。

もともとは、社内向けのやつを改修したり、テスト周りの整備をした際に、「なぜこういうことをしたのか」みたいな 話なのですが、その辺の背景とか細かい事例みたいなのはさすがに公開できないから、カットしてます。

カットした結果、だいぶ初心者向けっぽい話になっていますが、それなりに役にたつのではないかなぁ、と思います。



2015-01-19 探偵歌劇ミルキィホームズTD 第3話の信じる心について


例によって例のごとく、探偵歌劇ミルキィホームズTDのお話です。

Perl とか DB の話を期待してた人は閉じるボタンとか戻るボタンとか、クリッククリック!

ちょっと野暮な解説なので、ミルキィ好きな人もネタバレ的なの嫌なら、閉じるボタンとか戻るボタンとか、クリッククリック!

第3話の冒頭で茉莉音は CM の撮影に失敗し落ち込みます。そのあと、別の仕事で全国各地のパワースポット(?)を巡っていくうちに、よくわからない何かに目覚めて、「私には信じる心が足りない」と言い出して、 ガノターラ国へ「ありがたいお経」をもらうためのたびに出ます。

最初まったく僕は気づいていなくて、「あー、宗教的ななんかに目覚めちゃった話ね。お経を取りに行くのは西遊記だよね」くらいに思っていたのですが、実はコレはこの話の重要な伏線だったのです。

ガノターラ国への道中、ミルキィホームズは相変わらずのダメダメっぷりを発揮して、道中でとろけていたり、寝言でわけわからんことを言ったりして、その度に茉莉音はイライラを募らせていきます。 そして、ガノターラ国のカレー屋で、「吸いましょう!」を繰り出したミルキィホームズに対してついにはキレてしまい、「私一人でお経を探す」と一人で出て行ってしまいます。街中で「ありがたいお経」の 情報を集めていた茉莉音ですが、突然捕らえられてしまい、投獄されてしまいます。捕らえられた茉莉音をミルキィホームズが探し出し、捕らえた張本人のガノターラ国の王子との「カレー対決」に勝利し、 無事に茉莉音を助け出す、というのが第3話のお話でした。

ラストで、「結局、ありがたいお経、手に入らなかったけど、いいんですか?」とシャロが聞きます。それに対して茉莉音は「ええ。それよりも、もっと大事なものを手に入れたから」と答えます。 「大事なもの」ってのは最初は、王子との対決で取り返したエレメントだと思っていましたが、実はそれだけじゃなかったんですね。

それが冒頭に出てきた、足りなかった信じる心。

それに気づいて第3話をもう一度見てみると、見え方がまたちょっと変わってきます。どう変わってくるか。。。そこまで書いてしまうのはいくらなんでも野暮すぎると思うので、 各自見て欲しいなぁ、と思います。

こういう所が何気にしっかり作ってある所もミルキィホームズのいい所なのですが、全く気づかなくても問題なく楽しめちゃったりもするので、皆様も見てみると良いと思います!



2015-01-11 Mock::Quick というモジュールがいい感じ


偶然見つけたのですが、Mock::Quick というモジュールがいい感じです。

Synopsis みると結構色々できそうな感じなのですが、とりあえずTest::Mock::Guardの 代わりとして使っています。こんな感じ(↓)

で、「Test::Mock::Guard で良くね?」と言われると、まあそうなのですが、あのコードかなり難解で、何かミスったり、万一バグ踏んだ時に割と辛いっていうのと、 Class::Loadに依存していて、これの依存が結構多いので既存の環境で使いたくなった際にちょっと躊躇してしまう、 ってのがあります。Mock::Quick はその点、依存がとても少なくていい感じです。

qclass 以外にも便利っぽい機能が色々あるので、もう少し色々試してみたいと思います。



2015-01-04 「探偵歌劇ミルキィホームズTD」が始まったったー


あけましておめでとうございます。

今日はミルキィの話なので、Perl とか SQL とかその辺のお話を期待されている方は、閉じるボタンとか戻るボタンとかをクリッククリックしちゃってくださいね。

表記の通り、探偵歌劇ミルキィホームズTDが始まりました。

MX勢は昨日から、BS勢は今日というか、明日の0:00からですね。

感想を割とちゃんと書こうかな、と思っていたのだけど、まだ自分の中でそこまで消化できていないので、雑な感想を書きます。

ミルキィホームズの本放送をリアルタイムで見れるのは、「ふたりはミルキィホームズ」以来でした。 当時、めっちゃ期待していたのですが、ふたりは... はぶっちゃけ微妙でした。

ふたりは... のコミックス版(下記のやつ)は良くできていたので、これは監督とか脚本とか、 スタッフがダメダメだったのではないか、と僕は思っていたわけです。(ミルキィ情報局が本編だったのだ、と自分を納得させた)

なので、TD がふたりは... とほぼ同じスタッフで作られる、と知ったときは正直なところかなり不安でした。

で、しばらくすると、TD のプロモーションが公開されたわけです。(↓これ)

これを見て、僕は「TDいけるかも」と思いました。キャラクターは相変わらず可愛いし、音楽がかっこいい。(本編の音楽も同じスタッフが作っています)。 ストーリーがダメダメでも、絵が可愛くて、音楽が良ければ、なんとでもどうとでもなるでしょ、と思ったのでした。OP/ED も良さげだし。

と、そういう前提で TD の本放送を見たのですが、良かった良かった。絵柄変わったし、新キャラクターも出てきたから雰囲気は違うけど、 これはいつものミルキィだ、と思いました。

1話ですと、あの雑な伏線の回収の仕方が最高にいいですね。ミルキィはなにげに伏線の貼り方と回収の仕方がすごいので、 これからも色々見せてくれるのではないか、と期待しています。



2014-12-31 2014 年のふりかえり


2014 年も残すところあとわずかとなりました。ざっくりではありますが、この blog に書いた記事を中心に振り返ってみようかな、と思います。

1月〜3月

初詣等のごく一般的なお正月行事を除くと、1/3 のミルキィのお正月ライブからスタートした2014年でした。

1月ごろから、Otogiri と Reply を組み合わせると便利かも、ということに気付いて、色々と周辺環境を整え始めたようです。

4月〜6月

1月〜3月に引き続き、Otogiri + Reply の環境を整えていた感じです。Otogiri::Plugin::TableInfo というモジュールを書いて、 かなり便利に使えるようになりました。実装はめっちゃ大変でしたが。

あと、忘れちゃいけないのが、Acme::MilkyHolmesをリリースした!

Acme なので、基本的にはふざけたモジュールなのだけど、中身はちゃんと作ったつもりだし、(記事にも書きましたが)、僕は仕事で Moose 系のクラスビルダをちゃんと使ったことがなかったので、その練習も兼ねていたりします。

7月〜9月

夏はやっぱり YAPC ですね!

あずまさん(@ytnobody)と Otogiri の話をしよう、ということになって応募しました。で、選考のちょっと前に、YAPC で話す、ということという、ポエムを投稿したところ、思った以上の好評いただいて、結構有名なハッカーからもブクマとかRTしてもらったので、「よっしゃこれはワンチャンあるで」と思っていたのですが、今年の大量かつハイレベルな応募の前にあえなく撃沈したのでした。

YAPC の感想はこんな感じ。

(タイトルが若干頭悪い感じなのは、ミルキィのせいなので、気にしないでください)

YAPC 本編では漏れてしまった Otogiri の話ですが、その後 Rejectcon というイベントで無事発表することができました。良かった & 感謝です。

10月〜12月

10月11月は仕事がかなり忙しかったので、あまり記事を書いてなかったようです。12月はイベント関係の記事が多いですね。

最後に示した記事の Perl 入学式の講師は結構大きな経験でした。サポーターは何度もやっていましたが、教える側になってみて、 あらためて「サポーターって大事だな、やっててよかったな」と思いました。

毎年恒例の Advent Calendar 関係は Perl 入学式 Advent Calendarのみ参加しました。

年越し等の普通っぽいイベントを除くと、昨日のミルキィのライブで僕の 2014 年は終了しました。

イベント関連

記事書いている限り、14回技術系のカンファレンスに行っていたらしい、Perl 入学式のサポーターなど、記事書いてないけど行っているものもあるので、多分20回〜30回程度ではないかと思う。別のイベント(謎)の 方の参加回数はもっと少ない(多分片手で数えられるはず)ので、よかった僕は正常だ。(昨日イベントに何回参加したとか、そんな話をしていたのである。わかる人にしかわからない話ですねコレ)

まとめ

この tweet に集約されるんじゃないかな、と思います。

と、いうわけで、今年もありがとうございました & お世話になりました。

皆様よいお年を!



2014-12-26 Perl 入学式第4回補講で講師をやってきました


これは Perl 入学式 Advent Calendar 2014の26日目のエントリではありません。でもまぁ、そんな感じのエントリです。

12/20 に開催された、Perl 入学式第4回補講 で講師をやってきました。 やってみて初めて分かったこととかあったので、その辺の話をとりとめもなく書いてみようかな、と思います。

その前に軽く自己紹介っぽい話。

私と Perl 入学式

Perl 入学式に関わり始めたのは多分 2013年の途中からです。

2013年くらいから、@xtetsujiさんの紹介でhachioji.pmと関わり始めたのがきっかけな気がします。 YAPC でちょっと喋ったことある人飲み会(題名忘れたけど、そんな趣旨の飲み会)ってのがあって、@papix校長と会ったのは確かその時が最初なはず。

で、細かい経緯は忘れたけど、サポーターとして Perl 入学式に関わるようになったのでした。

多分最初に参加したのが 2013年8月23日っぽいです。

んで、それ以降、サポーターとして、都合のつく日はチョイチョイ参加してた感じです。

最近の Perl 入学式の話

いつ頃からか忘れたけど、最近は Perl 入学式のコアスタッフ(?)として、いろんなこと考えたり、資料チェックしたり、資料直したり、そんな事をしていたりします。 今回講師をやったのも、(多分)その一環ですね。

初めて講師してみた話

資料について

自分も commit 権あるんで、あんまり褒めるのもどうかと思うけど、Perl 入学式の資料って、スタッフの皆さんがちゃんと考えて、ちゃんとメンテしてるモノなので、 かなりいいものだと思います。まだまだ改善点は色々あるのだけど、よくまとまってていいなぁ、と思います。

教える、ということ

大学時代、大学院時代に塾講師のアルバイトやってたんで、それなりに教えるのは好きだし得意だと思っています。Perl もなんだかんだで10年以上書いてるので、 結構細かいところも知っているつもりです。

Perl 入学式で教える、ということ

そんな僕が、第4回の補講で講師をやってみたのですが、いやー大変でした。

教えていて、一番怖いのは、「ちゃんと伝わっているか、理解されているか」ということです。Perl 入学式の生徒のみなさんは、割と積極的に 質問とか疑問を出してくれて、それは本当にありがたいことだ、と思っています。

でもね、だけどね。それでも不安になるんですよ。

僕が講師をやってた4時間、「あーこれ難しいな、大丈夫かな?」って何回言ったか覚えてませんが、沢山言ったことは憶えています。

さっきも書きましたが、Perl 入学式の資料ってすごく良くできていて、優秀な Perl ハッカーの方々や、プロの校正者でもある @note103さんや、 (note103さんもそうだけど)Perl入学式の卒業生がチェックして、直しているものなので、とてもいいものです。

それを使って講義をしていても、やっぱり難しい概念って沢山あって、「伝わっているのかな、大丈夫なのかな?」と講師の立場でやってみると不安になってしまうものなのです。 プログラミングとかその周辺技術って、やっぱり難しいもんだよなー、と僕は思うのです。

サポーターのありがたさ

そんな感じで、不安を抱えつつも講義をしていたわけですが、そこで改めて分かったのはサポーターの存在の大きさでした。

「あーこれ難しいな、大丈夫かな?」って何度も思いましたが、実際に演習問題をやる際は、サポーターの皆さんがフォローしてくれるので、 「まー僕の説明がダメダメでも、なんとかなるかもなー」と思うことができました。

サポーターの皆さんがちゃんとフォローしてくれてるから、「まーなんとかなるだろー」と思って、講義を進めることができました。そしてまた、 自分が1年ちょっとくらい、サポーターとして色々やってきた事って意義のあるものだったんだなぁ、と実感できて嬉しく思いました。

まとめ

Perl 入学式って、なんやかんや1年半くらい関わっていますが、とてもいいと思います。Perl とかプログラミング言語に自信のない方は生徒として、 Perl の経験がある方はサポーターとして、関わってくれる方が増えたら嬉しいなー、って僕も思います。



2014-12-23 Perl Beginners #16 で DB の自動再接続の話をしました


当日に LT 枠が余っていたっぽいので、急遽スライドを仕立てて、最近気になっていた ORM やウェブアプリで DB の自動再接続を する際の注意点について話しました。

スライドはこちら(↓)

全然ビギナー向けっぽくなくて、ちょっと申し訳ない感じではありますが、スライドにも書いたのですが、この情報を見つつ、Teng の自動再接続周りの コードを読むと何やってるか理解できて勉強になるんじゃないかな、と思います。

Otogiri の自動再接続対応は、遅くともお正月休み中、できれば年内にはやってしまいたいなー、と思っておりますので、乞うご期待!

2014-12-30 追記

この記事を書いた後、このへんに造詣の深い @nihen さんから tweet もらいました

と、いうわけで、DBIx::Connector や Teng の issue なんかをいろいろ見てみました。

Teng は一時期は DBIx::Connector を参考にした fixup reconnect をサポートしていた(?ブランチだけ?)のだけど、そういうののハンドリングはアプリでやった方が良さそう、 ということで、今の実装(トランザクションの対応と fork/prefork の対応)になってるっぽい感じですね。

あと、Otogiri の対応もとりあえずやった。けれども、めっちゃ自信ないので、 しばらく様子をみて問題なさそうならマージするかなー、と思ってます。



2014-12-19 リファレンスの使い方とかの話


これは Perl 入学式 Advent Calendar の 19日目の記事です。

こんにちは。東京のPerl入学式でサポーターをしている@tsucchiです。

昨日は papix さんのPerl入学式の歴史 〜その3 2013年〜でした。「ただいま作成中」しか書いてない気がしますが、 きっと気のせいでしょう。

本日は毛色を変えて、リファレンスの話をしようかと思います。

はじめに

さてさて、Perl入学式では第3回から「リファレンス」の使い方を学習しています。リファレンスは最大の山場の一つで、かくいう僕もきちんと理解して使える様になるまでには 結構時間がかかった記憶があります。校長も「難しい!」「たくさん書いて慣れるしかない!」と、良く言ってますよね。

リファレンスの文法的なものは、Perl 入学式のスライドや、入門書をご覧いただくとして、 ここでは「リファレンスって何に使うの?なんでリファレンスを使うと嬉しいの?」みたいな話をしようと思います。

リファレンスの使い道

リファレンスの使い道は大きく分けて 3 つくらいだと僕は考えています。

  1. 複数の配列を関数やメソッドに渡す
  2. 複雑なデータ構造を作る
  3. 関数やメソッドで引数を更新する

このうち、最初の1つだけは Perl 固有の事情で、残りは他の言語でも当てはまるリファレンス(やポインタなどの参照系のデータ構造)に当てはまる特長です。 では順番に見ていきましょう。

複数の配列をサブルーチンに渡す

サブルーチンをちゃんと作れるようになったぶつかる難問(?)の一つが、「複数の配列を引数にとるサブルーチン」です。たとえば、下記みたいな、「二つの配列を引数にとり、配列の中身が同じかどうかを 比較するサブルーチン: is_same_array()」を作るとします。

Perl の引数の制約がなければ(あるいは知らなければ)こういう風に書きたい(書いちゃう)ですよね?

# @array1 と @array2 が同じなら真を返す
sub is_same_array {
    my (@array1, @array2) = @_;
    ...
}

ですが、これはうまく動きません。たとえば、下記のようなコードを書いたとすると...

my @a1 = (1, 2, 3);
my @a2 = (1, 2, 3);
if ( is_same_array(@a1, @a2) ) {
    print "配列の中身は同じ\n";
}
else {
    print "配列の中身は違う\n";
}

「配列の中身は違う」の方が出力されるはずです。 Perl のサブルーチンの引数は配列として取り扱うため、is_same_array の第一引数@array1(1, 2, 3, 1, 2, 3)のように2つの配列をくっつけた値が入ってしまうのです。

こういう場合は配列リファレンスを渡すようにします。

# $array_ref1 と $array_ref2 が同じなら真を返す
sub is_same_array {
    my ($array_ref1, $array_ref2) = @_;
    ...
}
my @a1 = (1, 2, 3);
my @a2 = (1, 2, 3);
if ( is_same_array(\@a1, \@a2) ) { # 配列ではなく、配列リファレンスを渡す
    print "配列の中身は同じ\n";
}
else {
    print "配列の中身は違う\n";
}

今度は「配列の中身は同じ」が出力されるはずです。(is_same_arrayをちゃんと実装すれば)

複雑なデータ構造を作る

複雑なデータ構造を作るために、リファレンスはよく使われています。

Perl入学式のスライドでは2次元配列を例に説明しているので、 ここでは別の例を出してみましょう。

下記みたいなデータがあるとします。DB とか CSV とか Excel とか HTML のテーブルとかでよく見る構造ですよね?

id name age
1 Sherlock Shellingford 15
2 Nero Yuzurizaki 15
3 Hercule Barton 16
4 Cordelia Glauca 17

このデータの1行分はどういうデータ構造をつかうのが自然でしょうか?配列でもいいですが、ハッシュの方がわかりやすいので、ハッシュがいいですね。

こんな感じです。

my %row = (
    id   => 1,
    name => 'Sherlock Shellingford',
    age  => 15,
);
print $row{name}; # => Sherlock Shellingford

では、このデータ全部は、どのような構造がいいでしょうか?「配列で中身がハッシュ」(?)

配列は配列、ハッシュはハッシュなので、そのまま共存させることはできません。

ここで必要になってくるのがリファレンスです。ハッシュリファレンスであれば、配列に入れることができます。こんな感じです。

my @rows = (
    {
        id   => 1,
        name => 'Sherlock Shellingford',
        age  => 15,
    },
    {
        id   => 2,
        name => 'Nero Yuzurizaki',
        age  => 15,
    },
    {
        id   => 3,
        name => 'Hercule Barton',
        age  => 16,
    },
    {
        id   => 4,
        name => 'Cordelia Glauca',
        age  => 17,
    },
);
print $row[0]->{name}; # => Sherlock Shellingford

このように、配列の中にハッシュが入っているような構造や、配列の中に配列が入っているような構造や、ハッシュの中に配列が入るような構造を 作りたい場合にリファレンスを使います。(もっと複雑なのも作れますが、あまり複雑すぎるのも良くないので、よく考えて使いましょうね!)

関数やメソッドで引数を更新する

たとえば以下のような配列があるとします。

my @people = (
    'tsucchi',
    'xtetsuji',
    'papix',
    'ytnobody',
    ...
);

で、この配列の中身をすべて小文字->大文字に変換する、to_upper_items という関数を作りたいとします。

sub to_upper_items {
    my (@array) = @_;
    for my $item ( @array ) {
        $item = uc($item);
    }
}
to_upper_items(@people); #これで中身が全部大文字になってほしいけどNG

これはうまく動きません。関数でなければ大丈夫ですが、関数だとダメなのです。なぜかというと、関数の引数は渡ってきた値をコピーします。なので、関数に渡した @people と 関数内で使っている @array はコピーされた別物なのです。これは、関数内で不用意に書き換えるミスを防げるので一般的には望ましいことなのですが、今作りたい関数にとっては 都合が悪いです。

この場合もリファレンスを使います。リファレンスはコピーされるのはアドレスなので、関数内の実体は渡したものと同じになります。(この辺の仕組みはリファレンスをちゃんと理解しないと ピンとこないと思いますが...)

sub to_upper_items {
    my ($array_ref) = @_;
    for my $item ( @{ $array_ref } ) {
        $item = uc($item);
    }
}
to_upper_items(\@people); #リファレンスを渡せば大丈夫

このようにリファレンスを渡すと、配列の中身を書き換えることができます。これはPerl入学式のスライドでは、 「リファレンスのはまりどころ」として紹介しているのですが、意図してやりたい場合もありますよ、というお話でした。

まとめ

他にもリファレンスの便利な使用例はいくつかあるのかもしれませんが、ぱっと思いついたものを書いてみました。リファレンスは慣れるまではなかなか大変なのですが、便利なもの であることは間違いないので、使いこなせるようになるといいですね!

明日は akms さんです。お楽しみに!