簡易的なuniqメソッド(文字列限定)を書いたので、underscore.jsのuniqメソッドとベンチマーク取ってみました
グリモンを書いてて、uniqメソッドを自前で作ろうと思ったのですが、少し面白い方法を見つけたので、jsPerfでベンチマークしてみました。文字列専用ですが。
自前のuniqメソッド
オブジェクトを構築する際に、キーはひとつのオブジェクトに対してユニークになるので、適当な値を突っ込んでオブジェクトを構築し、最後にキーだけ取り出す感じです。reduceを使えば、4行程度で書けます。
まとめ
文字列限定ですが、underscore.jsのuniqメソッドで、最適化オプションなしの状態より速い場合が多いようです。
ただ、Google Chromeでは、underscore.jsの最適化オプションがfalseでも、今回作ったuniqメソッドよりも速いので、実用的かどうかは微妙なところです。
Object.keysメソッドが遅いのかな?それとも、バイナリサーチが得意なのかな?よくわかりません。
追記
@hokaccha さんとのやり取り。
@taiju reduceのコストが高いのかなーと思ってforでやってみました。ブラウザによってはunderscoreより速いですね。 bit.ly/VWH6Ka
— Kazuhito Hokamura (@hokaccha) November 12, 2012
@hokaccha ありがとうございます!やっぱ、速度求めるとどうしてもforに軍配があがるんですねー。isSorted=trueのバイナリサーチより速いスコアが出てるブラウザがあるとは、分岐等の処理のコストは結構あるんですね。
— taiju (id:jdg) (@taiju) November 12, 2012
@taiju 分岐のコストというよりeachでループ毎に無名関数でスコープつくるにコストかかってるんじゃないかと思います。reduceよりforのが速いのも同じ理由な気がします。
— Kazuhito Hokamura (@hokaccha) November 12, 2012
@hokaccha 追加してみたんですけど、無名関数のコストはそんなにないっぽいです。reduce遅いのかな。 jsperf.com/string-uniq-fo…
— taiju (id:jdg) (@taiju) November 12, 2012
@taiju なるほどー。関数呼び出しのコストかなーと思ったんですけどブラウザによって違いすぎてよくわからなくなってきましたw bit.ly/ZeOH6E
— Kazuhito Hokamura (@hokaccha) November 12, 2012
@hokaccha Chromeが一番謎なスコアな気がしますけど、ほんとよくわかんないですねw
— taiju (id:jdg) (@taiju) November 12, 2012
@taiju たぶんV8の謎な高速化が働いてるんでしょうねw
— Kazuhito Hokamura (@hokaccha) November 12, 2012
悔しいですけど、for速いですね。
MovableTypeのモジュールのPODのViewerプラグイン作った
MovableTypeを触っていると、MTのモジュールのPODを見る機会が多くなります。MTタグの使い方とかも該当モジュールのPOD見れば解決することもあるので、とりあえずアイデアレベルですが、昨日作ってみたのでエントリー起こしました。
MTPodViewerという名前を付けました。
デモサイト
インストール
リポジトリにあるplugins/MTPodViewer
をサイトのplugins
にコピーします。加えて、リポジトリにあるmt-static/plugins/MTPodViewermt-static/plugins
にコピーします。
依存モジュールはextlib
に同梱したつもりですが、動かなかったらごめんなさい。cpanコマンドかcpanmコマンドでインストールしてください。依存モジュールは、plugins/MTPodViewer/Makefile.PL
に書いてあります。
プラグイン設定
システムのプラグインに進むと1箇所だけ設定があります。
ログイン必須にするかしないかの選択です。Yesならログイン必須、Noならログイン不要です。
検索方法
たとえば、MTのディレクトリで、perldocする場合、以下のような感じになると思います。
$ perldoc lib/MT/App.pm
MTPodViewerでは、以下の様なキーワードで検索することになります。
app
MT::Template::Tags::Entryを検索したい場合は、
template-tags-entry
と検索します。
MTというプレフィクスは省略して、「/」や「::」の区切り文字を「-」にして、全部小文字にしているということです。
bootstrapのtypeaheadがある程度面倒見てくれるので、これで充分な気がしてます。
感想
最初はCSSとか自分で書いてたんですけど、途中からbootstrapに変更しました。bootstrap-typeaheadのスタイル作るの面倒だったので...。というか基本的にbootstrapは何かと楽でマジ助かります。
見出しのフォントはHelvetica、本文のフォントはGoogle Web Fontsにある、OpenSansにしました。すごく読みやすいですね、このフォント。
速度的にはちょっと微妙なので、モジュール一覧をキャッシュしておくなりした方がいいと思いますが、また気が向いたら対応します。
リンクの部分とかは、Pod::Simple::XHTMLの吐き出すソースをちょっとカスタマイズしたらうまくできるのかもしれませんが、ページ内リンクと別モジュールへのリンクがうまく場合分けできなさそうなので、リンクをすべて外すって対応を取っています。
MTアプリケーションはMTをWAFと思えば、普通に使えますね。クライアントワークだったら、依存モジュールの解決もそんなに面倒じゃないですし、最近は、MTアプリケーション作る機会もあって、いろんなCPANモジュールと組み合わせて使ってます。
あと、英語のドキュメント書けない。深刻。
kanazawa.rbで「Mojoliciousと愉快なPerl」という話をしてきました
つい先程の話。kanazawa.rbで「Mojoliciousと愉快なPerl」という話をしてきました。
Perlの記事を書いたことはあるけど、Perlについての発表をするのは初めてだったので、いつも以上に緊張した感じです。というか、ようやくプログラムの話ができるようになったという感じでしょうか。
話の内容
スライドにはキーワードだけ書いて、口頭での説明とデモがメインだったので、スライドだけ読んでもちょっと物足りないかもしれません。
発表でも話しましたが、かつてはRubyがPerlから学ぶことが多かったけれど、今はPerlがRubyから学ぶことが多いです。
Rubyの勉強会に参加するのも初めてでしたが、多分、Perlの人がRubyの勉強会に参加するのは、少し先の未来を覗き見することにもなるのかなと思います。
今回はSinatra vs Mojolicious vs Expressみたいな構図でしたが、それぞれパクリ愛に溢れていて、どれも素晴らしいものだと思いました。
ですが、発表の準備をするにあたり、Mojoliciousをいろいろ調べ直してみると、やっぱりMojoliciousが好きです。ひいきなしで、自分はSinatraよりも、Expressよりも、Mojoliciousが好きだなぁと。
Mojoliciousは、標準モジュール以外、すべて自前で用意しているし、どのCPANモジュールを使えばいいかわからないという人でも、とりあえず、Mojoliciousの用意しているモジュールやツールを使えば、Perlで簡単なWebアプリケーションを書くことができるでしょう。
今回の発表では、デモも交えて説明したのですが、Perl使うならperldocをたくさん使いましょうねっていう話をしました。
Rubyのドキュメントの文化とかはよく知りませんが、Perlはドキュメントがちゃんと整っているし、ちゃんと書かないといけない印象で、しかもperldocってツールが最高に使いやすいです。
PODという発明、良いプログラマは良い物書きでもあるという教えが、この文化を生んだのかなと思います。
まとめと反省
Rubyの勉強会に参加することで、Rubyの人になる可能性もありますが、もはや、Perlのキモかわいさに慣れてしまって、なかなか難しいような気もしています。*1
去年のYAPC::Asia TOKYO2011に参加して、感想記事を書いた中で、来年のYAPC::Asiaまでに、CPAN Authorになりたいとか、次回のYAPCではLTに出たいとか書いていましたが、結局この目標は未達になってしまいました。。。*2
自分を慰めるとすれば、Perlの勉強会ではないにせよ、Perlの発表をすることができたのと、Perlでツールを作って公開するということはできたという点でギリギリ赤点でしょうか。もっと精進します。
margin-top派かmargin-bottom派で言えば、margin-top派です
世の中にはmargin-top派とmargin-bottom派がいるとかいないとか。
自分はmargin-top派です。
margin-left派とmargin-right派がいるならば、margin-left派です。
試しにmargin-bottom派になってみようかなと頑張ってみたんですけど、やはり慣れもあり、margin-topの方がしっくりきたのでエントリーを起こすことにしました。
margin-top派な理由
margin-top派になったのには理由はなくて、なんとなくmargin-top派になった気がするのですが、margin-bottom派に移るのが少し面倒な理由はあります。
その理由は:first-child
擬似クラスの存在です。
例1
例えば、以下の様なHTMLがあったとします。各section.content
の間には30px
の余白が欲しかったとします。
<section class="content"> <h1>title1</h1> <p>section2</p> </section> <section class="content"> <h1>title2</h1> <p>section2</p> </section> <section class="content"> <h1>title3</h1> <p>section3</p> </section>
この場合、:first-child
を利用すると、margin-top
で楽にレイアウトできます。
section.content { margin-top: 30px; } section.content:first-child { margin-top: 0; }
margin-top
で、30px
の余白を取ります。そうすると各section.content
の間には、30px
の余白が確保できます。しかし、このままだと、先頭のsection.content
には余計な30px
の余白が入ってしまいますので、:first-child
擬似クラスを利用して、先頭の余白を0
にすることで、各section.content
の間に30px
の余白を作るということが実現できます。
例2
横並びでも同じです。リストが横並びで、各リスト項目の間に20px
の余白を取りたい場合です。
<ul> <li>item1</li> <li>item2</li> <li>item3</li> </ul>
CSSはこんな感じになります。
ul { margin: 0; padding: 0; } ul li { list-style-type: none; display: inline; margin-left: 20px; } ul li:first-child { margin-left: 0; }
こんな感じです。
このケースでは、:first-child
を使わなくても、以下のようにすればOKですね。
ul { margin: 0 0 0 -20px; padding: 0; } ul li { list-style-type: none; display: inline; margin-left: 20px; }
それ、:last-childでできるよ
そうなんですけど、IE7から対応しているのと、IE9から対応しているのとでは、大きな違いがありますし、IE8とか捨てれる状況でないので、:last-child
を実務で使える状況はあまりありません。
まとめ
margin-top派、かつ、margin-left派です。その理由は:first-child
擬似クラスを利用して、余白を調整する機会が多いからです。
IE6に対応しないといけない案件の場合は、:first-child
の代わりに、.first
を付けることがありますが、要素を後ろに追加する機会の方が多い気がするので、.last
と付けた要素より、.first
と付けた要素の方が、後々、影響を受けないことが多い気がします。なんとなくですけど。
数年後、:last-child
がどんな案件でも使えるようになったら、margin-bottom派に移行するかもしれません。現状は、margin-topの方が利点があると思っているので、margin-top派です。
もし、margin-top派だと面倒な事例があれば、ツッコミいただけると嬉しいです。
S式から(X|HT)MLに変換する簡易的なコマンドラインツール作った
Lispの仏様と言われた竹内郁雄先生は、XMLを分厚いカッコのあるLispとおっしゃっているそうです。
実際に、S式で(HT|X)MLを書くと、自然でシンプルに書けるので、S式を(HT|X)MLに変換する単純なコンバータを作りました。
作ったもの
Buakko - Simple s−expression to (X|HT)ML converter.
ネーミングのBuakkoは「分厚いカッコ」をもじりました。
シンプルなコンバータです。むしろ、現時点ではいろいろ機能が足りない感じです。
S式といっても、データの表記方法の一つとして採用しているだけで、Lispとの関連性は強くはありません。演算機能もありませんし。
ツールはPerlで書かれています。
使い方
インストールするとbuakkoというコマンドラインツールがインストールされるので、それを使います。
$ buakko sample > sample.html
これで、sampleというS式で記述したHTMLファイルを、sample.htmlというHTMLに変換します。
リダイレクトしなければ、標準出力にプリントされます。
例
以下の様なS式形式のファイルを
(html (@lang "ja") (head # ヘッダ (meta (@charset "utf-8")) (title "EXAMPLE")) (body (@class "example home") # ボディ (h1 "example!") (p (a (@href "http://example.com/" @target "_blank") "example web site."))))
以下のようなHTMLファイルに変換します。
<!doctype html><html lang="ja"><head><!--ヘッダ--><meta charset="utf-8" /><title>EXAMPLE</title></head><body class="example home"><!--ボディ--><h1>example!</h1><p><a href="http://example.com/" target="_blank">example web site.</a></p></body></html>
その他、細かい仕様とかインストール方法は、下記のREADMEをご覧ください。
作った動機
hiccupをとても気に入っていて、Clojureを利用する時には、これを利用すればよいのですが、Clojureを使わなくても気軽にS式をHTMLに変換できるツールがあるといいなぁと思っていました。
何かのモジュールで出来ればよかったんですけど、なかなかズバリなものがなかったので、パーサ部分から書くことにしました。
Perlで作った理由は、Movable Typeで利用したいと思っているからです。これでテンプレートを書けるようにしたい。
このコンバータには、演算機能がありませんが、Movable Typeには、MTVarやら、MTIFやら、MTForやらいろいろあるので、これくらいの機能でも充分かなと思います。
汎用性はすごく低いので、必要に応じてバージョンアップできたらいいですね。
気づいたこと
パーサを書かないといけないというのはわかっていたものの、自分のレベルでは、正規表現でパーサ書くのは厳しいと思ったので、いろいろ調べてみると、Parse::RecDescentという超便利なツールを見つけました。
このツールを作る大半が、Parse::RecDescentの使い方を調べる時間になった気がしますが、これを使えば、Perlで使うちょっとしたミニ言語が作れそうです。
それでも正しく書けているのかどうかよくわからないし、それ以前にコンパイラ周りのこと、全然知らないので、このツールに頼らなくても、ミニ言語が作れるようになりたいですね。
他に、野良モジュールをインストールしてもらう方法とか全然知らなかったので、いろいろ苦戦しました。
まとめ
S式とは言いつつも、ただ、記法を利用しただけなので、別にLispができるできないは関係なく使ってくれる人がいるといいなぁと思います。S式もDOMも、同じく木ですし、S式はそんなに難しいものではないです。
とりあえず、タイプ数は減るし、zen-coding感覚で使ってもらえれば良いかと。
そのままLispに目覚めても良いと思いますよ; )
時間のある時に、Movable Typeのプラグインとして利用できるようと思います。
次の13日の金曜日というサービスをリリースしました
最近、なかなかプログラミングする機会がないので*1、作って放置していたプログラムを編集して、Webサービスにしてみました。
サイト
作ってみて
ClojureでWebサービス作りたいなーとは思ってはいたものの、なかなかそんな時間もモチベーションもなく、今に至ります。
作った背景とかサイトの使い方は、リポジトリのREADME.mdに書いてあります。
Clojureの基本は、4Clojureで概ね学んだので、新たに学んだのは、noirの使い方です。
noirのテンプレートは標準だとviewが別ファイルになっていますが、これくらい小規模であれば1ファイルで書く方が楽でした。
noirは、シンプルで、Mojolicious::Liteみたいに気軽に使えて良いのと、標準のテンプレートエンジンのhiccupがかなり良いです。zen-codingのような感覚で記述できます。zen-codingみたいに、手動でHTMLに展開する手間ないし、プログラムも埋め込めるし、勝手にminifyするし。
noirを使ってて困ったのは、JSONに出力する時に、charsetがISO-8859-1になってしまう点です。ただ、バージョンアップで改善されるっぽいので安心しました。(Google Groups)
Clojureらしく、無限シーケンスで処理したり、小さな関数を組み合わせて処理を組み立てるってところは意識しながら作りましたが、そもそも関数脳になりかかってるので、他の言語使うより、Lisp系統である、Clojure使った方がストレスなく記述できるようになってきました。ただ、Javaの主要のクラスとメソッドはなんとなくでも覚えておいた方がいいなぁとは思います。副作用はdotoの中に押し込んでしまえば、そんなに抵抗なく使えます。
なんというか、関数型言語は、小さな関数作って、拡張してみて、挙動変えてみて、入れ替えてみて、最後に欲しいのはこれ、って感じでルーズにプログラミングできる感じがして、自分の性格的に合ってるような気がするんですよね。
Clojure + noirでモノ作って、herokuに上げる流れは、ひと通り把握したので、また機会を見つけて、Clojureで何か作りたいですね。
たらい回しの塔
たらい回し関数(竹内関数)とProcessing.jsを使って塔を建てる。
たらい回しの塔 - jsdo.it - share JavaScript, HTML5 and CSS
えげつなさが可視化される。