Objective-Cの正規表現でメタ文字をエスケープするには\\を使う。

NSRegularExpressionSearchで正規表現検索をする場合、(とか+とかのメタ文字自体を引っかけるためには、\\を前に付けてエスケープする。[option]+[\]で出るバックスラッシュ2回ね。

[@"ab(c)" rangeOfString:@"("  options:NSRegularExpressionSearch]; //not match
[@"ab(c)" rangeOfString:@"\("  options:NSRegularExpressionSearch]; //not match
[@"ab(c)" rangeOfString:@"\\("  options:NSRegularExpressionSearch]; //match
[@"ab(c)" rangeOfString:@"[(]"  options:NSRegularExpressionSearch]; //match

4番目もマッチするけど、「Objective-C正規表現でカッコ()にマッチさせるには、文字セット[]の中に書く」のはよろしくないです。

近代プログラマの夕とカレー

昔、月刊アスキーの中に、近代プログラマの夕(ゆうべ)という連載があった。編集長の遠藤諭が、ホーテンス・S・エンドウ名義で書いていたコラムだ。内容は、「本物のプログラマPascalを使わない」ネタや、「この醤油はユーザーインタフェースが悪いね」とか「支払いは3k円」、「ロクゴーゴンザブロ」みたいな独特の発言ネタ、カレーやドクターペッパープログラマの関係など、プログラマの生態的なものが多かった。


僕は中学まで北海道の田舎に住んでいて、地元で売ってるコンピュータ雑誌は月アスだけで、毎月買ってはいたものの、分厚い本の内容はほとんどわからなかった。わからないながらも、カオス理論ってすごいなーとか、ベンチマークのグラフかっこいいなーとか、98じゃなくてDOS-V欲しいなーとか思って読んでた。そんな僕にとって、このコラムは、月アスの中でも理解することができる貴重な記事だった。これを読んでいるうちにプログラマに憧れ、いまはSIerになり、人生を激しく後悔している。それはともかく、このコラムのファンになった僕は、連載を追いかける他、アスキーに単行本を注文して読みふけっていた。


旭川高専5年生になり、大学編入の受験のためはじめて上京した時、このコラムで取り上げられていたカレーを食べようと、アジャンタに行った。当時はジャワカレーの中辛くらいの辛さにしか免疫のなかった僕には、アジャンタのカレーは辛すぎた。はじめはすごい量の汗をかき、そのうちに寒くなって震えがきて、半分以上残してしまった。苦い(辛い)思い出だ。


その後、プーさんのカレーに鍛えられ、札幌でスープカレー屋を訪ね歩き、結構辛いカレーも食べられるようになった。今、そのカレーをもう一度食べたい。そう思って、お店の名前を確認しようとググったら、近代プログラマの夕のブログ版が引っかかった。
http://blogmag.ascii.jp/tokyocurrydiary/cat30/
読んでみたら、当時と変わらないテンションで、つい読みふけってしまった。さらに遠藤さんが、東京カレーニュースなるFBページを運営していることもわかった。そして件のアジャンタが、カレーランキングのトップを争っていた。
東京カレーニュース
僕も「いいね!」を押すとともに、キングオブフードであるところのプーさんのカレーに一票を投じた後、懐かしさに突き動かされてこのブログを書くに至った。


月アスはもう無くなって、ググってもバックナンバーの目次も出てこない。近代プログラマの夕の古本はまだ買えるようだ。実家には残っていたはずなので、今度帰省したら読み返してみよう。


近代プログラマの夕(ゆうべ)
ホーテンス・S. エンドウ
アスキー
売り上げランキング: 578467
近代プログラマの夕(ゆうべ)〈2〉
ホーテンス・S. エンドウ
アスキー
売り上げランキング: 882939

canvasとjavascriptで幾何学的なアニメーション


学生の頃、幾何学的なアニメーションをFlashで作ってたことがあって、それを今、html5canvasjavascriptで再現してみた。
http://jsdo.it/hsksyusk/sVOn
その2
その3
その4
ちょっとしたコードでいろんなアニメーションのパターンが出てくるのが楽しいのよね。

そもそも作り始めたときの元ネタはこちら。ジョン・ウィットニー。


今回作成にあたって参考にしたのはこちらのサイト。
HTML5 の canvas でアニメーションさせてみる - 1ka2ka.com

ユーザープロビジョニングの未来ってこうなるの?

以前 OpenID tech night #7 を見たあとに、その辺のことを少し勉強したまとめ記事を書いた。
OAuth 2.0やOpenIDの最新動向に追いつくために勉強したことまとめ。 - hsksnote
最近、この中で触れたユーザープロビジョニングの未来の姿というのが、具体的にイメージできなかったので、ちょっと考えてみた。
考える元になったのは、こちらのスライド。
Cloud Identity Summit 2011 TOI
の、P.28。

これね。この未来が現実になるとどうなるか、と言うのを考えてみた。
ただし、ちゃんと理解できていない部分があるから、見当違いのことを書くかも。


まず、利用者はこんな感じ。


その未来の企業環境はこんな感じ。

  • 未来なので、GoogleがメガSaaSとして、トークン管理サービスや、プロビジョニング機能も持ったよ。
  • 未来なので、サイボウズLiveOpenIDを導入したとするよ。
  • 未来なので、人事SaaSやプロビジョニングSaaSは、よさげなスタートアップが出てきたとするよ。


ここから、企業に新入社員が入ってから、いろんなサービスが使えるようになるまでの動きを追ってみる。

まずは入社したよ。やったね!



入社したから、人事は人事SaaSに新人の情報を登録するよ。



人事SaaSは人事情報の変更をプロビジョニングSaaSに通知するよ。
プロビジョニングSaaSは、人事SaaSの新しい情報を取ってきて、各SaaSのプロビジョニング用の情報を作るよ。
プロビジョニングSaaSには、人事情報とSaaSの権限が紐付けて定義されているよ。例えば、部署とGoogle Groupの紐付けとか。



プロビジョニングSaaSが各SaaSにユーザープロビジョニングをするよ。
Googleにユーザーを作るよ。
Google Groupに参加できるユーザーを追加するよ。
サイボウズLiveにもユーザーを作るよ。



Googleもプロビジョニング機能を持ってるから、勤務管理SaaSにユーザーを作るよ。


ここまででユーザープロビジョニングは終わり。



使うときはこんな風になるよ。
GoogleがIdP、サイボウズLiveや勤務管理SaaSはRPになるよ。
GoogleがSSO機能を持って、Googleにサインインしていれば他のSaaSもそのまま使えるよ。


こうですか?わかりません><
教えて@tkudos

Facebook内で使うタイプのアプリで認証にAmon2::Authを使う方法

前回は外部のFacebookアプリの認証をやって、それを内部でやろうとしてうまくいかなかったということを書きました。
Amon2を使って!DotCloudで!Facebook アプリを作りたい!(まだ試し中) - hsksnote
今回はそれがうまくいったので、ソースと一緒に解説します。


前提として、Facebook内で動かすアプリは、Facebookのキャンバスページ内のiframeに表示されます。なので、ローカルでテストできません。これが非常に面倒くさい。
今回はDotCloudにテストアプリを作って動かしました。


Facebook側の設定は、こちらの記事をご参照。キャンバスURLを設定してやる必要があります。
Apps on Facebook.com : Facebook開発者向けドキュメントの日本語訳とTips


まずは認証につかうAmon2プラグインへの依存を書きます。
Makefile.PL

         'Plack::Session'                  => '0.14',
         'Test::WWW::Mechanize::PSGI'      => '0',
         'Time::Piece'                     => '1.20',
+               'Amon2::Plugin::Web::Auth'        => '0',
+               'Amon2::Auth::Site::Facebook'     => '0',
     },


コンフィグファイルに認証用の設定を書きます。callback_uriにキャンバスページのURLを設定するのがポイント。Facebookのアプリ設定画面にURLが出てます。
dotcloud上で動かすので、development.plだけじゃなくdeployment.plにも同じ事を書く。
config/deployment.pl & config/development.pl

             sqlite_unicode => 1,
         }
     ],
+       Auth => {
+               Facebook => {
+                       client_id => 'xxxxxxxxxxxxxxx',
+                       client_secret => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
+                       callback_uri => 'http://apps.facebook.com/hsksyusk_sample_app/',
+                       scope => 'read_stream',
+               }
+       }
 };


プラグインを読み込みます。redirect先にも、キャンバスページのURLを指定。
lib/fbsample/Web.pm

+__PACKAGE__->load_plugin(
+       'Web::Auth',
+       {
+               module => 'Facebook',
+               on_finished => sub {
+                       my($c, $token, $user) = @_;
+                       my $name = $user->{name} || die;
+                       $c->session->set('name'  => $name );
+                       $c->session->set('site'  => 'facebook');
+                       $c->session->set('token' => $token);
+                       return $c->redirect('http://apps.facebook.com/hsksyusk_sample_app/');
+               },
+               on_error => sub {
+                       my ($c, $error ) = @_;
+                       warn ("auth_error!![$error]");
+                       return $c->redirect('/');
+               },
+       }
+);

ここでURL末尾の/を書いてなくてずっとハマってた。


今回作ってるWebアプリは、FacebookのキャンバスページからはPOSTで呼ばれます。
おなじくWeb.pmで、Web::CSRFDefenderプラグインの読み込みをコメントアウトします。
lib/fbsample/Web.pm

 # load plugins
 __PACKAGE__->load_plugins(
     'Web::FillInFormLite',
-    'Web::CSRFDefender',
+    # 'Web::CSRFDefender',
 );


HTTPレスポンスヘッダーのX-Frame-Optionsの設定を無効にします。
このオプションは、iframeで読み込まれることを許可しない設定で、クリックジャッキング攻撃を防ぐ目的で使われるのだとか。
lib/fbsample/Web.pm

         $res->header( 'X-Content-Type-Options' => 'nosniff' );

         # http://blog.mozilla.com/security/2010/09/08/x-frame-options/
-        $res->header( 'X-Frame-Options' => 'DENY' );
+        # $res->header( 'X-Frame-Options' => 'DENY' );

このへん、セキュリティ的に無防備になってしまうところは、呼び出し元をfacebookからに限るとか、対策を考えないといけないですね。


ここまでで設定が終わったので、処理を書いていきます。
と言っても、こちらの記事のコードそのままでいけます。
Amon2でFacebookAPIを使う その2 - Perl勉強メモ アルパカDiary出張版
lib/fbsample/Web/Dispatcher.pm

+use JSON qw(decode_json);

 any '/' => sub {
     my ($c) = @_;
-    $c->render('index.tt');
+       my $sign = $c->req->param('signed_request');
+       my $data;
+       my $token = $c->session->get('token');
+       my $sign = $c->req->param('signed_request');
+       if( $token ) { #loggedin
+               my $ua = LWP::UserAgent->new();
+               my $res = $ua->get("https://graph.facebook.com/me/home?access_token=${token}");
+               $res->is_success or die $res->status_line;
+               $data = decode_json($res->decoded_content);
+
+               $c->render(
+                       'index.tt',
+                       {
+                               name => $c->session->get('name'),
+                               data => $data->{data},
+                       }
+               );
+       }
+       else {
+               $c->redirect('/auth/facebook/authenticate');
+       }
+};

 post '/account/logout' => sub {
     my ($c) = @_;
     $c->session->expire();

DotCloud特有なのかわかりませんが、リクエストがPOSTで来ると、responseが全部来る前にセッションが完了しちゃうという問題がありまして。それに対応するために、$c->req->param('signed_request')を変数に入れてます。こうやって明示的にパラメータを読んでやることで、この問題を回避することができるみたい。


HTMLテンプレートはこんな感じ。
tmpl/index.tt

[% WRAPPER 'include/layout.tt' %]
<section>
[% IF data %]
        Hi! [% name %]
        <section>
                <ul>
                        [% FOR v IN data %]
                        <li>[% v.created_time %] [% v.from.name %] [% v.message %]</li>
                        [% END %]
                </ul>
        </section>
[% END %]
</section>
[% END %]


cssで幅をiframeに合わせます。
static/css/main.css

+.container {
+       width: 740px;
+}


これで全部です。git addしてgit commitしてdotcloud pushしてFacebookのキャンバスページにアクセスしたら、リダイレクトして認証したあとにキャンバスページに戻ってきて、自分のニュースフィードの中身が表示されるという寸法です。

Pre Hachioji.pmとHachioji.pm #14に参加した。

pre Hachioji.pm #14 : ATND
Hachioji.pm #14 : ATND

Pre Hachioji.pm

Preのほうは、ハッカソン的なこと!ということだったけど、フタを開けるともくもく会的な感じになりました。


みなさんの発表に理解している範囲で感想を書く。

  • @hondallicaさん:が途中で顔出して会場代とパイの実を差し入れしてくれた。ありがとうございます!パイの実おいしかったです!
  • @perl_o_palさん:X Window+SWIG
    • SWIGを知らなかったので感心してるそばからSWIGがDISられてた。
  • @uzullaさん:ファイルアップローダー。仕事で使うので権限管理もしっかり。
  • @yellow844さん:Node.jsの百人一首アプリ。Web Socketで対戦。縦書きがかっこいいと評判。
  • @ichigotakeさん:Google Docsと連携するウェブアプリ。
    • Google Docsは色々と使い道があって楽しそう。
  • @kkotaro0111さん:iPhoneアプリで脱出ゲームを作るために、スライドの実装。1->2->3->4->1とループするスライドを、pushとpopで作った。
    • そういうiPhoneならではのUIを使うっていうのは楽しそう。
  • @maka2_donzokoさん:Web版パルモン
    • コマンド入力形式
      • そういえば、あとのHachioji.pmで、@uzullaさんとコマンド入力式のアドベンチャーゲームについて話してて楽しそうでした。
  • @charsbarさん:CPAN Testers?の表示をモダンに。
  • @mgikenさん:のところがスッポリ記憶から抜け落ちてる。すみません。
    • 思い出した。GANGで作ったBlogのCSSを作ってた。
    • Hachioji.pmでは情弱な私のためにGANC講座をしてくれた。
  • @cj2tszkさん:Googleの日本語入力APIで、コマンドラインで変換候補を取得。
    • ふだんWAFばかり触っているので、スクリプトベースで使うとこうなるんだー、というのが面白かった。
  • @hide_o_55さん:KyTeaという日本語とかの形態素解析をするののNode.js版ラッパー
    • NPM(PerlでいうCPANみたいなもののNode.js版?)に公開したとか。ちょうかっこいい。
    • 今見たらPerlモジュールもあって、Perl自然言語処理するならこういうの使えるんだろうなー。

人とIDの対応が曖昧なので、間違ってたらごめんなさい。理解できてないところが多すぎて非常に残念な感じに。


僕は、Facebook内で動くタイプのFacebookアプリをつくろうとしてて、Amon2::Auth::Site::Facebookで認証通ったよーという、大変レベルの低い発表をしました。
詳しくはこちら。
Facebook内で使うタイプのアプリで認証にAmon2::Authを使う方法 - hsksnote


といっても、個人的には収穫は多くて。


まず、集中できる時間が持続するのはすごい良かった。普段家でやってるときに躓くと、そのうち漫画に逃げたり、諦めてよろしくないと知りつつも別の方法を採っちゃったりする。
でも今回は、そういうことはせず、プラグインのソースを読んで、動きをある程度理解して、原因を特定するところまで持っていけた。


で、解決できたのもよかったんだけど、ソースを読んで動きを理解するというのが、かなり勉強になった。
たとえばAmon2::Authだと、認証用のURLにトリガーをつけて、設定ファイルから設定を読み込んで、Site::Facebookモジュールで認証用URIを組み立てて、そこにリダイレクトして、というようなことをやってる。
Amon2::Plugin::Web::Auth - auth with SNS - metacpan.org
Amon2::Auth::Site::Facebook - Facebook integration for Amon2 - metacpan.org


使うモジュールのソースを読むのは、そのモジュールの使い方がわかるだけじゃなく、人がどういうコードを書いているのかを知ることでもあるので。

Hachioji.pm

去年の #10 以来2度目の参加。
Hachioji.pm #10 に参加したよ - hsksnote
今回は、テーマと無理やり絡めて人生相談的なLTをしてみて、いろいろとためになるフィードバックを頂いた。
その一方で、自分のレベルの低さというのも如実に見えてしまって、それはそれで貴重なことだしありがたいんだけど、バイトから始めるレベルなのかと思うとヘコむものがあります。自分でもそうなのかもなーと思いつつも、やっぱり。
Hachioji.pmというコミュニティに対しても、自分からは何も提供できてないし、もうちょっと自分何とかしなきゃなーと思いました。

Perl Beginners #1のビギナーズ・セッションで、Perlのテストについて聞いてみた

Perl Beginners #1 : ATND
Perl初心者向けのイベントに行ってきた。ビギナーズ・セッションで発表(質問)してみた。

ビギナーズセッション
Perl初心者(でなくても良いですが)に登壇していただいて質問して頂き、それに対して聴衆の方々が回答していく、という形式のセッションとなります。
時間が15分間割り当てられますので、その範囲内でご自由に質問・発表をしてください。

発表(質問)用のスライドはこちら。はてなってslideshare貼れなかったっけ?
Perlのテストがわからない
話逸れるけど、この勉強会は、発表者(質問者)のスライドはあんまりわかってない状態で書いてるし、その場で答えてもらってるわけだから、スライド自体よりそれに対する答えを含めたレポートっていうのが、他の勉強会より重要になるんじゃないかと思った。


本題に戻る。質問したことに対しての回答を以下に。メモ取ってなかったのでうろ覚えで申し訳ない感じです。

  • 回答は@ytnobodyさんから。
    • 会場に「テストやったことない人」→ほとんどの人が手を挙げる
      • おれ、大安心
  • テストの命名
    • 連番_メソッド名という形式
      • 連番は、より基本的なテストに若い番号をつける。
      • 実行順を考えて連番をつける。
    • クラスが増えたら、連番_クラス_メソッド名
  • WAFのテスト
    • Plack::Testはモックサーバーを立ててHTTPリクエストを受けたり返したりする。
    • WWW::Mechanizeは、フォームの中の値を取ってきたり、ボタンを押したりということができる。
      • Test::WWW::Mechanizeは、そんなテストができる。
      • 掲示板サービスのテストなんかもこれでできる。
    • デプロイした先でのテスト
      • たとえばVPSなら、SSHでつないで同じテストを流したりする。
  • テストについて勉強するなら

モダンPerl入門 (CodeZine BOOKS)
牧 大輔
翔泳社
売り上げランキング: 117182

  • テストは書いたほうがいいよー。


以降は、他の方の発表とか、LTとか、2次会とかで勉強になったところを書いてく。

  • WWW::Mechanizeの話
    • は、よく理解できなかった。
  • 日本語の扱いの話
    • Perlで日本語をマッチさせる場合、UTF-8SJISも一旦Decodeして内部コードにして扱う。
      • Encode::decodeを使う。
  • PerlのWAFは何がいいの?
    • Railsのライブコーディングを見せつけられる。
    • @ytnobodyさんはKossy推し。
    • 僕はAmon2推し。
  • cpanmの話
    • 中でどういう処理を行なっているのか。FTPを使ったり、Cを使ってるとか。
    • 帰りの電車で話を聞いたら、cpanmでインストールに失敗して、絶望的な気持ちになったのだそう。
      • で、コードを読み始めたとのこと。すごい。
  • Amon2でSNSを作ったとか。
    • 大学生で。すごいな。
  • ローカル環境でツールとしてPerlを使っている人が多い。
  • Hachioji.pmの話題が多く出てた。
  • まわりに同じようなことをやってる人がいないと、自分がどんなレベルかもわからない
    • 勉強会とかもレベルが高そうで参加しにくい。迷惑をかけちゃいそう……
      • だからPerl Beginnersはとても良いきっかけになった。

あと今日話題にのぼった上記のモジュールについては、Perl CPANモジュールガイドに書いてあったので、ちゃんと読もうと思った。

Perl CPANモジュールガイド
冨田尚樹
ワークスコーポレーション
売り上げランキング: 112798


最後になりましたが、ガチホモ合コンでは、2,3のグループに分かれてた話してた14人が、TENGAの名前が出た途端に一つの輪になるという現象が発生したことは書いておきます。Perl Beginners #2 が不安です。