« 2013年6月 | メイン

2013年7月31日

Blogで簡単にシンタックスハイライトを実現する3行のおまじない

body終了タグの直前に以下を書いておけばよろしい。Markdownで書いたコードブロックとかが簡単にシンタックスハイライト対応になる。

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="//google-code-prettify.googlecode.com/svn/loader/run_prettify.js"></script>
<script>$(function(){$('pre > code').addClass('prettyprint');prettyPrint();});</script>

外部リソースに直接向けてあります。パーソナルユースなら問題ない感じがします。jQueryもGoogleにしてあるのは、https対応しているので、//始まりのURLが記述できるからです。

jQueryのバージョンは適宜調整して下さい。jQuery2系はlatest versionへのリンク的なやつは公開しないポリシーみたいですね。

html出力時にサーバーやジェネレーター側で変換するとコストが大きいし、HTMLは汚くなるしであんまり好きじゃないですね。

02:41

2013年7月29日

Puncheurのご紹介改めオレオレWAFを作ってしまった件

職質テックトークでもちょっと話したのですが、 PuncheurというWAFを作ってCPANにもあげてしまいました。

読み方はパンチャーですが、パンツァーでもパンチラでもなんでもいいです。

気軽に開発を始められてカスタマイズ可能なWAFとなっております。 最低限のユーティリティーを提供しつつ、DispatcherとViewは差し替え可能になってるという、最近よくあるあれです。 実際かなりAmon2からコピペです。

ちょっとしたPSGIアプリケーションをCPANで配布する的な用途に向いているのが大きな特徴となっています。

主な特徴としては以下。

  • Perl5.8切り捨て
  • すべてMyApp->new(%opt)から始まる
    • MyApp->new(%opt)->to_psgi; って書ける
    • my $c = MyApp->new(%opt); ってCLIで書ける
    • Lite的な奴も.psgiにべろっと書かずに、ちゃんとpackage書いて、plackup -MMyApp -e 'MyApp->new->to_psgi'すればいい
  • configファイル決め打ちじゃなくて、指定もできるように
  • myapp.pl みたいなサーバー起動スクリプトが書きやすい
  • プロジェクトディレクトリ前提ではない
  • 比較的一枚岩。あんまFlavor有りきにはしない
  • Puncheur::Requestが高速(なはず)

Perl5.8切り捨て

//とかstateとかsayとかが使えると捗りますね。

すべてMyApp->new(%opt)から始まる

MyApp->new(%opt)->to_psgi とか書くのが分かりやすいんじゃないかなーと思います。コンストラクタにオプションとか渡せると分かりやすそう。

my $c = MyApp->new(%opt) とかやればそのままコンテキストオブジェクトとしてCLIでも使える感じ。Plugin::Modelを使えば、 $c->model(...)みたいなやつもできます。

1ファイルアプリみたいなのもPuncheur::Liteを使えば書けますが、psgiにベロっと書くんじゃなくて、ちゃんとpackage書いてplackup -MMyApp -e 'MyApp->new->to_psgi'すればいいんじゃないか的な思想になっております。

configファイルも決め打ちじゃなくて指定できるように

従来の多くのWAFだとconfigファイルが規約で決まっていたりするわけですが、同じリポジトリでメインアプリと管理画面を管理したいみたいなときに困ることがあります。

Puncheurでは、MyApp->new(config => $conf:filename|HashRef)などとすることにより設定を差し替えることが可能です。

Amon2と同様にload_configをオーバーライドすることで設定読み込みを変更することも可能です。

myapp.plみたいなサーバー起動スクリプトが書きやすい

割と目玉機能のつもりですが、以下の様なスクリプトを書けば簡単にサーバーとして使うことができます。plackupに指定するオプションや、MyApp->newに渡すオプションを 混ぜこぜで使うことができます。(ちょっとこの辺りは変更の可能性があります)

% cat my-app.pl
#!/usr/bin/env perl
use strict;
use warnings;
use Puncheur::Runner;
# MyAppはPuncherアプリ
Puncheur::Runner->new('MyApp', {
    # default plack settings
    server => 'Starlet',
    port   => 1988,
})->run;

% ./myapp.pl -p 9955 --config my_config.pl

プロジェクトディレクトリ前提ではない

単なるプロジェクトディレクトリ形式だけではなく、CPANで配布する用のアプリを作りやすくなっています。例えばテンプレートディレクトリの デフォルト配置配置が share/tmpl になっているところもそんな狙いが伺えます。

比較的一枚岩。あんまFlavor有りきにはしない

Puncheur.pmを読めば比較的処理が分かるんじゃないかと思います。Flavorとか使わないでも気軽に書き始められる感じになっております。 現状Flavor機構はないのですが、そのうち追加はしたいなーとは思っています。

Puncheur::Requestが高速(なはず)

req->urireq->baseをキャッシュしたり、クエリのパースにURL::Encodeを利用したりと高速な感じになっております。 この辺はNephia::Requestで得られた知見を盛り込んでおります。 クエリのパースに関しては、Plack::MiddlewareのどこかでPlack::Requestが使われたりするとあんま意味が無かったりします。 Plack::Requestが自動的にPlack::Request::XSとかに差し替わるようになってると嬉しいのかなーとか思ったりもしましたが、 クエリのパースコストがそこまで支配的になることは少ないのかも知れません。


テストがない。ドキュメントがない。メモリリーク周りケアできてるかよくわかってないと三重苦ですが、その辺を解決しつつ、 その後はflavorとかPluginとか多少充実させるかなーとか思っております。

Puncheurを使った、RijiというBlogアプリケーションもCPANに上げてありますがその説明はまたそのうち。

Puncheurの名前の由来としては、元々PHPっぽい名前ってことで、PhiloPurple(紫が好き、的な造語)という名前にしていたのですが 覚えづらいし、思ったよりまともな出来になってきたので、ちゃんとした名前にしたいなーと思ったので変更した次第。

“Roadie”という名前も考えたのですが、RubyにHTMLメールを配信するための同名のgemがあり、メンテもしっかりされている 感じだったので諦めた感じでした。Puncheurも自転車用語ですがそのへんの話も職質テックトークで 軽く触れていますので、お聞きいただければと思います。

22:14

2013年7月15日

Kyoto.pmに行ってきました

トークもさせてもらって来ました。資料は以下

http://songmu.github.io/slides/kyoto0713/start.html

折角nekokakさんがゲストなので、Tengに絡めた話をしたらいろいろ質問とかもしてもらえてよかった。 DBIx::TransactionManager::EndHookの話をしたら「これ本家に取り込みますよ」的なことも言ってもらえたのも大分収穫だった。 やっぱ、直接コミュニケーションしたほうが色々速いってのはありますね。

Kyoto.pmはだいぶ良かった。Perlをいろいろな用途に使っている人がいて、そのへんの話も聞けたのが興味深かった。 モジュールとか使わせてもらってるけど普段あまり接点ないはてなの人とかと話せたのも大きかった。

Onishiさんと色々話せたのが有意義でした。motemenさんとも話したんだけど「Class::Accessor::Lite::Lazy使ってます!」 って言えなかったのは残念でした。

また地方pm、お邪魔したい。

azumakuniyukiさんが話してた、Hainekoがだいぶ面白くて、 HTTPでメールが送れるってのは大分胸熱だなーと思いました。

01:29

2013年7月 9日

Teng::Plugin::SearchJoinedとSQL::Maker::JoinSelectとKyoto.pmの話

N+1問題という近年まことしやかに語られるようになった言葉があります。当たり前の事象に大げさに名前をつけるのどうなのかと思ったりもするわけですが、名前が付いていると案外説明に便利だったりして「名前重要」だなーとか思ったり思わなかったりするわけです。

最近はTengを便利に使わせてもらっているわけですが、Tengはシンプルな分、何も考えないで使うとN+1問題が多発してしまいます。そう言う思想なわけです。

クエリ数を抑えるためにJOINしたクエリを投げたくなるわけですが、そうなると自分で投げるしか無くて、それはまだいいとしても、普段Rowオブジェクトを使い慣れているゆるふわエンジニアとしては、JOINして複雑なデータを取った挙句、途端に生々しいハッシュを使わないといけないのはだいぶつらいものがあります。

ということで、

  • JOINしたクエリを分かりやすく記述できる
  • Rowオブジェクトをちゃんと取りたい

という目的をかなえるために、Teng::Plugin::SearchJoined というものをリリースしました。使い方はSYNOPSISとほぼ同じですが、以下の様な感じです。

package MyDB;
use parent qw/Teng/;
__PACKAGE__->load_plugin('SearchJoined');

package main;
my $teng = MyDB->new(...);
my $itr = $teng->search_joined(user_item => [
    user => {'user_item.user_id' => 'user.id'},
    item => {'user_item.item_id' => 'item.id'},
], {
    'user.id' => 2,
}, {
    order_by => 'user_item.item_id',
});

# $itr->suppress_object_creation(1); も可能
while (my ($user_item, $user, $item) = $itr->next) {
    ...
}

割と直感的でいいんじゃないかとおもいます。デフォルトINNER JOINですが各種JOINにも対応可能です。その辺りは、ドキュメントをご確認ください。

このプラグインはSQL::Maker::Plugin::JoinSelectというモジュールに依存しており、これもまた、SQL::MakerでJOINしたクエリを分かりやすく記述するために書いた拙作のモジュールです。

このモジュールを作るにあたっては、SQL::Makerに幾つか細かいp-rを送り付け、挙句一時的にTengをぶっ壊したりして大変ひどい感じだったのでした。いつもながらしょうもないp-rに素早く対応してくれるtokuhiromには感謝です。

今週末のKyoto.pmでトークさせていただくのですが、多分このへんの話をするんじゃないかと思います。

宿とか何も決めていないので誰か宿を提供してくださったりすると大変嬉しいです。ただし当方いびきがうるさいです。

あわせて読みたい。 http://blog.64p.org/entry/2013/07/09/114744

00:57