ブログトップ 記事一覧 ログイン 無料ブログ開設

あと味 このページをアンテナに追加 RSSフィード Twitter

2012-02-02 最近の制作環境メモ(主にgitのこと)

制作環境メモ(主にgitのこと)

定期的に書いてる気がするけど、実際に定期的に見直しているので、最近制作環境メモを書きます。

制作環境で言う制作とは、割と一般的なサイト制作のことです。

制作ツール

  1. vim
  2. git
  3. sass(最近compassも使ってみたり)
  4. yuicompressor
  5. firebug
  6. Wordpress or Movabletype
  7. Dropbox
  8. 社内サーバー

ほとんどの案件で使う制作ツールはこんな感じ。MTを使うことが増えてきてます。

MTCMSとして使うほか、CMS不要お客様案件でも、案件ごとに社内サーバーMTOSを入れて、HTMLジェネレータツールとして利用しています。

Dropboxは社内で共有しています。個人的には、全員がgitを使えるようになれば、共有する必要はないと思っていますが、まだその段階は先の話です。

gitの使い方

個人的にgitがようやく「使うことで効率が落ちる」というフェーズから、「使わないことで効率が落ちる」というフェーズに入って来ました。

「使うことで効率が落ちる」というのは、単に学習コストを払えていないため、ツールの使い方を調べたりするのに無駄時間がかかるということです。

  1. 社内サーバーに共有リポジトリを作る
  2. Dropboxに置いた制作環境git管理し、remoteに社内サーバーの共有リポジトリを設定する
  3. 社内サーバードキュメントルートgit管理し、remoteに社内サーバーの共有リポジトリを設定する
  4. 社内サーバーの共有リポジトリhookに、Dropbox内の環境pushした時には、社内サーバードキュメントルートでpullを走らせる設定を書く
  5. WordpressMovableTypeテンプレートファイル以外のすべて、コンパイル後のCSSJavaScriptは.gitignoreで除外。

利用する本番サーバーgitが使える場合は、remoteをもうひとつ追加して、ローカル編集内容が本番サーバーにも同期されるように設定する場合もあります。

静的ファイルテンプレート管理

静的ファイルを先に作って、WordpressMovableTypeなどのテンプレートに切り出していきますが、割と大きめな修正がある時は、テンプレートを書き換えるより、静的ファイルを書き換えた方が手っ取り早いことが多く、静的ファイルも同じディレクトリ構成で管理しています。

  1. HTML
  2. DevServer

のようなふたつのディレクトリを用意し、基本的には同じディレクトリ構造にします。同じディレクトリ構造というのは、ディレクトリ的に同じというよりは、最終的なURLパスが同じ構造になるようにということです。HTMLディレクトリとDevServerディレクトリに違いがあるとすれば、DevServerの方には、WordpressMovableType固有のファイルや、scssファイル、圧縮前のjsファイルなどが入っている点が違います。

また、HTMLディレクトリの中身は、社内サーバーには要らないので、remoteを追加せず、別のgit環境として管理しています。

そして、HTMLディレクトリ画像CSSJavaScriptディレクトリは、DevServerディレクトリものと同じファイルを使うことになるので、DevServer側のディレクトリからシンボリックリンクを貼ります。

DevServerのファイルも、HTMLファイルも、環境依存がないようにパス記述が必要な箇所は、「/(スラッシュ)」から始まる絶対パスで書くように統一しています。

現時点の問題点及び改善

  1. 社内サーバードキュメントルート更新した内容をcommitしたり、それをDropbox環境に反映するのは、手動でしていますが、これも自動化した方がいいのかもしれない。
  2. sassとyuicompressorを走らせる設定もhookに書いておいた方がいいかも。
  3. 他の人が行った更新コミットログは、自分が書かないといけない感じになっているので、なんとかしたい。
  4. 他社の方のやり方を聞いたり、ディスカッションする場があまり持てていない。
  5. まだgitの表面的な使い方しかできていない。

まとめ

文字ばかりでごめんなさい。まだまだ試行錯誤してます。もっと良い方法が多分ありますが、やりながら見つけていくしたないですね。

とりあえず、現段階ではgitベースにしたサイト制作フローが、それなりに機能してきたので嬉しいです。

2012-01-15 ロジカル・シンキングについて学ぶ

ロジカル・シンキングについて学ぶ

社内勉強会ロジカル・シンキングについて説明する機会をもらいました。(社内と言っても、自分除いて3人しかいませんが...)

社内に特化した話をしたり、ちょっとしたワークもしましたが、その部分は本エントリーから除いています。

現在の職種は、テクニカルディレクターなので、ロジカル・シンキングは基本スキルとして必要だと感じています。今回の資料を作るにあたって、以前購入して読んだっきりの書籍を読みなおして、頭の整理や考察ができたので、とても良い機会になりました。

では、本題に入ります。

ロジカル・シンキングとは?

論理的な思考力のことです。

論理」という言葉意味辞書新辞林 三省堂)で調べると、

  1. 思考の形式・法則。議論や思考を進める道筋・論法
  2. 認識対象の間に存在する脈絡構造

とあります。

論理学という学問は昔からありますが、学問としてではなく、それをよりカジュアルに、ビジネスで使えるよう進化させていったものロジカル・シンキングです。

ロジカル・シンキング馴初め

ちょっと話は脱線して、思い出話。

パソコンインストラクターだった自分は、自然ロジカル・シンキングに触れることになりました。

インストラクションは、相手に物事を理解してもらう技術であるので、知らず知らずの内に、ロジカル・シンキングの種が自分の中に生まれていたのかもしれません。

ビジネス書を大量に読んでいた時期には、自然ロジカル・シンキングという言葉に触れ、インストラクションの技術向上のために、体系的にこの技術を学びたいと思い、出会ったのが馴初めです。

体系的に学ぶことなく、論理的な思考ができる方はたくさんいます。

ロジカル・シンキングは説明したり、説得したりする技術を合理化していく過程で生まれた技術かなと考えています。ですので、頭の良い人は知らず知らずの内に、自力でそれができるようになっていくのではないでしょうか。

また、頭の良い人に囲まれて生活していたり、読み書きを頻繁にしたりすると、それに影響されて、自分でも論理的な思考ができるようになる方もいるように見受けられます。

ただ、まったくそういう機会がなかった方は、書籍などを通して体系的に学んでみると、一生役立つスキルになると思いますので、もう少し具体的に説明していきます。

オススメ書籍などは、後ほど後述していきます。

ロジカルシンキングの基礎技術

ロジカルシンキングは以下の2つの基礎技術が根幹にあります。

MECE

書籍ロジカル・シンキング―論理的な思考と構成のスキル (Best solution)」によると、MECE定義が以下のように書かれています。

ある事柄や概念を、重なりなく、しかも全体として漏れのない部分の集まりで捉えること。

Mutually Exclusive and Collectively Exhaustive

MECEの具体的な例としては以下のようなものです。

  1. 男性女性
  2. 都・道・府・県
  3. 起・承・転・結
  4. 0点〜25点・26点〜50点・51点〜75点・76点〜100点

「モレなく、ダブりなく」になっているものMECEです。

実際に自分MECEを作る際には、本当にモレはないか?、本当にダブりはないか?を何度も自問しないといけませんが、完全なMECEを作るというのはなかなか難しく、客観的にMECEと認められる程度の分類になることが多いです。

マジックナンバー7という言葉がありますが、人間が短期的に記憶できる数は7±2と言われています。

MECEを作る際、あまり厳密に分類しすぎて、項目が多くなってもいけないので、一つメタ構造を考えるとか、グループでまとめるとかいろいろ検討しないといけません。

So What? /Why So?

先ほどと同じく書籍ロジカル・シンキング―論理的な思考と構成のスキル (Best solution)」によると、So What? /Why So?の定義が以下のように書かれています。

So What?:

手持ちのネタ全体、もしくはグルーピングされたものの中から課題に照らした時に言えることのエキス抽出する作業。

Why So?:

So What?した要素の妥当性が、手持ちのネタ全体、もしくはグルーピングされた要素によって証明されることを検証する作業。

この定義だけ読むと難しいのですが、要は、結論とその結論を導き出した根拠、つまり因果を考えて、因果関係妥当かどうかを検証する作業になると思います。

から果を導きだす作業がSo What?、導きだした果の因となる要素の妥当性を検証する作業がWhy So?です。

論理の基本構造

以上のMECESo What? /Why So?の基礎技術をどのように使うのかも、書籍ロジカル・シンキング―論理的な思考と構成のスキル (Best solution)」に書かれています。以下がその定義です。

論理とは、結論と根拠、もしくは結論とその方法という複数の要素が、結論を頂点に、縦方向にSo What? /Why So?の関係で階層をなし、また横方向にはMECEに関係づけられたものである

言葉ではわかりにくいので、図でも確認します。同書の図を簡略化したものが以下の図です。

f:id:jdg:20120107153506p:image:w360

MECESo What? /Why So?を利用してこのようなピラミッド構造を作ることが、論理の基本構造を作る作業とされています。

フレームワーク思考

ロジカル・シンキングに利用できる、様々なツールがあります。それらのツールのことをフレームワークと呼びます。

フレームワークよりも基礎的な汎用的なツールもあります。

  1. ロジックツリー
  2. マトリクス

などです。

マインドマップマンダラートも、ロジカル・シンキングに利用できる汎用的なツールとして使っても良いかもしれません。

フレームワークの例としては、

  1. 空・雨・傘
  2. SWOT
  3. 3C
  4. 4P
  5. AISAS, AIDMA

など、各分野の先駆者たちが作ったフレームワークが大量にあります。

いずれのフレームワークも物事を、あるテーマで、MECEに分類できるものであると思います。

フレームワークを利用するということ

プログラミング世界でも、フレームワークというものがありますが、やはり、凡人である自分などは、自分の持つスキルだけで何かを作ったり、何かを考えたりすると、手落ちがあります。

何かの課題を解決するためにフレームワークを利用すると、大抵は、無駄なく、網羅的に物事を進めることができます。効率的かつ安全です。フレームワークは先人の知恵の詰まった大変役立つツールなので、使わない手はありません。ビジネスにおけるフレームワークでも同様です。

フレームワークを探す際には、その分野についての書籍を読めば、大抵いくつかは載っています。例えば、企画職だったりすれば、以下のような書籍も売っています。

考具 ―考えるための道具、持っていますか?

考具 ―考えるための道具、持っていますか?

守破離

武道や芸の世界で、日本に古くから伝わる、伝承のためのフレームワークに、守破離というものがあります。

守・破・離は時系列MECEです。

守破離の教えのように、フレームワークを先ずは使いこなせるようになって(守)、自分なりの改良を加えて(破)、自分オリジナルフレームワークを作る(離)という手順に則って使っていくのが良いのかなと思います。

ロジカル・シンキングは習慣化するもの

自分は、ロジカル・シンキングを本で体系的に学ぶ機会がありましたが、確実に実践できているかというと疑問があります。

ただ、何かの難題に出会って、自分の頭では整理がつかない時には、その解を求めるのに適したフレームワークを探して利用しますし、論理破綻している文章や話を聞いていても、違和感を感じるようにはなっています。パンツを履き忘れているような、何か気持ち悪い感じがします。

ロジカル・シンキングは基礎技術であり、様々な問題に適応できる汎用技術です。基礎技術は習慣化していくことで、応用ができるものだと思うので、まずは習慣化することが大事だと考えます。

習慣化している人がどんな感じなのかの例は以下が参考になります。ここまでになれば楽しそう。

暇人\(^o^)/速報 : 勝間和代の「桃鉄論」がガチすぎて引く - ライブドアブログ

ロジカル・シンキングに関することは、勝間さんの本にも書いてありますが、マッキンゼー出身者の出している本が多いように思います。コンサルティング業界では標準スキルなんでしょうね。

ロジカル・シンキングの注意点

ロジカル・シンキング魔法の道具ではないので、時に、間違いを犯します。

あくまで客観的に筋道が通っているように見せることができるだけで、それが正しいかどうかはやってみないとわかりません。確実に仮説が正しくなるのであれば、ロジカル・シンキングが出来る人は、人生で間違いを犯さないということになってしまいます。優秀なコンサルタントだって、間違いは犯します。

優秀な人が、お客さんの課題を解決するために、ロジカル・シンキング論理に穴がなく、確実に課題が解決できそうな期待を持たせる提案書を作ったとしても、提案の熱意が伝わらないという理由で却下されることは往々にしてあります。逆に組み立てたプランは根拠が乏しくズタズタであっても、熱意がものすごく伝わったからOK。という場合もあります。

ロジカル・シンキングは、仮説が正しいことを保証するものではありません。仮説が正しくなる確率を高めることはできます。

一度立てた仮説を信じ続けるのではなく、小さな失敗や環境の変化が起こった際、仮説について再考して、仮説が正しくなる確率を逐一高めていくことが必要だと思います。

ロジカル・シンキングの使い所

誰かを納得させるために使います。納得の先にアクションを求める場合もあります。

論理的な文章や、論理的な話は、例えその結論や仮説が間違っていたとしても、間違ったという事実がなければ、それを導くまでのプロセスには納得できるものです。

なので、誰かを納得させる時がロジカル・シンキングの使い所です。説明であれば、納得や理解がゴールですし、提案であれば、納得してアクションを起こしてもらうことがロジカル・シンキングで求めるゴールです。

まとめ

ロジカル・シンキング技能を身に付けて、相手を納得させる文章を書いたり、議論をすることができるようになれば、意思決定が早くなりますし、成果を出しやすくなったり、失敗の確率を低めることができるようになるはずです。

まずは基礎技術であるMECESo What? /Why So?です。

MECEは「モレなく、ダブりなく」分類する技術So What? /Why So?は分類された要素から、「要するに何なの?」を、掘り下げて結論を作り、結論が「なぜそうなるの?」を、So What?した要素で説明がつくかどうかを検証する技術です。この両者を用いて横軸がMECE、縦軸がSo What? /Why So?の階層となるような論理ピラミッド構造を作ることがロジカル・シンキングの基礎です。

以下に紹介する書籍も参考に、是非学んでみてください。

参考図書

ロジカル・シンキングという言葉は出てきませんが、そのさらに基礎となる考え方を学べます。

ロジカル・シンキングという言葉が世に浸透するキッカケを作った書籍だと言われています。メッセージシンプルですが、例題などもあり、基礎技術の習得には適していると思います。

ロジカル・ライティング (BEST SOLUTION―LOGICAL COMMUNICATION SKILL TRAINING)

ロジカル・ライティング (BEST SOLUTION―LOGICAL COMMUNICATION SKILL TRAINING)

上記と同じ著者の書いた、ライティングに特化した書籍です。

戦略思考コンプリートブック

戦略思考コンプリートブック

ロジカル・シンキングの基礎技術を、頭で理解したら、手を動かして実践したくなります。ロジカル・シンキングをより応用的、実践的にした戦略思考という言葉テーマとした書籍で、各種フレームワークの紹介やそれを用いたケーススタディがあります。

地頭力を鍛える 問題解決に活かす「フェルミ推定」

地頭力を鍛える 問題解決に活かす「フェルミ推定」

直接的には関係ありませんが、客観事実を洗い出す際に、手に入らない情報というものもあります。基本となる情報を用いて、必要な情報を推論して導きだすためのフェルミ推定について書かれた本です。

その他、ロジカル・シンキングテーマの本は大量に出版されているので、自分にあった本を探すと良いですね。上記に上げたものは、割と古典的な教科書なので、それが堅苦しい方はもう少しカジュアルな本をとっかかりにするのも良いかなと思います。

2011-12-14 JavaScriptでswitchの再発明

JavaScriptでswitchの再発明

先日、Underscore.jsを弄っていて、なんでも関数化したい病にかかり始めたので、書いてみました。

when$when関数の返り値がtrueになっても継続するオプションを設けてもいいかもしれない。

追記

2011-12-11 watchオプションの使い方

watchオプションの使い方

Less & Sass Advent calendar 201111日目です。

Sassは自分コーディング担当案件は、確実に使っているのですが、まだまだ表面的な使い方しかできてないのかなと、Advent Calendarの他の記事を見ると感じます。

さて、Sassを使ってCSSを書いていく時には、ほぼ例外なく、watchオプションのお世話になることと思います。

弊社のデザイナーのやり方などを見ると、イマイチ理解して使ってない感じもしたりしたので、少し細かく説明する記事があってもいいのかなと思って、この記事を書くことにしました。

知ってる人には当たり前すぎて、得るものがないかもしれませんが、その点はご了承下さい...

watchオプションとは?

Sassはfilename.sassまたは、filename.scssを使って、Sassの記法、もしくはSCSS記法で書いたファイルを、コマンドラインを使ってfilename.cssコンパイルするという方法で、CSSファイルを作ります。(以後、SCSS記法を使うことを前提で書きます)

その際、SCSSファイル更新するたびに、毎回コンパイルし直すという手順が非常に面倒なので、ファイル更新監視し、更新があれば、自動コンパイルしてくれる、watchオプションが非常に役に立ちます。

watchオプションの使い方

Sassのリファレンスにwatchオプションの指定方法が書いてある他、Unixコマンドラインツールの多くは、コマンドラインオプションを、

commandname --help

入力することで確認することができます。

Sassの場合も、

sass --help

入力することでSassのコマンドラインオプションをすべて確認することができます。*1

watchオプションの項目を見ると、

sass --watch input.sass:output.css
sass --watch input-dir:output-dir

というコマンドが確認できます。

どちらも、変換元と変換先をコロンで区切る形でオプション引数を指定することがわかります。

SCSSファイルの作り方

人それぞれかもしれませんが、SCSSファイルは用途やページによってファイルを分けることが一般的なのかなと思います。

@importが強力で、CSSの@importルールと違い、Sassの@importはインポートするファイルを一つのファイルに結合してくれます。

Webサイトパフォーマンス改善が流行った時期に、CSSの@importはHTTPコネクションが多く発生してしまうからやめましょうという流れがあって、@importを使うことを消極的にしていた方もいらっしゃると思いますが、SCSSの@importはガンガン使っちゃっても最終的に一つのファイルに結合されるのでガンガン使っちゃって問題ありません。

ファイル監視フォルダ監視

watchオプションは、ファイル監視フォルダ監視があると述べましたが、上述のSCSSファイルの作り方に書いたように、複数のファイルを@importで結合する場合ファイル単位監視ではちょっと厳しくなってきます。

例えば、以下のような場合

/* /scss/style.scss */
@import "hoge.scss";
@import "fuga.scss";

ファイル単位監視をすると以下のようなコマンドになるかと思います。

sass --watch scss/style.scss:css/style.css

この時、せっかくwatchオプション監視していても、hoge.scssやfuga.scss更新しても、style.scss更新をしたことにはならないので、style.cssが新たにコンパイルされることはありません。

なので、基本的にはフォルダ監視オススメです。

同じ例で、フォルダ単位監視をすると以下のようなコマンドになります。

sass --watch scss:css

フォルダ名を指定すると、watchオプションは、監視フォルダに指定したフォルダに保存されている.scssと.sassを探して、ファイル更新監視してくれます。

先ほどのファイル監視では、hoge.scssやfuga.scss更新しても、監視対象に含まれていなかったので、style.cssが新たにコンパイルされることはありませんでしたが、このフォルダ監視であれば、hoge.scssやfuga.scss更新すると、style.cssが新たにコンパイルされます。

アンダースコア付きファイル名について

ただ、上記に関して、1点問題があります。

それは、hoge.scss、fuga.scssも、それぞれ、hoge.css、fuga.cssコンパイルされるということです。

style.cssは、最終的にHTMLで読み込むCSSファイルですが、hoge.css、fuga.cssは、style.cssに結合されていれば良く、無駄な中間成果物かもしれません。

Sassでは、そのケースを解決するために、Partialsという仕組みを用意しています。

hoge.scssや、fuga.scssのように、@importで結合はするが、CSSファイルコンパイルする必要がないファイルについては、_hoge.scss、_fuga.scssと、ファイル名の先頭にアンダースコア入力しておくことで、コンパイルされないSCSSファイルにすることができます。

この際、アンダーバーを付けたからといって、

/* /scss/style.scss */
@import "_hoge.scss";
@import "_fuga.scss";

とする必要はありません。

さらに言うと、sassファイルまたは、scssファイル場合は、拡張子も省略できます。

/* /scss/style.scss */
@import "hoge";
@import "fuga";

なので、上記のような指定をすれば結構です。

まとめ

では、まとめです。

  1. Sassのwatchオプションは、ファイル単位監視フォルダ単位監視があるが、フォルダ単位監視おすすめ
  2. 結合元のscssファイルで、cssとして使用することがないファイルファイル名の先頭にアンダースコアを付ける

リファレンスに書いてあることですが、始めたての頃の自分や、身近な人が理解できてないようだったので、少し丁寧に説明してみました。

Sassは、一度使い出すとなくてはならないツールになると思うので、まだの方はぜひお試しください。

オマケ

個人的には、このくらいのコマンドライン操作はできるようになった方がいいと思うのですが、どうしてもコマンドラインツールが難しい方は、GUIツールでwatchする方法もあります。

まだ使ってはいないのですが、CompassというSass向けのCSSフレームワークがあって、そのCompass用にGUIツールがあるようです。

どうしても難しいという方は、上記のツールを使うのもありなんじゃないでしょうか。

アプリをつかうかどうかは置いておいて、個人的にCompassは今後使っていこうかなとは思っています。現状、SassとYUIと組み合わせていますが、Sassに最適化されたCompassの方が良いのかもしれませんし、調べてみます。

LESSにもLESS.app For Mac OS Xというアプリがあるみたいです。

LESSは使ったことないですけど、Sassに比べて大きなアドバンテージがあったら触ってみようかな。

*1最近バージョンからか、今まで気づかなかっただけなのか、scssってコマンドもあるみたいですね。使い方はsassコマンドと同じです。

2011-12-09 Underscore.jsの全メソッドを表にまとめてみた

Underscore.jsの全メソッドを表にまとめてみた

JavaScript Advent Calendar 2011 (フレームワークコース) の9日目です。

せっかくの機会だったので、ものすごく気になってたけど、触る機会がなかった、Underscore.jsをいろいろと弄ってみました。

配列関係の便利メソッドの集合ライブラリイメージでしたが、タイマーユーティリティ関数、条件判断関数など、いろいろ機能があって面白いですね。

とりあえず、ひと通り実行しながら、すべての関数を触ってみました。

非常に見難くて恐縮ですが、以下のGoogleスプレッドシートにいろいろとメモを取っていったので、参考にしてください。

間違いなどあるかもしれませんし、自分自身理解しきっていないため説明がおかしい箇所があるかもしれません。

その際はご指摘いただけると助かります。超めんどくさかったので、自主的なアップデートは、たぶん、しません...

リンク先: Underscore.jsの機能表

機能表の見方

左の列から順に、

  1. カテゴリ
  2. メソッド
  3. 書式
  4. 説明
  5. aliases
  6. native method変換
  7. 備考
  8. 擬似的な型(Ocamlっぽく)

となっています。

各列の説明をすると以下のとおりです。

カテゴリ

Underscore.jsサイトどおりのカテゴリ

メソッド

メソッド名。

書式

実行例を引数も含めて書いたもの

説明

自分で考えた説明(ここは間違っている可能性も高い箇所です)

aliases

別名が定義されているものはそれを列挙。

native method変換

内部でnative methodに変換しているものは、変換したメソッド名。

備考

気づいた点など。

擬似的な型

Ocaml勉強しているので、それ風に書いてますが、オリジナルの型を勝手に付けてますし、合ってるか間違ってるかの判断もできないレベルです。書き始めちゃったら後戻りできなくなったし、かと言って消すのももったいないし、私のためのメモというか...

えっと、無視してください。(もし、Ocamlに造詣の深い方がいらっしゃったら、助言いただけるとうれしいです。)

オプション引数[context]について

書式の列にオプション引数を使っているメソッドがありますが、個人的に[context]はわかりにくかったので、解説します。

Collectionのカテゴリには、each, map, reduce, reduceRight, find, filter, all, any, max, min, sortByに。Utilityのカテゴリには、templateにあります。

templateはちょっと違う意味で使われていますが、[context]に指定するものオブジェクトになります。

eachで例を出すと以下のような感じです。

var messs = ['My', 'name', 'is', 'taiju'];

var Blog = function(author) {
  this.author = author;
};

var blog = new Blog('taiju');

_.each(messs, function(mess) {
  console.log(this.author + ' said: ' + mess);
}, blog);

eachに[context]を渡した例です。見てわかるように、thisの値に[context]で指定したオブジェクトが束縛されます。

内部でthisの値を使うような関数を渡す時に、[context]を使います。

ネイティブメソッド変換について

JavaScriptが持つメソッド(以後、ネイティブメソッドと表記)で処理を実現できるものに関しては、内部でネイティブメソッドに変換して実行しているものがあります。詳しくは、表中のnative method変換の列をご参照ください。

オリジナルの処理よりも、最適化されたネイティブメソッドが使われた方がやはり効率的です。

eachメソッドでベンチを取ってみました。eachメソッドはArray.prototype.forEachが使える環境では、それを使うように最適化されています。

eachメソッドのベンチ - jsdo.it - share JavaScript, HTML5 and CSS

Array Likeオブジェクトでは、forEachメソッドが使えませんので、パフォーマンスが低くなっています。eachメソッド配列だけではなく、オブジェクトにも使うことができますが、オブジェクト(Arrayオブジェクトを除く)も、forEachメソッドが使えませんので、パフォーマンスが低くなります。(上記のベンチでは微妙な差ですが、要素数が多いと、よりハッキリするかもしれません。Array Likeオブジェクトは最も効率が悪いですね。)

パフォーマンスが気になるのであれば、_.toArrayメソッドなどを適宜利用して、ネイティブメソッドが使われるようにプログラミングした方が良いかなと思います。とは言え、どれとは言いませんが、そもそもArray.prototype.forEachを持っていないブラウザ使ってる時は無意味ですね。

ソートリスト最適化

一部、ソートリストを渡すことでアルゴリズムがより効率の良いもの最適化されるメソッドがあります。

具体的には、uniqとindexOfです。

これらのメソッド配列を渡す際、ソート済の配列を渡して、かつ、[isSorted]オプションにtrueを渡すとより効率の良いアルゴリズムが選択されます。

具体的にはuniqの場合最適化すると、配列の走査が一度で済みます(最適化されない場合は、要素の数だけ配列全体を走査する)。

indexOfの場合は、最適化すると、線形探索ではなく、二分探索になります。

ベンチも取ってみました。

[Underscore.js]indexOfのベンチ - jsdo.it - share JavaScript, HTML5 and CSS

indentityメソッドについて

引数をそのまま返す関数を返す関数です。

関数型言語では、一般的に恒等関数と呼ばれるもので、ユーザーが使うことはないと思いますが、高階関数を利用するシーンにおいて、何も作用を及ぼさないが、関数全体を壊しもしない関数ということで、利用価値があるのだと思います。

実際に、内部的に、iteratorデフォルト値として使われるシーンがあります。

OOPスタイルプログラミングについて

Underscore.jsでは、OOPスタイルプログラミングができるようになっています。

サイトに載っているサンプルコードを以下にコピペします。

var lyrics = [
  {line : 1, words : "I'm a lumberjack and I'm okay"},
  {line : 2, words : "I sleep all night and I work all day"},
  {line : 3, words : "He's a lumberjack and he's okay"},
  {line : 4, words : "He sleeps all night and he works all day"}
];

_(lyrics).chain()
  .map(function(line) { return line.words.split(' '); })
  .flatten()
  .reduce(function(counts, word) {
    counts[word] = (counts[word] || 0) + 1;
    return counts;
}, {}).value();

// => {lumberjack : 2, all : 4, night : 2 ... }

_()の中にコレクションを挿入して、そのままメソッドチェインで処理をつなげていますね。

_()の返り値は、this._wrappedに引数オブジェクトが代入されたラッパーオブジェクトですが、ユーザーがUnderscoreオブジェクト拡張する用途にも使う、mixinメソッドを使って、wrapperオブジェクトのprototytpeオブジェクトに、Underscoreオブジェクトに追加したメソッドが全て結合されています。

_.prototypeとwrapper.prototypeは共通の参照を持っているので、どちらの方法でも同じメソッドが使えるようになっています。

引数の順番について

Underscore.jsでは、コレクション、配列を指定する扱うメソッドに関して、第一引数がコレクション、または配列になっているメソッドがほとんどです。

これには引数の順番に一貫性があってわかりやすいという利点がある他、メソッドチェーンを実行できるようにするための、chainメソッドにおいても重要ポイントになっています。

前述した、_()の返り値であるラッパーオブジェクトは、chainメソッドを持ちます。chainメソッドを実行すると、内部のchainフラグが立ち、それ以後、chainフラグが立っている限り、メソッドをチェインでつなげることができます。

チェイン化されたラッパーオブジェクトは、各メソッドの実行時、そのメソッドの第一引数に、ラップされたコレクションを渡す処理になっています。そのため、チェインでつなげるメソッドの第一引数は、関数オブジェクトから渡せばよく、関数適用後のコレクションは、ラップされたコレクションに上書きされます。これによって、次々とメソッドを実行していく過程で、ラップされたコレクションを書き変えていくことができます。

動的型付けで、prototypeベースのいつでもどこでも拡張していいよ!というゆるゆる言語なお陰で、こういう柔軟な機能提供できるってことで、改めて、JSすげ、と思う次第です。

まとめ

Underscore.jsは、個人的に超好きそうなライブラリだと思っていましたが、弄ってみて、やはり超好きなライブラリでした。

関数プログラミングに興味がある人は、好きになる可能性が高いと思います。

今回はAdvent Calendarの縛りで、公開日が決まっていたため、一部記事の内容を妥協せざるを得ませんでしたが、後日、Underscore.jsソースコードを参照しながら、もうちょっと踏み込んだ内容の記事が書けたらいいなと思います。

特にタイマー系のメソッド結構トリッキーだったり、公式のサンプルコードではイメージがわかなかったり、オプション引数の使い方がわからずじまいになったりするので、オリジナルのサンプルコードを用いて解説する記事があるといいなと、個人的にも思います。

無駄にUnderscore.jsについての知識がついてしまいましたが、ありがたい話です。そんなキッカケ作りに、Advent Calendarはいかがでしょうか。

今年度分もまだ、空いてます!!