$ sudo -s
# bash < <( curl -L http://bit.ly/rvm-install-system-wide )
# rvm install 1.8.7

RubyでのUUIDのversion 1の使い方。

gem install uuid
>> require 'rubygems'
=> true
>> require 'uuid'
=> true
>> UUID.new
=> MAC: 58:55:ca:f3:26:47  Sequence: 9499
>> UUID.new.generate
=> "bc66c930-22f1-012e-251b-5855caf32647"
>> UUID.new.generate :compact
=> "be64e03022f1012e251b5855caf32647"

:compactはハイフンを取ってくれる。


How to use UUID Version 1 in Ruby.

:compact option omits the hyphens.

# Gemfile:
gem 'devise'
% bundle
% rails g devise:install
% rails g devise:views
% rails g devise user
% rails g controller home index
% rake db:migrate
# config/environments/development.rb:
Foo::Application.configure do
  # ...
  config.action_mailer.default_url_options = { :host => 'localhost:3000' }
end
# config/routes.rb:
Foo::Application.routes.draw do
  root :to => 'home#index'
  # ...
end
# app/views/layouts/application.html.erb:  
<p><%= link_to 'Sign in', [:new, :user_session]  %></p>                                                                                                               
<p><%= link_to 'Sign up', [:new, :user_registration]  %></p>
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
<%= yield %>
% curl https://github.com/svenfuchs/rails-i18n/raw/master/rails/locale/ja.yml -o config/locales/ja.yml
% curl https://gist.github.com/raw/833169/54d19c523f6a608e732d4e9a6606a6d6cbec7f8e/devise.ja.yml -o config/locales/devise.ja.yml

同じrouteを2回定義する件。

routesも要はRegexpとブロックの配列。でも最初に定義した方が呼ばれるって何か変。こういうものって後に追加した方が呼ばれる設計にする方が自然な気がする。

そこでもしかして同じroutesとか関係なくて、単にファイル内で上から下に書いてく時の優先順位がそのまんまこの設計に反映されてる的な感じなんじゃないかと思ってpassしてみた。

# public/plugin/lokka-unk/lib/lokka/unk.rb:
module Lokka
  module Unk
    def self.registered(app)
      app.get '/' do
        puts 'unk'
        pass
      end
    end
  end
end
% bundle exec ruby lokka.rb
unk
localhost - - [17/Feb/2011:10:41:33 JST] "GET / HTTP/1.1" 200 38183
- -> /

普通にページは表示されつつ、標準出力にunk。予想通りだ。これは擬似beforeみたいにも使えそう。(普通にbefore '/' do ... endした方が良いが。)

sinatraはルールがシンプルだから自由度が高いなあ。

何だか感慨深い。Java(僕のJava知識はJ2SE1.4で止まってる)とかその他の大きめなフレームワークだとChain-of-responsibilityパターンとかいってFilterChainみたいな感じで実装すると思うんだよね。こういうの。

sinatraはちっちゃいからRegexpとブロックのオブジェクトを配列にもってるから単にナメればいいでしょ?みたいな雰囲気。

Filterクラスを継承したクラスを作るとか面倒。Objective-Cだとブロック対応してない環境のためにワザワザdelegate作るのでヘッダも必要だしとか・・・だるいよなあ(ただの愚痴です・・・)

require 'rubygems'
require 'sinatra'

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

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

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

ブログ(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界隈の簡単ルールみたいなものがあったら知りたい・・・。

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

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

同期コミュニケーションが仕事に与える問題は"総量は同じでも小分けにすると質が下がる"というところ。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]

Railsを追いきれる自信が無かったから。Rails文化に引っ張られてアプリが一生完成しない気がしたから。あとアプリとしては問題無いのにベースのRailsのバージョンが低いだけで残念っぽくなってるアプリ(Redmineとか)を見たから。

半年やってみてSinatra面倒クセー!っていっぱいあったけど、(Sinatra本体の)ソースが短いので完全把握できる掌握感は独自のOSS作る上で心強かった。

いつもググってる気がするのでシリーズ。

require 'rubygems'                                                                                                                                               
require 'active_record'                                                         

ActiveRecord::Base.establish_connection(
  :adapter  => 'postgresql',
  :host => 'localhost',
  :username => 'komagata',
  :password => '',
  :database => 'foo',
  :port => 5432
)

class Post < ActiveRecord::Base
end

puts Post.first.name