やんごとなき事情でJavaでDH鍵交換を実装しなければならなくなったので実装してみました。
クラス/メソッドの説明と型しか書かれていないJavaのドキュメントをdisりつつ、いろいろ試行錯誤してみたらできた。
ググっても無駄に長くてめんどくさくて実用性に欠ける実装ばかり出てきたりして辛い思いをしたので公開してみます。
javaは最近はじめて書いたのでよくわかんないんだけど、Exceptionのcatchは公開用に適当にe.printStackTrace()してお茶を濁しております。こういうのどうするのがいいんすかね。
念のため書いておくと、DH鍵交換は単体だと中間者攻撃に対して脆弱なので、素直にSSLなどを使うのがおすすめでございます。
YAPC::Asia 2013 で ぼくがかんがえたさいきょうのMVC についてはなします #yapcasia
YAPC::Asiaとは
日本で最大級の規模のPerlのカンファレンスです。Perlのカンファレンスですが運用、プロトコル、テスト等開発に関わる様々なトークがあり、和気あいあいとした雰囲気でときには意識高い話もしつつ、ゆるふわにPerlとその周辺技術等への学びや発見を得る事が出来ます。詳しくは http://yapcasia.org/2013/ をどうぞ。
今回、ありがたい事に僕が応募していたトークを採択して頂きました。
ぼくがかんがえたさいきょうのMVCとは
下のリンク先をご覧下さい。
http://yapcasia.org/talk/show/f60b8522-d43e-11e2-ac80-4cc16aeab6a4
ではちょっとさみしいのでこのトークを応募した経緯を書いてみます。
僕は仕事でソーシャルげーむを作っています。ソーシャルゲームは若干特殊な部分はありますが基本的には普通のWebアプリです。(最近はクライアントをAndroid/iOS向けに提供しているものも多いですがそれも多くの場合はバックエンドはWebAPIを提供するWebアプリです)
ソーシャルゲームは場合によってはかなりの種類の機能を提供する場合があり、対応デバイスもAndroid4系/Android2系、iOS/FeaturePhone(所謂ガラケー)などに対応させ、更に複数のソーシャルプラットフォームで動作させる場合もあり、プラットフォームによってOpenSocialの同じAPIでも微妙に仕様が違う場合があったり、同じ目的のAPIをそれぞれ独自の仕様で持っている場合があり、またゲーム自体のロジックが複雑な場合もあり、規模が大きくなる傾向があります。
ある程度の規模まではぶっちゃけ設計が適当でもなんとかなります。意味のわからないコードもひたすら追えばなんとかならなくもないでしょう。最悪全部書き直す事が現実的なコストでできる場合もあります。場合によってはschemaだけ真面目に設計してコードはゴリっと愚直に書いたほうが運用を含めた総合的なコストを低くする事もできる場合も多いと思っています。
しかし、ある程度以上になってくると、適当な設計のアプリケーションでは全てのコードを把握する難易度はかなり上がります。特にRPG系と呼ばれるジャンルのソーシャルアプリは確実に困る規模だと思います。
規模が大きいとどうしても複数人で同時に開発を進める事になります。規模が大きい割に設計が適当だと、同じ役割のコードが様々な場所に書かれたり、様々な機能が沢山搭載されている「ぼくがかんがえたさいきょうのClass!!!」「ぼくがかんがえたさいきょうのmethod!!!」みたいなやつが出来たり、非常にカオスなコードが出来上がります。処理の共通化も困難になり、そのようなコードベース上で無理に行われた共通化は諸悪の根源になりがちです。プロダクションコードでこのようなコードが出来上がると非常に悲しいことになります。テストが書かれていればかなりマシですが、それでもそもそもの設計がぐちゃぐちゃだとリファクタリングにかなり苦労する印象が強いです。コードレビューも苦労します。
これを解決するための考え方の1つが僕はソフトウェアアーキテクチャだと考えています。MVCはそのうちの1つですが、これも必ずしもそのままWebアプリケーションに当てはめられる訳ではなく、特にRDBMSとの関わり方やコンテンツキャッシュとの関わり方について悩んだり、ロジックが変に分散してしまったり、逆に殆どのロジックが詰め込まれる「ぼくがかんがえたさいきょうのClass」みたいな奴が出来て苦労する場合が多いと思います。その為、MVCの考え方を拡張して、目的のアプリケーションに合わせて整理して設計する事が必要になります。
そこに関してある程度考えがまとまったので、今回この話をする事にしました。
ただ、ぼくの考えも非の打ち所の無い完璧なものであるとは思っておらず、より良い感がえ方がきっとあると思うので、この話をきっかけにみんなそれぞれの「ぼくがかんがえたさいきょうのMVC」について話し合うきっかけにでもなれば、ベースの設計の重要性について考える機会が出来たらいいな風な感じです。
id:TAKESAKO さんの「SPDY、HTTP/2.0の使い方」とかid:xtetsujiさんの「mod_perlの展望とApacheの超絶技巧」とかid:akiymさんの「Herokuで学ぶ、初めてのPerl」とか裏番組みんな面白そうなので僕も聴きに行きたいくらいですが、もし興味があれば聴きに来て頂けると喜びます!
YAPC::Asiaに参加するには
チケットの購入が必要です。2日通し券で5000円、1日券で4000円です。なお、学生は無料です。(!!)
チケットの購入はこちらからどうぞ! http://yapcasia.org/2013/tickets/
明日、8/11までなのでまだ購入していない方はお早めに!
Yomiuri構想
まだ構想段階だけどこれだいぶイケてね?って思ったので勢いで書いてみる。
Yomiuriとは
手軽に拡張出来るJekyllインスパイア系ブログフレームワーク/オーサリングツール
特徴
Github Flavord Markdownで記事が書ける
エンジニア的にアツい。
レイアウトの自由度
Kolon(Text::Xslate)の継承テンプレートで良い感じに拡張出来ます。
また、良い感じのメソッドを提供しているので
まるまるテンプレートを置き換える事もできます。
JS/CSSも自由に書けます。
機能拡張の自由度
JavaScriptとWebAPIを使って機能拡張を行う事をYomiuriはサポートします。
用意されたhook pointにJavaScriptでAPIクライアント処理を埋め込むと良い感じにWebAPIを叩いてunderscore.jsで書いたtemplateをレンダリングするイメージです。
仕様として決まるのはWebAPIのCSRF対策*1とJavaScriptのhook pointだけです。*2
この仕様を満たす事が出来ればWebAPIは自由な言語で実装する事が出来ます。
また、APIを楽に実装するための標準API仕様とサーバーサイド(Perl)/クライアントサイド(JavaScript)フレームワークも別途用意します。
大概はこれをつかうと楽にそこそこ便利なAPIをおてがるに開発出来る様になる予定です。
シンプルな動作
Jekillと同様に記事ファイル(Markdown)とテンプレートから静的なHTMLを生成するだけです。
gitで管理しやすいと思います。
静的ファイルサーバーがあれば公開可能なのでやろうと思えばGithub Pagesとかでも公開出来ます。*3
使い方イメージ
インストール
$ cpanm App::Yomiuri
新しいブログを作成
対話式で良い感じに設定作ってくれる。
$ yomiuri create MyBlog title: My Blog of darkness description: publishing my darkness creating yomiuri.toml ... OK creating MyBlog ... OK $ cd MyBlog $ git init $ git add . $ git commit -m 'initialize commit'
暗黒面を綴るブログが出来ました。
カテゴリの追加
カテゴリははてブと同様にタグっぽいやつ。
$ yomiuri category add darkness $ yomiuri category add emacs
darknessとemacsという2つのカテゴリが出来ました。
記事の作成/編集
insert or update的な感じで処理してくれるのでファイル食わせるだけです。
h1(レベル1の見出し)の前に[]でカテゴリを囲んで書くとそのカテゴリの一覧に追加してくれます。
$ cat > entry/hoge.md [darkness][emacs]My first entry. =============== Hi. I write a blog post for the first time. My hobby is to messing about with emacs. ^D $ yomiuri entry entry/hoge.md
HTMLなどの生成
コマンド一発でお手軽生成
$ yomiuri publish
creating htdocs/index.html ... OK
creating htdocs/entry/hoge.html ... OK
creating htdocs/archive/1.html ... OK
creating htdocs/config.json ... OK
creating htdocs/meta.json ... OK
生っぽい感じで拡張
$ cat > htdocs/js/darkness.js (function () { var Comment = { model: null, view: null }; Comment.Model = Backbone.Model.extend({ apiUrl: "http://api.yomiuri.yourhost.com/comment/", list : function () { return this.get("list"); } }); Comment.View = Backbone.View.extend({ el : "#yomiuri-comment", model : new Comment.Model(), events : { "click .button.add": "openAddEditModal", "click .button.res": "openAddEditModalWithRes", "click .button.submit": "submit" }, initialize: function() { Comment.model.get(this.$el.attr) this.template = _.template($("script#yomiuri-comment-template").text()); this.modalTemplate = _.template($("script#yomiuri-comment-modal-template").text()); this.render(); }, openAddEditModal: function (e) { $("#yomiuri-comment-modal").html(this.modalTemplate()); $("#yomiuri-comment-modal").modal("show"); }, openAddEditModalWithRes: function (e) { var targetCommentId = e.target.getAttribute("data-comment-id"); $("#yomiuri-comment-modal").html(this.modalTemplate({ targetCommentId: targetCommentId })); $("#yomiuri-comment-modal").modal("show"); }, submit: function() { throw "飽きた"; }, render: function() { this.$el.html(this.template({ list: this.model.list })); } }); Yomiuri.router.on("entry/:name", function () { new Comment.View(); }); }); })(); ^D
本日の一言
Jekillでよくね!!!!!!という気持ちは凄く分かります。
ぶっちゃけ最初はPerlでJekill的な奴自作してみよっかなー的なところから始まって、
JS自由に書いて機能拡張する事考えたらある程度フレームワークあると楽だよねってなって、
ああいう感じの静的HTML吐く系のブログエンジンを利用者が独自拡張するためのアプローチとして、
こういう感じの事が『手軽に』出来たら楽しいんじゃないかなと思っている。
そのためには仕様と実装をサポートするライブラリの整備が不可欠なので、
また、その肝心の部分はまだまじめに作り始めてないので実装が進んだらまた記事書きます。
まとまんねーーーーーーーーーーーーーー
本日のこだわりぽいんと
宗教間戦争が起きないようにcatで書きました
plenv.el 0.31 released!!
plenv.elのメジャーバージョンアップが行われました。
今回のバージョンアップでは--asオプションを利用してperlをインストールしたケースでうまくperlのパスを取得出来なかった問題が修正され、README.mkdnのサンプルコードにおけるflymakeと連携する部分のコードが間違っていたものが修正されました。*1
また、plenv 1.9からrbenv basedなコードになった事により、
一部のインターフェースで互換性が無くなってしまった為、既存のコードではplenv-globalなどのバージョンの補完が効かなくなっていたりplenv-listが動かなくなってしまいましたが、
このバージョンからplenv 1.9以降もサポートするようになりました。
一応まだplenv 1.6未満もサポートしていますが、これは将来的にはサポートされなくなる可能性がありますので1.9以上へのバージョンアップをオススメします。
また、ちょっと前にMELPAに登録した為、
package.elからインストールする事が可能になっています。
これを機会にplenvとemacsを使っている方はぜひお使い下さい。
余談: YAPC::Asia 2013のトークに応募しています。よかったら。 http://yapcasia.org/2013/talk/show/f60b8522-d43e-11e2-ac80-4cc16aeab6a4
*1:id:sun-basix++
コンテキストとハッシュの怪
怖い話
割とハマりがちなので。
たとえば、以下のようなコードがあったとします。
use strict; use warnings; use utf8; use Data::Dumper; sub yyy { my $key = shift; return unless $key; return "yyy_$key"; } my $hashref = { xxx => yyy(), aaa => 'bbb', ccc => 'ddd', }; print Dumper $hashref;
上のサンプルコードの出力は以下のようになります。
$VAR1 = {
'bbb' => 'ccc',
'xxx' => 'aaa',
'ddd' => undef
};
マテマテマテマテって思うかもしれませんが、perlのバグなどではなく正常な挙動です。
コンテキスト
Perlにはコンテキストと呼ばれる概念があります。
これは、値の解釈によって処理を変えるための概念です。
詳しい説明は初めてのPerl*1を読むか、こことかこことかを読むと良いかもしれません。
Perlは値をスカラーコンテキストで評価する場合とリストコンテキストで評価する場合があり、それぞれで処理内容が変わる場合があります。
例えば変数への代入の場合はスカラー型の変数への代入の場合は値をスカラーコンテキストで評価します。
例1:
use strict; use warnings; use utf8; my $calar1 = 'aaa'; ## スカラーをスカラーコンテキストで評価 my $calar2 = ('xxx', 'yyy', 'zzz'); ## リストをスカラーコンテキストで評価(リストの最後の値が得られる) print $calar1, "\n"; # 'aaa' print $calar2, "\n"; # 'zzz'
アレイ型/ハッシュ型変数への代入の場合は値をリストコンテキストで評価します。
例2:
use strict; use warnings; use utf8; use Data::Dumper; # ARRAY my @rray1 = 'aaa'; ## スカラーをリストコンテキストで評価(与えたスカラー値が1つだけ入ったリストが得られる) my @rray2 = ('xxx', 'yyy', 'zzz'); ## リストをリストコンテキストで評価 # HASH my %ash1 = 'aaa'; ## スカラーをリストコンテキストで評価(与えたスカラー値がkeyとなりvalueがundefなハッシュが得られる) my %ash2 = ('xxx', 'yyy', 'zzz'); ## リストをリストコンテキストで評価 print Dumper \@rray1; # ['aaa'] print Dumper \@rray2; # ['xxx', 'yyy', 'zzz'] print Dumper \%ash1; # { 'aaa' => undef } print Dumper \%ash2; # { 'xxx' => 'yyy', 'zzz' => undef }
また、更に変な書き方として、リストの中にリストを含む事も出来ます。
これは結合され1つのリストとして解釈されます。
('xxx', 'yyy', ('aaa', 'bbb')); # => ('xxx', 'yyy', 'aaa', 'bbb')
ハッシュ内では値はリストコンテキストで評価します。
なので、一番上の何も返さない関数の場合、空のリストとして解釈されてキーがズレてしまうのです。
{ xxx => (), aaa => 'bbb', ccc => 'ddd', }; ## { xxx => 'aaa', bbb => 'ccc', ddd => undef }
この場合、ほぼプログラマの思い通りの挙動にはならないでしょう。怖いですね。
こわいのこわいのとんでけー
上のコード類を実行してみた人は以下のような警告が出るのに気づいたかもしれません。
Odd number of elements in hash assignment
これはハッシュとして与えたリストが奇数だった場合に警告してくれています。
上のような間違ったコードを書いてしまっている場合がある事を危惧して(かどうかは知りませんが)教えてくれているのです。
なので警告は/dev/nullには決して捨てたりせずに*2、不可解な挙動が起こった場合は警告も含め怪しいメッセージが出ていないか確認するとよいでしょう。
perl触ってるんだから一度くらいソースフィルタを触ってみたいなと思ったのでVS.pmを書いた
VS.pmとはワンライナーでおてがるにベンチマークを取るためのPerlモジュールである。
ソースフィルタを実験したくなっただけなので実用性はほぼない。
こんな感じで使える。
perl -MText::Xslate::Util -MVS=1000000 -MURI::Escape -E 'xslate { Text::Xslate::Util::uri_escape($ARGV[0]) } vs orig { URI::Escape::uri_escape($ARGV[0]) }' 'xxxxxxxxxx<"&x7axxxx;xxxxxxxxxxxxxx'
ソースはこんなの。
use Filter::Util::Call; すると
いろいろ必要なサブルーチンをエクスポートしてくれるので、
importの中でこんな感じで回せば使えるっぽい。
おてがる!
filter_add sub { my $status; if ($status = filter_read()) { die "filter abort. status: $status. " if $status < 0; s!(^|\s*vs\s|;\s*)(\s*)(\w+)(\s*){! my $p = index($1, 'vs') > -1 ? ',' : $1; $defined_in_caller->($3) or $is_registered_block->($3) ? "$1@{[$2||'']}$3@{[$4||'']}" : "${p}spec '${3}' => sub {"; !emsgx; }; return $status; };
なお、複雑な構文の場合はDevel::Declareを使うとよいらしい。
CPANモジュールでソースフィルタを使っているモジュールはTryCatch、Smart::Commentsなどがあるらしい。
コード書いたのはずいぶん前だけどそういえばブログ最近書いてないなと思ったので書いた
#chibapm いってきたたたたた
#1も#2も行ったけど#1のレポ牡蠣忘れてたのでついでにかく。
#1
内容は他の方々が既にしっかりまとめてくださってるのでそれに頼らせていただくとして、
Perl初心者な人とある程度がっつり使ってる人の両方がいて、
Perl初心者な人はこういうのやりたい!もっとうまいやりかた教えて!みたいなかんじで、
懇親会でも他の言語と比べてみてどうだとか、突き詰めれば手続き型でちゃんとロジック分割して疎結合に書けなければ他のパラダイムでも酷いコード書きがちだよねとか、
そんな感じの事をゆるふわに語ってた記憶があります。たのしかったー
Chiba.pm#1でLTしました。 - arveltの技術メモ
Chiba.pm#1に行ってきた。 - ほっけの足あと
Chiba.pm #1 に行ってきた ( #chibapm ) - WebService::Blog->new( user => ’hide_o_55’ )
Chiba.pm #1 に参加してきました - その手の平は尻もつかめるさ
Chiba.pm #1 に行きました - ああああ
Chiba.pm #1に行ってきました - 日々の覚書
Chiba.pm #1に行ってきた - YellowStore
Chiba.pm #1 に参加してきました - その手の平は尻もつかめるさ
#chibapm #1に行ってきた。 - masasuzu 技術メモ
ぼくのすらいど
#2
もくもくたいむ
市川市民会館という場所でやったんですが、ぼくははやく行ってててきとーにもくもく出来そうなところ探してました。
そしたら市川市民会館に無料休憩所なるところがあって、そこは超静かにもくもくしながら待てて凄い良い感じで、そこで開始までずっともくもくしてました。
電源は使っていいのか分からないので使わなかったですが、たぶん言えば使わせてもらえたかもなぁ。
そんなかんじで待ってたらstudio3104さんと、masasuzさんがきて一緒にもくもくしはじめて、
時間が近づいてきてほっけみりんさんとかkaztrさんとかもきはじめてそろそろかーっておもってたら始まるぽかったので移動しました。
本編
ぼくのトークからはじまりましたが、DBI便利だよ!DBIx::Sunny使うともっと便利だよ!更にDBIx::Handlerとかの周辺モジュールと組み合わせるとだいぶいいかんじなので調べてみて!ってことをはなしました。
ぼくのemacsのsyntax highlightをそのまま使ったら全然みえなくて焦った。プロジェクタで出してるからかなと思ったけどふつーにディスプレイで見ても見づらいのでやっぱりemacsでの色の付け方見なおそうかなと思いました。
質問で出てたDBIx::SunnyとDBIx::Handlerの組み合わせですが、xaicronさんのHokkaido.pm#9のスライドと同様にRootClassでもできますが、kazeburoさんの記事によると
RootClass を使う場合は、connectionが確立するまでは DBIx::Sunny が呼ばれないので Print、RaiseError等は接続前に指定しておく必要がある。BKですね。
ということなので、DBIx::Handlerの$optsにdbi_classを指定するのが良いようです。documentにみあたりませんでしたが。。。
yoku0825さんはXtraDB Clusterの説明と実際に使ってみてどうなのかというお話をしていました。
残念ながらぼくの知識では付いていくことすらできず、とりあえずmasterを複数作ってmongodbぽいノリで使えるように出来るらしいということと、類似品にndbclusterというのがあるというのを覚えたので、これから勉強しようとおもいました!
このあとはLTなのですが、moznion氏が最初からかっ飛ばしてくれてvimの設定とかの自動切り替えツールを作っていてペアプロで便利って言ってたり(PC2台使えばいいよねというオチ付き)して会場を爆笑の渦に巻き込んで一気に会場に熱を入れたり、
vimのテンプレート機能が便利というお話があったり、XSモジュール書いてみたけどM::B::Pluggable思ったより使いやすかったというお話があったり、HyperLogLogというアルゴリズムを知れたり、某社がやってるようなbashでの開発みたいなのはユニケージ開発手法という名前が付いているという事を知れたり、Mac::Pasteboardでコピペした文字列を良い感じにIRCとかに投げてめもったりする話をがあったり、vagrantが便利というお話があったり、pt-query-digestが便利というお話があったり、Perlの学習がてらどういう感じの出力になるのかひとめで分かる感じのPerlのリファレンスサイトを作っているよというお話があったり、
これほんとにLTかってぐらい充実した内容で、どれも面白かったり便利そうだったり良さそうだったりしてすごい良い感じでした。
雰囲気も和気あいあいとしててゆるふわでよかった。
全員LTするとかなると、知らないひとでも懇親会で「ああ!あの発表してたひとか!」とかなるので便利だし、idと顔が一致するしとてもよかったです。
懇親会ではひたすらkenjiskywalkerさんとはなしてたりしてtypestarさんがpokeすごい送ってくるはなしとか、弊社と御社の勉強会どんなかんじなの情報交換とかしてた記憶があります。
勉強会おじゃまします!とか言ったのでこんど行くと思いますので、罠仕掛けたりバット振りかぶって待ち構えたりせずに暖かく迎えてくれないかなとびくびくしながら打診リプライを送ると思います。
すらいど
まとめ
たのしいのでみんなChiba.pmくるといいよ!