何故同じrouteを2回定義したときの動作が気になったかというと、@miminashiさんのtweetが気になったからです。

Twitter / @miminashi: @komagata プラグインに書いたdoブロックの ...

Lokkaではまずプラグインが読み込まれるのでこの動きは好都合。

# public/plugin/lokka-unk/lib/lokka/unk.rb:
module Lokka
  module Unk
    def self.registered(app)
      app.get '/' do
        'unk'
      end
    end
  end
end
% curl http://localhost:9646
unk

プラグインから簡単にトップページを横取りできた。これはいいフリーダム。

# public/plugin/lokka-unk/lib/lokka/shit.rb:
module Lokka
  module Shit
    def self.registered(app)
      app.get %r{^/([0-9a-zA-Z-]+)$} do |slug|
        slug
      end
    end
  end
end
% curl http://localhost:9646/1
1
% curl http://localhost:9646/hoge
hoge

個別ページはこんな感じ。選ばれない方のメソッドは単に実行されないので副作用はありません。

require 'rubygems'
require 'sinatra'

get('/') { 'unk' }
get('/') { 'shit' }
% curl http://localhost:4567
unk

先に定義された方が実行される。

Mac版Lokkaの始め方。

仕事を邪魔されない非同期コミュニケーションのやり方を模索中。

ランチャーと簡単なスクリプトを使って受信せずにTwitterとメールを送信する。

前回最低限のテーマの作り方を紹介しました。今回は無くてもいいけど使うと便利なテンプレートタイプについて紹介します。

Lokkaにはデフォルトのentry, entries以外に様々なテンプレートタイプがあります。テンプレートは一覧、個別、その他のどれかに分類されます。

テンプレートタイプ

一覧

  • index --- トップページのテンプレート
  • category --- カテゴリー別の一覧ページのテンプレート
  • tag --- タグ別の一覧ページのテンプレート
  • yearly --- 年別の一覧ページのテンプレート
  • monthly --- 月別の一覧ページのテンプレート
  • search --- 検索結果の一覧ページのテンプレート
  • entries --- 一覧ページのテンプレート。上記のテンプレートが無い場合に使われる。

個別

  • post --- 投稿(Post)の個別ページのテンプレート
  • page --- ページ(Page)の個別ページのテンプレート
  • entry --- 個別ページのテンプレート

その他

  • partial --- テンプレートの一部分を共有するテンプレート
  • layout --- テンプレートの外枠を共有するテンプレート

一覧テンプレート

一覧はentries、個別はentryというテンプレートがありますが、例えば一覧で"検索結果だけに必要なもの"があった場合、entriesの中がごちゃごちゃしてしまうのでsearchという名前でテンプレートを作っておくと、検索結果の場合はそちらが優先して使われます。

個別テンプレート

同じようにentryとpostというテンプレートがあった場合投稿(Post)の場合はpostが優先的に表示されます。投稿とそれ以外で別の内容にしたい時に便利です。

どのテンプレートが選ばれるかはURLで決まります。実際には厳密なルールがありますが長くなるので代表的な例を紹介します。

  • index --- /
  • category --- /category/foo/
  • tag --- /tag/foo/
  • yearly --- /2011/
  • monthly --- /2011/01/
  • search --- /search/foo/
  • post --- /1
  • page --- /2

(postやpageやcategoryはIDの他にスラッグと呼ばれる自由なURLを持つことができます。そちらでもアクセスすることも可能です。)

上記以外に特殊なテンプレートタイプが存在します。それがpartialとlayoutです。

partialテンプレート

partialは複数のテンプレートで共通の部分等を別ファイルとして作成して共有するためのテンプレートです。好きな名前で作成することができます。

例えば、Copyright部分をpartialテンプレートとして下記のように作成し、別のテンプレートから読み込む事ができます。

copyright.erb:

<p>Copyright FJORD, LLC</p>

entries.erb:

(省略)
<%= partial 'copyright' %>

entry.erb:

(省略)
<%= partial 'copyright' %>

同じ内容が複数のテンプレートで出てくる場合にpartialを使うと楽でしょう。

layoutテンプレート

もう一つのlayoutテンプレートはpartialとは逆に、テンプレートの一部分を共有するのではなく、外枠の殆どを共有するイメージです。

layout.erb:

<h1 id="header">Title</h1>
<%= yield %>
<div id="footer">Powered by Lokka</div>

entry.erb:

<h2>Post Title 1</h2>
<div class="body">body ...</div>

yieldの部分にentryやentriesのテンプレートの結果が全部入るイメージです。layoutテンプレートはWordPressなどには無い機能なので多少取っ付きづらいですが、テンプレートの大部分を共有できる非常に便利な機能で、上手く使うとテーマコーディングが大幅に楽になります。数多くのフレームワークに採用されている機能なので是非とも活用してみてください。

機能としては簡単だけど名前の付け方で悩んでいる。どうでもいいことかも知れないけど数日悩んでいる。

ブログ(Lokka)に記事のドラフト機能を追加したい。つまりデータとしては存在するけどおもてには表示しない記事。そこで下記のようにフラグを用意し、その一覧をとってくるメソッドを用意する。

class Post
  property :title, String
  property :draft, Boolean

  def self.draft # 重複!
    all(:draft => true)
  end

  def self.not_draft
    all(:draft => false)
  end
end
>> Post.draft
>> Post.not_draft.all(:title.like => '%foo%')

draftがフラグ名だとメソッド名とかぶるので使えない。この例はDataMapperだけどActiveRecordのnamed_scopeでも同様だ。

こういう場合、今までの俺は、

フラグ名:publish
メソッド名:published, unpublished

みたいな名前を付けてたんだけど、draftというフラグ名を見てこっちの方が具体的な名前だからいいなと思った。できればdraftを採用したい。publishは動詞でdraftは名詞だから上手くいかないのかな。こういうモノを作る場合のRuby/Rails界隈の簡単ルールみたいなものがあったら知りたい・・・。

[OSX]理想のランチャーを探す Alfred ? | diary NET. 1.2mg

@milligrammeさんのエントリーを見てAlfredのPowerpackを買ってみた。Terminalのコマンドを実行できるという機能があったからだ。

System

>からテキストを打ち始めるとTerminalが新しく開いてコマンドを実行してくれる。これはかなり僕の求めてたものに近い。しかしopen http://google.comのような結果の表示が必要無いコマンドの場合は実行するたびにTerminalのウィンドウが1枚増えるので閉じて回るのが面倒臭い。

ところが、open http://google.com;exitのように打てば問題無いことに気づいた。特に僕はzshのaliasでexitをqに割り当てているので;qを末尾に書くだけで勝手に閉じてくれる。上記スクリーンショットの様に結果を見たい場合は普通に打って、そうでない場合は;qを付ける。

これはマジメに使えそうだ。しばらく常用してみます。(常用=Spotlightのショートカットと入れ替えること)

DataMapperのdefault_scopeのマージされ方がおかしい。

class Entry
  default_scope(:default).update(:draft => false)
end
>> Entry.count
SQL: (0.000099) SELECT COUNT(*) FROM "entries" WHERE ("draft" = 'f'))
=> 1
>> Entry.count(:draft => true)
SQL: (0.000099) SELECT COUNT(*) FROM "entries" WHERE ("draft" = 'f' AND "draft" = 't')
=> 0

ActiveRecordでも多用していた機能なので困ったなと思ってたら・・・。

#1202 Overwriting default_scope conditions is broken - DataMapper - datamapper

It's a private API so the ticket should be treated more like a suggestion to make the default_scope a public method and of course make it work correctly.

default_scopeはprivate APIなのでbugではなくsuggestion扱いだそうです。ticketのstateもholdになってました・・・。

tikushoo

Debian -- News -- Debian 6.0 "Squeeze" released

After 24 months of constant development, the Debian Project is proud to present its new stable version 6.0 (code name Squeeze).

おめでとうございまーーーす!

しかしLennyの時に比べて自分の心の動かなさにビビった。2年しかたってないのに。

Debian Lennyリリース - komagata [p0t]

Heroku使い始めてからホントにサーバー触らなくなってしまった。(HerokuもDebianベースなのに)

一応実家にはサーバーあるんだけど、オフィスの引越しで社内サーバーを撤廃してから本当に触る機会が減った。以前はローカルのcoLinux内のDebian+仕事の公開用サーバーがDebianって感じのDebian尽くしだったのが、今はローカルのMac+Herokuだから寧ろMacの設定を触ってる感じ。その代わりコード各量は増えてる気がするのでいいか。

"受動的なコミュニケーションツール"の件はとりあえず"非同期コミュニケーション"と"私書箱"の二つの問題に分けて考えることにする。まずは"非同期コミュニケーション"の方。

同期コミュニケーションが仕事に与える問題は"総量は同じでも小分けにすると質が下がる"というところ。Json Friedは"睡眠"のメタファーを紹介している。"都市部と高速道路での燃費"のメタファーでもいいかもしれない。

要は会話や電話を辞めてメールを使えということ。ついでにTwitterやSkypeチャットやGrowlも非同期、要するに1日1回まとめて処理すればいい。

そんなモノは簡単だ。メールもTwitterもフィードリーダーもSkypeも朝一回確認したら終了して使わなければ良い。でも実際にはなかなかそうはならないのは何故か。

"受信がデイリーになっても送信は一日何度もある"からだ。

メールを送る時に未読メールを見てしまう。Twitterでメッセージを送るときにTimelineを見てしまう。

「あれ?何をしてる途中だったんだっけ?そうだ、仕事のメールを送ろうとしてたんだ。」

これが仕事の妨げになっていることに気付いた。送信と受信(一覧)の機能が一緒になっているのがいけない。メールは完璧な非同期コミュニケーションツールなんだから、送信専用のメーラーがあればいい。

ということで簡単なスクリプトを書いてみた。

% vi ~/bin/ml
#!/usr/bin/env ruby                                                                                                                                              
to = ARGV[0]
body = ARGV[1]
length = 30
subject = body.split(//u)[0, length].to_s
IO.popen("mail -s '#{subject}' #{to}", 'r+') {|io| io.puts body }

gist: 812535 - MTA *sending only*- GitHub

% ml machida@fjord.jp 来週の打ち合わせの場所をGカレンダーに入れときました。

頻繁に送る相手はたいしていないのでshellのhistory補完で十分だ。でもどうせRuby使うなら普通に直接GmailのSMTPにつないでもいいかも知れない。しかしその代わりに伝統的な~/.mailrcとかが使える。

% vi ~/.mailrc
alias komagata komagata@gmail.com
alias machida machida@fjord.jp
% ml machida キムチもって帰りました。超うまかったす。

TwitterやSkypeも上記の様な感じの送信専用が欲しい。

関連:受動的なツール - komagata [p0t]