月別アーカイブ: 2012年11月

FacebookとTwitterの連携に対する一つの考え

こんにちは、最近はTwitterで開放的に発言しているおがた (@xtetsuji) です。

ネットを検索していると「TwitterとFacebookを連携すべきか」「Twitterの投稿をFacebookに流すべきか」「Facebookの投稿をTwitterに流すべきか」という疑問が散見されました。私もどうするのがいいのかと思っていたので、興味深く読みあさってみましたが、後述の理由によりあまり参考になりませんでした。

この場合、「すべきです」という「主張」は少なくて、そういう人は主張するまでもなく「やり方」を書いて終わりにする人が多いようです。2012年11月現在であれば、https://twitter.com/settings/profile にアクセスしてTwitter社が提供するTwitter→Facebookの連携投稿が設定できます。Facebook→Twitterの連携投稿も https://apps.facebook.com/twitter/ 等でできるんじゃないでしょうか、以上、って感じです。すべきメリットとかの主張は無し。あらら。

一方、「すべきではない」という主張をする人も一定数いて、特にFacebookに思い入れのある方の一部がそういう主張をしている事が多いようです。ただ、理由が論理的でないところが笑いどころで、「TwitterとFacebookは空気感が違うからです!!!!!!」なんてキリッと言ってしまうところが意味不明。空気感って何だ?文字数の違い?こういう回答をしている人は大抵「Facebook◯◯の会」「SNS◯◯の会」といった肩書きを名乗っているのも面白かったです。思い入れ強いんだね。

…;とは言っても、私のTwitter TL、Facebookニュースフィード、両方じっくり見ていても、そんな空気感の違いがあるようには思えない。Twitterでも承前承前を繰り返して140文字をはるかに越える議論を展開した挙句Togetterでまとめられるケースもあったり、比較的長文が投稿できるFacebookでも一言二言しか投稿しない人がいたり、投稿内容や投稿文字数が醸し出している空気感という違いは無いように感じます。Twitterはエコシステムが発達しているので、画像を添付したりも擬似的にできますし、その点の機能についてはFacebookと大差ない。

まぁ、Twitterは不幸自慢、Facebookはリア充自慢が蔓延している傾向といった違いはありますが、リア充自慢はSNSの歴史が始まってからの伝統みたいなものがありますから。Twitter社はTwitterのことをSNSではなく「マイクロブログ」と読んでSNSではないと否定しているわけで、私もそれに賛同する派です。

ただ、TwitterにはRTがあったり、Facebookには「いいね!」やシェアがあったり、両者には機能的に違うものがあるのは確かです。同じTwitterでも、ウェブで見るのと各種クライアントソフトで見る場合では風景が違うように見えるのは気のせいではないでしょう(Twitter社は現在、Display Requirementsを開発者に強要する事でその違いを排除しようとしているようですが)。

ではどうするべきか、考えてみました。

Twitter→Facebook連携の場合

「Twitter→Facebook連携」と仮に名づけてみましたが、Twitterの特定のアカウントに投稿した内容をFacebookのウォールやページに投稿することです。

この機能はTwitter社が提供していて、2012年11月現在 https://twitter.com/settings/profile にアクセスすればすぐに設定することができます。Facebookでもサードパーティが作った機能もあるけど、たぶん似たり寄ったりだったりTwitter社のDisplay Requirementsで排除されるかもしれなかったり、流動的なので、もしやるのであったらTwitter社公式の機能を使ったほうがいいんじゃないかな、というのが私の考え。

ただ、この機能はTwitter社公式(?)の機能にも関わらず、連投したツイートを本当によくこぼす。後述の議論にもありますが、これでは色々と使えない。

「ところで、Twitter→Facebook連携はすべきなの?すべきでないの?」の私なりの答えをしていませんでした。

私なりの回答をしますと「文脈を持ったツイートをFacebookにフィードするのはやめたほうがいいのではないか、それ以外はご自由にどうぞ」といった感じになるでしょうか。

では「文脈を持ったツイート」とは何かというと

  • 承前を繰り返して複数のツイートで140文字以上の発言をTwitterでする場合
  • 公式RTをした直後に、その公式RTをしたツイートについて言及する場合
  • 非公式RT
  • ハッシュタグを伴ったもの、特に実況、いわゆる「tsudaる」行為

等のこと。

先ほども挙げた通り、Twitter→Facebook連携は、よくツイートをこぼします。例えば A B C Dとツイートを連投した場合、B をこぼすことは結構あります。また、Facebookの恣意的なエッジランクにより、他者のFacebookニュースフィードでは、A B C D の順で表示されるとは限らないという点もポイントです(その人のウォールに行けば順序そのものが見られますが、そこまでする人が一体どれくらいいるでしょうか)。最悪、「Bをこぼされる→FacebookのエッジランクによってニュースフィードからCが重要でないと見なされ表示されない→時系列無視されて D A の順で表示される」といった無茶苦茶なことがこのシステムでは起こりえます

この場合「文脈を持たないツイート」つまり1ツイート完結の話題であれば何の問題もありません。こぼされても、エッジランクで淘汰されても他に影響ありません。ただ、そのツイートが文脈を持っていた場合、他のツイートへのフォローや他のツイートからの参照となっていた場合、時と場合によってはFacebookのニュースフィード上で意味不明となる事があります。

特に上記の現象は連投によって起こる事が多く、実況(tsudaる)行為をする人は、普段Twitter→Facebook連携をしていても、実況時には一時的にオフにするくらいしたほうがいいと思います。他者のニュースフィードを埋めて迷惑をかけるからではなく、文脈無視の無茶苦茶な時系列での情報連投になるかもしれないからです。

RTの話では、公式RTは、たぶん標準のTwitter→Facebook連携ではフィードされないはずです。それなのに「さっきのRT…;」というツイートがFacebookにフィードされても意味不明であることは確かでしょう。非公式RTも文脈を持っていて、Twitterの世界の人はそれを追いやすいかもしれませんが、Facebookの世界に閉じこもっている人にとっては、単体でそれを切りだされても分からないといった問題をはらんでいます。RTを実際のツイート上の文脈で語るようなTwitterの使いかたをしている人には、少なくとも私はTwitter→Facebook連携はおすすめできません。私はそれほどFacebook愛がある人ではありませんが、Facebook愛のある人に嫌われるのはTwitterのRT文脈をFacebookに持ち込むことなんじゃないかと勝手に想像しています。

それ以外の一話完結のツイートの場合、Facebookにフィードされたおかげで、Facebookの返信で話題が盛り上がったり、良いこともあるんじゃないでしょうか。連携関係なく、Facebook内部での投稿の場合は、Facebookのコメント機能を利用することが多いので、それがいわゆるスレッドとして機能することで文脈を表現することができます。

Facebook→Twitter連携の場合

今度は逆のケース、Facebookのウォールに投稿した内容を、Twitterの特定のアカウントでツイートする内容です。

これに関しての私なりの回答をしますと「自分のウォールを公開設定にしている人、そうでない人は投稿時の公開範囲設定を理解した人なら問題無さそう。ただ、140文字を越えるポストを繰り返すとTwitterから読むときにリンクを踏むのが相当面倒くさいと思われる」でしょうか。

なんか複雑になってしまいましたが、これの否定形をしているFacebook→Twitter連携のツイートの見え方を考えると良さそうです。

まずは自分のウォールを公開設定にしていない人は、140文字で収まらない長文投稿や、画像等の添付がある投稿は “fb.me” URL を伴ったツイートとして投稿されます。この先にアクセスすれば投稿内容を見ることができるからTwitterにツイートしても問題無いと思われる人もいるかもしれませんが、私はこれが面倒でなりません。たとえブラウザでFacebookにログインしている状態の人でも、iPhone/Android等のスマートフォンではTwitter専用クライアントを使っているケースがあります。そういう場合、URLクリックをアプリ内ブラウザで開こうとするわけです。そこで自分のFacebookウォールを公開設定にしていない人は「Facebookにログインしないと見られないよ」というページを見ることになるわけです。これは面倒臭い。Twitterのオープンな世界と相容れないと感じます。

Facebook→Twitter連携をしている人でも、普段は「友達のみ」の公開範囲で投稿している人はTwitterへのフィードは発生しないはずです。そういう人はFacebookの「公開」で投稿した場合にのみTwitterへのフィードが発生することが分かっているので、そういうときはTwitter向きのコンパクトな発言をしようと理解するクッションが生まれるはずです(と期待しています)。「友達のみ」にはじっくりとFacebookで長文を語り、世間に「公開」する発言はボソッと一言であれば、Facebook→Twitter連携の親和性が生かされることになるでしょう。

その他のアプリとのFacebookやTwitterの連携の場合は?

FacebookやTwitterは事実上の標準となったことは異論がないと思います。

その他のアプリとのFacebookやTwitterの連携はどうすると良いでしょうか。この場合、2通りの大別をしてみましょう。

  • SNSやマイクロブログ
  • それ以外

SNSやマイクロブログというのは、例えばmixiボイス等のことですね。この場合、mixiボイス→Twitterという連携が考えられます(逆は通常の方法ではできない)。この場合も文脈の議論を持ち出せばいいと思います。mixiボイスならmixiの世界の文脈をTwitterに持ち出したとして、Twitterのみの世界の人に通じるかという思考。mixiボイスで一話完結したボイスをTwitterにフィードするのは何の問題もないと思います。{その他のSNSやマイクロブログ}→Facebookのような連携も同様でしょう。

それ以外のアプリも、TwitterやFacebookへの連携投稿をサポートしているものはたくさんあります。例えばInstagramやFoursquare等。Instagramなどは「写真SNS」などとSNSに強引にくくられるケースもありますが、「いわゆるSNS」と、何らかのキー(Instagramであれば写真)を軸としたゆるいコミュニケーションサイトは別に考えたいところです。

こういうサイトの場合は「一話完結」している場合がほとんどなので、InstagramでTwitterやFacebookに写真投稿、FoursquareでTwitterやFacebookに位置情報投稿というのは一つの話題として良い活用法だと思います。ただ、なぜかはよく分かりませんが、私のTLでは #nowplaying (今聴いている曲) は嫌われる傾向にあるようです。この部分は、通常の投稿同様、何事も限度があって、つまらない写真をInstagramで投稿フィードし続けたり、どうでもいい位置情報をFoursquareで投稿フィードし続けたりしたら、まぁ私でもウザイなぁと思いますね。私はFoursquareのヘビーユーザですが、比較的人の興味をひくと思われる場所のみフィードして、バス停や鉄道駅などへのチェックインはフィードしないようにしています。

じゃぁ、あなたは今どうしているの?

以前はTwitter→Facebook連携をしていましたが、前述の「こぼす」問題、あと私があまりFacebookで好まれるような「リア充投稿」をしないので「ちょっと馴染まないなぁ」ということで、現在は連携を切っています

ただ、Facebook世界の人たちの興味を引くような一話完結のツイートは、別途手作業でFacebookにもクロスポスト(?)するようにしています。私の場合は、Twitterクライアント「夜フクロウ」「Tweetbot for iOS」に投稿するときにツイートをコピーしておいて、Facebookにも合うかなと思った投稿を、OS X / iOS 標準の Facebook 投稿機能でペーストして投稿するというスタイルをとっています。

そういうのが面倒な人の場合、HootSuite等は標準でクロスポストをサポートしているので、そういうクライアントを使うのがおすすめです。私の場合は、Twitterクライアントはユーザストリーム対応じゃないとというこだわりがあるので、夜フクロウやTweetbotを使っているだけに過ぎません。

Instagram、Foursquare等のサイトの投稿は選別しつつTwitterとFacebookにフィードしています。前述の通り、バス停や鉄道駅などのFoursquareチェックインは除きますが、大体はフィードしていますね。その他のアプリについても、だいたいそんな感じ。ただ、ハッシュタグ付きポスト等、Twitterの文脈を強く持っているInstagramやFoursquareの投稿やチェックインの場合はFacebookには投稿しない、といったこともします。

Twitter→FacebookもしくはFacebook→Twitterという連携をしている場合、他のアプリからTwitterとFacebookに同時投稿をした場合に、どちらかに多重投稿をしてしまう可能性があるのもデメリットではあります。私がTwitter→Facebook連携を切った一つの理由でもあります。Facebookのニュースフィードで「それは情弱の所業」と断罪していた人がいたのもキッカケでした。まぁ、Facebookのエッジランクに期待とはいえ、同じ内容の投稿が複数流れてきて気持ちいい人はあまりいないでしょうね。

「TwitterがRSSを殺した」という言葉もあるようですが、ブログの投稿などもTwitterとFacebookに自動ポストするようにしています。私の場合は2012年11月現在Posterousというブログサービスを使っていますが、現在の大抵のブログサービスにはTwitterやFacebookへの更新通知機能は存在するでしょう。そういう点では、RSS/Atomなどのフィードリーダーを知らなかった人も、半リアルタイムで情報をプッシュできるTwitter/Facebookは新しい時代のフィードリーダーといっても過言ではないのかもしれません。

Google+はどうですか?他はどうですか?

Google+も使ってみたいのですが、久々に行ってみたら見事に廃墟になっていて、退散してきました。TwitterのEvil化(API改訂など)、Facebookの独占などが騒がれますが、現状Google+はそもそも書き込みAPIも持たず、それゆえエコシステムも育たないので、そこが解決されない限り使い勝手は悪いよなぁというのが印象です。ウェブの作り込みは見事なんですけどね。

Google+の投稿読み込みAPIは存在するので、Google+を起点としてTwitterやFacebookへフィードするという使い方もあるようです。

Google+の最近は、ハングアウトなど、TwitterやFacebookよりもミーティングや議論に適した機能などがあるので、一度は使ってみたいものですが、人が集まらない限りはどうしようもないなという感想です。

TwitterやFacebookがEvil化しようと不穏な動きをしようと、多少のことでは現状は揺るがないでしょう。3年先はどうか分かりませんが、少なくともここ1年2年はそうであると言えます。プロプライエタリなシステムが嫌いだと公言している人もTwitterやFacebookを(仕方なく?)使っている時代です。SNSは言うにおよばず、Twitterが属するマイクロブログというジャンルも乱立の時代を経て淘汰され、今後はせいぜい「特化型」が細々と生き残るのではないでしょうか。

「使い分け」なんて考える必要無いんじゃない?

全てに平等に情報をフィードして、全てを平等に使うというのももちろんアリかと思います。この記事では「…;すべし」といった強制はしていませんので、この記事が何かの参考になれば幸いです。

はてなブログでMathJaxを使う

こんにちは、ずいぶん昔に数学科で数学を勉強していた おがた (@xtetsuji) です。

2014年3月5日追記: 2014年3月現在、はてなブログはhead要素中に任意の要素を差し込めるようになっています。ダッシュボードからブログを選択して、設定→詳細設定→headに要素を追加、にMathJaxのタグを追加してやるだけで良いです。

はてなブログの設定でMathJaxを全域で有効にする

というわけで以下は古い情報です。

………

さる2012年11月7日はてなブログが1周年だそうで、当時作ったっきり何も書いていなかったはてなブログ ogata.hatenablog.com を思い出しました。「とりあえずサブドメインスクワッティングで ogata 取れるかなー」と思ったら取れちゃった感じ。普段は日本中のオガタさんやテツジさんに負けているのに、たまたまでした。

このメインブログ(?)は2012年11月現在Posterousで運用させてもらっている(色々細かいところが気に食わないので今後変えるかもしれない)のですが、何か別の使い方ができないかなーって考えて、はてなブログのほうは数学とMathJaxの実験場にしてみるかと、数学の記事をいくつか書いてみました。

MathJaxとは、LaTeXやMathMLの記法で数式が書けるJavaScriptライブラリ。Ajaxでいろいろやってくれるスグレモノ。この分野だと、昔はLaTeX記法をクエリ引数に渡して画像化してくれるmimeTeXなんてのものがあって、はてなダイアリー(ブログじゃない古いほう)でも対応しているようだけど、なんとなくMathJaxのほうが手元で実験して良かったなと思った。

理由:

  • mimeTeXは img 要素の src 属性の中に数式情報が入っちゃうけど、MathJax は HTML のソースコードの中に LaTeX 記法がそのまま見えるので、再利用性はさることながら、アクセシビリティという観点からも好ましい。
  • MathJaxが出力する数式のフォントクォリティが意外に良かった。mimeTeXの出力はアンチエイリアスされていないガタガタの線画数式GIF(?)って感じで、Web 2.0 から数年経っているのにコレはないよって感じ。
  • メインブログではもう容易に試せない状態だった。既にPerlの記事がたくさんあって、HTML中に書かれたASCIIのドル記号が数式の区切りや特別な意味を記事全体で持つなんて、今さらできないですよね。
  • 新しいものを試してみたかった。

「アクセシビリティって何?」という方は、全盲や弱視の数学学習者や数学者を想定するといいかなと思います。そういう方に対しても、スクリーンリーダーでLaTeX記法が読みあげられれば意図が伝えられます。結構大事。実は私の学生時代のゼミの先輩も全盲でした。

MathJax では LaTeX のようにASCIIのドル記号で囲む事でインライン数式を表現できるのですが、Perlの記事がたくさんある状態でそれをやったら…。インライン数式とブロック(ディスプレイ)数式の始点と終点の記号をMathJaxの設定で選べはするのですが、なんか面倒だし最初から複雑な事はやらないでおこうということで避けました。

MathJax は LaTeX 記法だけでなく MathML 記法も解釈するらしいですが、手書きで MathML を書く人がいるとは思えないので説明は省略します。

といった前段を済ませたところで、はてなブログに MathJax を埋め込む方法を解説します

MathJax は自分のサーバに設置することもできますが、MathJaxのCDNがあるのでそれをそのまま利用させていただきます

まずはてなブログを一つ作っておく必要があります。既に作ってあるはてなブログで記事を新規作成するわけですが「見たまま編集」から「HTML編集」に切り替えて、冒頭に以下のHTMLを入れます

<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/javascript">// <![CDATA[
MathJax.Hub.Config({
  tex2jax: {
    inlineMath: [['$','$'], ['(',')']],
    displayMath: [['[',']']]
  }
});
// ]]></script>

MathJax公式サイトのCDN(Contents Delivery Network)を使って読み込みます。本当はhead要素内に書けと指示されているものなのですが、それができないのでここで書きます。

はてなブログのバグのようなのですが、上記のHTMLを空白の「HTML編集」画面にコピペするとブラウザがフリーズするようです。もしフリーズが発生するようであれば、ダミーで何か文字を書いておいてコピペするとうまくいくと思います。

複数の記事を作る場合も、都度同じscript要素のHTML断片を冒頭に入れましょう。その記事がこのHTML断片を含んだ他の記事と一緒に表示されるかは分かりません。一意URL(Permalink)から特定記事だけ表示されるかもしれません。また、重複してこれが書かれていても無駄なリクエストは発生しないはずです (HTTP的に言えば、重複してsrc要素へGETをしても重複リクエストへはCDNが304 Not Modifiedを返すか、ブラウザが賢ければJavaScriptファイルをキャッシュするでしょう)。ただ MathJax.Hub.Config() の設定値はブログ全体で統一しておいたほうが良いでしょう。

設定値は色々ありますので、興味があればMathJax公式サイトを参照ください。設定項目のページも参照。

上記の設定は

  • インライン数式の始まりと終わりをASCIIドル記号 “$”、または “(” と “)” の組で宣言
  • ブロック(ディスプレイ)数式の始まりと終わりを “[” と “]” の組で宣言

という内容です。JavaScript のシングルクォート中の “” 記号 (0x5C、円マークかバックスラッシュ記号) の扱いのため、それ自体の表現は と二重で書く必要があります。

サンプルは「OGATA Tetsuji の数学ブログ」 ogata.hatenablog.com で見られますので(2012年11月現在)、HTMLソースを表示させて雰囲気を感じてみてください。

改めて(というかほぼ初めて)触ったはてなブログもそこそこの使い勝手でしたが、MathJaxいいですよー。これほどまでにきれいな数式記号が再現されるとは…。なんか自分、数学好きというか記号好きなのかもしれない。最近は当時勉強した数学を思い出したりしているので、MathJax/LaTeXの体験も兼ねてぼちぼち更新していこうと思います。

「モダンmod_perl入門」のこれまでとこれから #yapcasia

こんにちは、先日YAPCトークデビューした おがた (@xtetsuji) です。

YAPC::Asia Tokyo 2012 に行ってきた感想については以前のエントリでたっぷり書いたので、ここでは、YAPCで初トークした「モダンmod_perl入門」の詳細や、これにいたる経緯、そしてこれからの計画について書いてみようと思います。

トークのフォロー

まずはトークを聴講しにきてくださった方々、ありがとうございます

話したい事がいっぱいあって、20分の枠に収めるのにトーク直前まで四苦八苦していたのですが、時間超過などのカッコ悪いことにならず、何とかうまく話せたかなと自分では思っています。

トーク内容の一部フォロー

SlideShareにアップロードする段階でトークのスライドを見返していて、ちょっと説明不足だったかなというところがあったので、ここで補足させていただきます。

mod_rewriteのPerlTransHandlerでのリファクタリングの話で、「Directory Contextに書かれたmod_rewriteの場合、別途ケアが必要になる場合がある」といった内容に触れました。Directory Context の例として <Location> と .htaccess をスライドで例示していますが、まさに Directory Context の代表と言える <Directory> に触れていないのは、単に忘れていただけです。

実際、mod_rewriteは「URLを書き換える」処理を行っているわけですが、PerlTransHandlerに対応するApacheフェーズでは、まだURLから実ディレクトリへのマッピング処理が完了していません。Apache設定のルートや<VirtualHost>直下に書かれたmod_rewriteの場合は、まだURLから実ディレクトリへのマッピング処理が行われない段階、つまりPerlTransHandlerと同じフェーズで処理されるので問題がないのですが、Directory Contextでは既にURLから実ディレクトリの解決が済んでいるわけです。mod_rewriteは、この部分をうまく解決するために内部的に多少面倒な事を行っています。このようなこともあり、mod_rewrite では $r (Apacheモジュールでいえば request_rec 構造体 r) が持っている uri 情報を実際は書き換えず、書き換えて穏当に実ディレクトリを解決したように見せかける処理を PerlFixupHandler と同等の場所(リクエスト処理フェーズの直前)で行っています。通常は問題にならないと思いますが、レスポンスフェーズで動作するプログラム(CGI, PHP, mod_perl Registryスクリプト等)がURLをつぶさに見る場合に状況によっては mod_rewrite → mod_perl PerlTransHandler の単純な書き換えで同等の動作が保証されない場合もあります。この辺りは mod_rewrite が見事とも言える複雑な処理をしている部分が大きいです。皮肉ですが、mod_rewrite 設定がすぐに魔窟になる所以でもあるでしょう。

PHPとの連携については、PHP以外の言語でもレスポンスフェーズで入出力を処理するものについては同様の事ができるはずですが、自信がなかったので私が経験したPHPとの連携に限ったお話とさせていただきました。PHPがレスポンスフェーズ以外でほとんど仕事をしないポリシーであることはPHPのコア開発者が述べていることでもあります(これはApache以外へのPHPの移植性を考えてのことでしょう)。その明瞭さゆえ、レスポンスフェーズでPHPが動作する場合、他のフェーズでmod_perlを投入することで干渉が起こらないと言っていいのです。

最近はdisられ役になったり、PHPプログラマ自身がそれを自嘲気味にネタにする時代ですが、私はPHPが得意な人・Perlが得意な人で協力しながら開発をする姿も良いと思っていますし、mod_perlがPHPとPerlを繋ぐ糊(glue)となって欲しいという思いもあります。誤解は無いとは思っていますが、少なくとも私のトークではPHPをdisったりする意図はありません。だからといって、多種多彩なプログラム言語で書かれたプログラムが乱立している状況だと保守性もへったくれもないので、必要性に応じて仕事では社内のプログラム言語はある程度統一しておいたほうがいいかなとは思います。

ただ…、過去にPHPで絡ませて頂いた仕事の半分くらいは痛い目に会っているんですよね。これは私が、スキルの低いPHP開発者とたまたま一緒に仕事をせざるを得なかっただけの話かもしれませんが…。しかしそのおかげで、PHPの勉強をサボろうという猛烈な熱意がmod_perl力をさらに向上させたとも言えるでしょう。もちろん、気持よく一緒に仕事をさせていただいたPHPプログラマの方も多くいらっしゃって、勉強させていただいたことも多くありました。その節は本当に助かったと同時に、良質なコードからPHPの勉強も自然とさせていただきました。

認証・許可処理は名前通り PerlAuthenHnadler・PerlAuthzHandler に書くべきでしたが、例示したコンセプト(スケルトン)ハンドラは PerlAccessHandler での設定でした。これには言い訳があって、Authen/Authzは癖があってApacheコアのRequireディレクティブなどと組み合わせないといけないのが面倒だっただけです。本来、PerlAccessHandlerはアクセス制御処理(IPアドレスでのアクセス制限等)を入れるフェーズですが、認証・許可処理を手軽にやるときはPerlAccessHandlerに書いてしまえというのは単なる私の怠け癖です。実際、アクセス制御処理を行う場合、単純なIPアドレス処理のようにヘッダを見ないのであれば、遥か前 PerlHeaderParserHandler のさらに以前である PerlPostReadRequestHandler でやってしまったほうが効率的なのです(多くの処理フェーズを省けるわけですから)。

Perlのスレッド(ithreads)をApacheのworker MPMと合わせて使うことでprefork MPMでは実現できない変数共有といったお話もしました。ただ、スライドでworker MPMはスレッドとプロセスのハイブリッドであると言っているのに変数共有できるのはなぜ?という疑問が湧いた方もいらっしゃったかと思います。これは完全に設定の説明を失念していて、worker MPMで生成されるプロセスを1つにするという設定が必要です(1プロセス・マルチスレッドの状態にする)。詳しい説明はここでは割愛しますが、ざっくりと StartServers、ServerLimit、PerlInterpStart、PerlInterpMax の各ディレクティブの設定値を 1 にしておけば良いはずです。スレッド設定については、MinSpareThreads、MaxSpareThreads、ThreadsPerChild の各種設定値を用途と環境によって適宜調整下さい。

ただ、トークでも何度も繰り返していましたが、現状Perlのスレッド(ithreads)は決して使用をすすめられるものではありません。諸事情あって私はこれを商用環境に投入することになりましたが、原則的に勧められることでは無いと思います。ただ、prefork MPM 以外、worker MPMがあまり陽の目を見ないことと、mod_perlの一つの可能性を知っていただきたかったので、今回トークのネタにしました。

他のmod_{lang}との比較をしようとは以前から考えていたのですが、検索すればあらゆるプログラム言語のmod_{lang}が出てくる状態はカオスでした。もちろん「コンセプトで実装してみました」で後は放置されて実用段階に無いものがほとんどなのですが、mod_ruby や mod_python についてはその名前から今も現役(現在のmod_perlと同等の実用性を持ち、保守がなされている)と誤解している方がまだいるのではないかと思ったので、念押しで解説させていただきました。

mod_ruby は、まだRails以前のRubyのエコシステムがそれほど整備されていなかった当時、Perlに追いつけと主にRegistryスクリプトに対応するものができるようにと mod_perl (mod_perl1) と対応したものを作ったものと私は理解しています。mod_ruby は Apache2 には少なくとも正式には対応されていないはずです。Rails以後は、Lighttpd + FastCGI が定石になって、その後 Rack 方面へと進んだと私は理解しています。

Apacheを拡張するものとしての mod_perl (mod_perl2) に対応するものは、現時点では mod_mruby でしょう。組み込み用途の mruby が今年2012年4月に登場してすぐに登場した mod_mruby ですが、現在も作者の @matsumotory さん (まつもとりょうすけさん) によって精力的に開発が進められています。「ApacheをC以外の他の言語で拡張する」という用途がmod_mrubyで見直され、それがmod_perlの「再発見」にもつながってほしいという期待を持っています。

ベンチマーク関係も不得意な私なのですが、今回は @matsumotory さんの結果を許可を得たうえでスライドに転載してご紹介させていただきました。mod_perlでの追加ベンチマークの補足情報もいただけて、本当に助かりました。会場にはRubyistの方もいらっしゃると思ったので「RubyでApacheやるならmod_mrubyもいいよ」とも伝えたかったのです。相当な機能と歴史を誇るmod_perlですが、現在進行形で開発されているmod_mrubyもmod_perlに追いつけ追い越せで開発されています。mod_perlの開発は今も現在進行形で行われていますが、mod_mrubyのような存在がmod_perl開発への良い刺激になれば良いなと願ってやみません。

20分で膨大なmod_perlのノウハウを語るには足りないと思ったので、アフターストーリーとして今後の展望を述べました。Twitter アカウント @mod_perl_info では時々mod_perlで困っている人をウォッチしてその解決策をご紹介したりしていますが、ウェブサイト modperl.info のほうは私がなかなか取り掛かれずに未完成となっています。作り途中でもいいので、今年中に何とか成果を小出しにでもしていきたいと考えています。ご声援、よろしくお願いします。

mod_perl関連の情報は他のmod_{lang}に比べて豊富ではあるのですが、日本語使用者にとって、やはり英語の情報が大多数なのがネックで、その辺りを解消していきたいと考えています。mod_perl関連のCPANモジュールの翻訳についてはmodperl.infoに閉じ込めずに、perldoc.jpへ積極的にコントリビュートしていきたいと考えてはいますが、まだ計画段階です。私の英語力の足りなさも目下の課題です。

あとどうでもいいことですが、古いネタ「キモーイガールズ」を入れたのは、いつか私が大舞台でこのネタをやってみたかっただけです。私がmod_perlをdisるはずもなく、いわば自虐ネタですね。トークの数時間前にホールで座っていた見知らぬ隣の人が、私が隣にいるとも知らず、私のトークについて「mod_perlの追いやられ感は半端ない」「mod_perlは風前の灯火」と評論してくださった事への皮肉です。もちろん現在それは実際の事であって、怒ったりはしてませんよ。入れる予定は無かったのですが、その事もあって勢いで数時間前にはてなセリフで作って入れちゃいました。はてなラボのサービス、便利!

会場での質問へのフォロー

トーク後の質問タイムで幾つか質問があったのですが、満足に答えられなかったかなという思いがあるので、ここで質問に対する少し詳細なフォローをさせていただきます

まず消費メモリやコストの問題

消費メモリに関しては、初期にかかる量は十分把握できるわけですが、その後mod_perl/Apacheが「太っていく」問題に関して、会場では Apache::SizeLimit / Apache2::SizeLimit を使った解決策を紹介しました。それは、規定以上のメモリを使用した子プロセスが MaxRequestPerlChild の指定に関わらず自発的に終了するという、言わば消極的な解決策ですが、「太っていく」事への対策はこのような対症療法しかないと思います(問題のプロセスを取り出して何らかの操作で「痩せさせる」事ができるでしょうか)。なぜ太っていくのかといえば、mod_perlの処理の中で大きなファイルなどメモリを大きく使用する処理の後で思惑通りの量のメモリを開放してくれなかったり、使っているPerlのバージョン自身に未知および既知のメモリリークのバグがあったり等、様々です。このような問題はスクリプトのコンパイル結果を都度捨てているPHP(mod_php)自身にも見られる問題であり、Apache固有の子プロセス終了関数apache_child_terminateも用意されているくらいです。

また上述のような対症療法以外に、初期にかかる消費メモリを抑える事もご紹介しました。Apacheの親プロセスの起動時に PerlModule ディレクティブで Encode や DBI 等のよく使用するモジュールをプリロードしておくことで、Apacheの親プロセスを子としてforkするときにCopy on Write(CoW)効果が働くことを利用して初期のメモリコストを抑えることができます。この周辺については、Perlの永続プロセスをマルチプロセスで生成するものであれば同様に考えられる問題と解決のようで、FastCGI等でも似たような感じのようです(この辺りは、例えば書籍「Mobageを支える技術」でも軽く触れられていました)。

初期メモリを抑えるためにCoWを利用することのトレードオフは、サーバの初期起動時間が長くなる事でしょうか。あと、あまり素性も分からないモジュールを親でロードしないほうが安定性の面で良いかなとは思います。

また、mod_perlのテスト環境についても質問をいただきました。

実はテスト駆動開発は私の完全に不慣れな分野でして、回答では「mod_perl自身には触れていないのに、なぜかmod_perlのテストについては『モダンPerl入門』にしこたま書いてある」なんて答えて少し笑いをいただきましたが、私の知識はそれくらいです。

テスト駆動開発全盛の昨今、この部分については皆さんも興味があるだろうと思ってスライドを用意はしたのですが、時間の都合で割愛させていただきました。サービススライドに押しやっているので、もし良かったらそちらをご覧いただけると幸いです。

会場では Apache2::FakeRequest を使った $r のフェイクオブジェクトを使うという方法をお答えしましたが、(私の不慣れのせいかもしれませんがこれは)手間はかかります。後は Apache::Test による方法などがありますが、あまり私が語れる部分は少ないのが恐縮です。この部分については今後も勉強していきたいと思います。

書籍「Practical mod_perl」にも、mod_perl1時代の情報でかつ洋書ですが、各種テストやデバッガを交えた開発手法が乗っています。こちらも興味深いので、もっと知りたい方におすすめです。「Practical mod_perl」はCreative Commonsライセンスで公開されているので、書籍が無くてもサイトから読むことが可能です。

ここまでの経緯

個人的なお話で恐縮ですが、このトークに至るまでの私の紆余曲折です。

2003年にプログラムも分からない自分を入れてくれた現在の会社。当時は学生時代に得たサーバ管理の知識で食いつなごうと思ったのですが、見事に素人知識を見透かされてかサーバは任せてもらえず、まずはテキスト処理・ログ処理からPerlを勉強することになりました。

2004年からPerlでのウェブ開発を任されるようになりましたが、当時は右も左も分からず、大変でした。mod_perlの事も言葉だけ聞くだけで、当時は「Perl CGIを速くするものだけどクセがあるから要注意」程度の理解をしていました。柱コンテンツはmod_perl1で動作していましたが、今振り返って見ると、当時はPerl CGIの高速化 (Apache::Registry) を目的とした使い方しかしていませんでした。

2005年から一人プログラマとして企画やデザイナの方々と小中規模のサイトを運営していくのですが、mod_perlの正体がつかめなかったので、私はPure CGI(Apache mod_cgi)でのPerlウェブ開発をしていました。ただ、この時からパフォーマンスを気にするようになって、柱コンテンツに使われているmod_perlを横から研究するようになりました。このころから隠れて(?)mod_perlを勉強するようになり、mod_perlはPerl CGIの高速化だけでなく、Apacheの拡張すらできるものだということを徐々に理解していきました。

これ以降の数年間は仕事の幅も広がり、後輩や一緒に働く外部の方も増え、自分がメインで担当する開発案件以外にも、PHPコンテンツの納品保守や、遊軍として他のPerlウェブ開発プロジェクトのサポートなども担当しました。その中で、それまで勉強してきたmod_perlの知識が色々なところで役に立ったのが印象的です。

数年前から、一緒に働く開発者の人数やプロジェクトの数が整理され、社内の柱コンテンツに戻ってきました。それまで得たmod_perlの見識を投入して、パフォーマンスチューニングや、mod_perlハンドラによる諸々の拡張や新規開発、mod_perl1からmod_perl2へのマイグレーション等、Registryスクリプト利用による高速化のみを目的に当初導入されたmod_perlの可能性を広げていっています。

せっかくこれだけ培ったmod_perlのノウハウを社内に閉じ込めておくのも良くないと考え、2011年からはHokkaido.pmでのトークをメインに、社外にもmod_perl情報をアウトプットしはじめました。今年2012年のYAPC::Asia Tokyo 2012での本トークは、それの集大成としたものです。

これからの計画

私はmod_perlも古くて新しい現役技術と考えてはいるのですが、残念ながら今の世の中的にニーズは少ないのが現状でしょう。私としても会社としても新しい技術を取り入れていく事が将来的なメリットであることは確かで、今後は Plack/PSGI ベースの WAF を積極的に勉強して取り入れていこうと考えています。今のところ、なんとなくMojolicious かなという気分です。少しずつ勉強中。

それでもせっかく得た mod_perl の知識をこのまま自分一人で抱えて枯らしてしまうのはもったいないと思い、今後はその知識を体系化してまとめて外に出していく作業をしていこうとしています。それがトークでも触れたアフターストーリーであり、Twitterアカウントやウェブサイトの開設の野望でもあります。

今回のYAPCのLTソンでもミートアップがありましたが、地域pmが盛んになってきたことは嬉しい限りです。もし地域pm等のPerlの集まりで「mod_perlについて聞きたい」という要望があれば、声をかけてくだされば時間やお金をやりくりしてぜひ訪問したいです(経費をいただいて呼ばれる身分ではありませんので、費用は自分でなんとかします)。

繰り返しになりますが、今回のYAPCでの「モダンmod_perl入門」は、私の数年間のmod_perl開発の集大成的な位置付けでトークしました。今後はmod_perl以外のジャンルにも視野を広げて、求められればmod_perlの事を語れる準備は怠らないものの、今後自発的に発表するものは、多くの皆さんの興味を引く別の話題ができればなと考えています。

今後とも、mod_perl を含めた Perl の世界で、皆さんのお役に立てるアウトプットをしていきたいと考えていますので、どうかよろしくお願いします。ここまでの長文、読んでいただきありがとうございました。