The Dabsong Conshirtoe

技術系の話を主にします。

dotcloudにRailsをデプロイ

dotcloudが楽しそうなので使ってみました。

アプリケーション作成

cd $HOME/src
rails new myapp

DBはmysql想定です。

dotcloudでアプリケーション作成

dotcloudにでサインアップしてください。

サインアップしたらダッシュボードでcreate a new applicationしてください。
アプリケーション名は先程作ったものと合わせてmyappとします。

セットアップ

cd $HOME/myapp
dotcloud setup

以下の様なmyapp/dotcloud.ymlを$HOME/myappに作成します。

www:
    type: ruby
    approot: app
    postinstall: ./postinstall.rb

db:
    type: mysql

postinstallはインストール後に実行されるスクリプトです。配置はapp下。
なくても良いです。

ビルド

dotcloud connect myapp
dotcloud push

簡単!
無料枠で色々できそうなのでお遊びにはもってこいですね。

SQLアンチパターン「ランダムセレクション」の補足(でもないけど)

解決策③「すべてのキー値のリストを受けとり、ランダムに 1 つを選択する」では、当然の話だけどトランザクションの考慮も必要ですよねって話。なんだか書いてて当たり前すぎて消そうかと思ったけどもったいないので公開します笑

例えば以下のような手順をとるとする。
(execute_queryはクエリを実行して結果セットを良い感じに取得するメソッドを想像してください)

ids = execute_query(u'SELECT bug_id FROM Bugs;')
target_id = random.choice(ids)
record = execute_query(u'SELECT * FROM Bugs WHERE bug_id = %d;' % target_id)

この場合、target_idのレコードを3行目実行前に別のプロセスにより削除された場合はrecordを取得することができませんので、アプリケーション側でrecordが取得できないことを考慮できていない場合に思わぬ例外に繋がり得ます。

これを防ぐために、取得できなかった場合は後続の処理を実行しない、または例外を投げるなどの配慮が必要ですね。

基本的なことですがこういう考慮が抜けるとバグにつながるので気をつけましょう。>自分

SQLアンチパターン

SQLアンチパターン

pythonの日時系操作まとめ

プログラミングをしていれば、日時系の操作をする機会ってかなり多いですよね?
何日前を計算したり、文字列を日時オブジェクトにしたりその逆をしたり、曜日や月末日が欲しかったり。

自分が忘れっぽいのか、この辺の操作はすぐ忘れてしまい何度もググってしまうので、自戒の念も込めてまとめておきます。
バージョンは2.6。

datetimeの加算減算

# 現在日時から1日進める
datetime.datetime.now() + datetime.timedelta(1)

# 現在日時から1時間戻す
datetime.datetime.now() - datetime.timedelta(hours = 1)

dateをdatetimeに変換

d = datetime.date.today(2012, 12, 12)
t = datetime.time(12, 12, 12)
datetime.datetime.combine(d, t)

datetimeをdateに変換

dt = datetime.datetime.now()
dt.date()

エポックからの経過秒数をdatetime(ローカル)に変換

utc = time.time()
datetime.datetime.fromtimestamp(utc)

datetimeをエポックからの経過秒数に変換

now = datetime.datetime.now()
timetuple = datetime.datetime.timetuple(now)
int(time.mktime(timetuple))

月末日を求める

youbi, end_of_month = calendar.monthrange(year, month)
datetime.date(year, month, end_of_month)

日付が属する曜日を求める

# ※曜日を表す数値はcalendarの定数として定められている(calendar.SUNDAYなど)
datetime.date.today().weekday()

日付が属する週の初日を求める

# 週の初日を日曜日と仮定
d = datetime.date.today()
weekday = d.weekday()
if weekday == calendar.SUNDAY:
    return d
else:
    delta = datetime.timedelta(7 - (calendar.SUNDAY - weekday))
    return d - delta


とりあえずこの辺で。

へび年なのでpythonで占い

あけましておめでとうございます!

今年はへび年なのでpythonで占いしてみますね。

>>> import random
>>> print random.choice([u'大吉', u'中吉', u'マジ吉', u'', u'大凶'])
中吉

悪くないですね!
今年もよろしくお願いします。

PythonのGood Parts

pythonを使い始めて1年半ほどになります。

ここらで、pythonの良いと感じたとこをまとめてみよう。

1. リスト内包表記

リスト内包表記とは、以下のようなものです。

# 通常のリスト生成
r = []
for i in range(100):
    r.append(i)

# リスト内包表記
r = [i for i in range(100)]

良いと思うとこを箇条書き。

  • 簡潔で直感的。
  • 素のforループと違い、ループ処理がインタープリターにより最適化されるのでループ速度も向上します。(「Learning Python」では、"often roughly twice as fast"とあります。)
  • 抽出条件や抽出した要素に対する処理を記述できる。

例えば、

# 対象のリストから3以上の値を取り出して2倍して新たなリストを作る
r = [i * 2 for i in target if i >= 3]

# これを素のfor文で書くとコードブロックが2段階発生して雑多な感じになります。
r = []
for i in target:
    if i < 3:
        continue
    r.append(i * 2)

なお、pythonにはリストの各要素に関数を適用するmap関数や、ある条件の要素抽出するfilter関数もあります。

# 全ての文字にord関数を適用
r = map(ord, 'spam')
# リスト内包の場合
r = [ord(c) for c in 'spam']

# 3で割り切れる値を取り出す
r = filter(lambda x: x % 3 == 0, range(10)) 
# リスト内包の場合
r = [i for i in range(10) if i % 3 == 0]
  • ネストしたfor文も可能。(ただしやりすぎると可読性を損なう。)
# ネストしたfor文を内包表記
nested = [x + y for x in 'spam' for y in 'SPAM']

# 素で書くとこう。
nested = []
for x in 'spam':
    for y in 'SPAM':
        nested.append(x + y)

リストではなくジェネレータが欲しい時は()で囲みます。(リスト内包表記とは言わないけど)

g = (i ** i for i in range(10))

2. キーワード引数

元々Java使いだったのですが、これはかなり感動しました。
キーワード引数とは、関数に渡す引数を "keyword = value" の形で渡せる機構です。

def f(x, y, z):
  ...
f(x=2, y=4, z=5)
# 順序を崩すことも可能
f(y=2, z=3, x=5)
# dictを展開して渡すことも可能
args = {"x":2, "y": 3, "z": 4}
f(**args)

これ、何が良いってコードの可読性が増す点だと思います。
上記の関数のように引数が3個以上ある関数だと、どの位置がどの引数と対応づけられているか確認するのがなかなか手間だったりしますし、うっかり位置を間違えてしまうこともあります。
キーワード引数の仕組みを使えば、順序を気にすることもないですし初めてコードを読む人にとっても何を渡しているかわかりやすいコードになります。

デフォルト引数

またキーワード引数では以下のように、引数のデフォルト値を設定できます。

def load_users_by_type(user_type, max_results=100):
  ユーザーをuser_typeで絞ってid順にDBから取得する処理

# 呼び出し側は、max_resultsなしで呼べる。
users = load_users_by_type(1)

# max_resultsを変動させたい場合
users = load_users_by_type(1, max_results=200)

max_resultsが大抵の場合は100だが、特定のケースでは200取りたい、というような場合に便利です。

それ以上に便利なシチュエーションが、メソッド引数の変更時。

例えば、load_users_by_typeメソッドにソートキーを指定したくなったとします。

キーワード引数が無い言語ならば、load_users_by_typeに引数を追加すると呼び出し箇所全てに修正が入ることになります。
それを避けるためにsort_key引数を加えたラッパーメソッドを作るというのもイマイチな気がします。

しかし、キーワード引数があるとload_users_by_typeの引数を、他の呼び出し箇所を気にせず変えられます。

def load_users_by_type(user_type, max_results=100, sort_key='id'):

まぁメソッド引数がそう簡単に変更されないような設計をするのが望ましいのですが、そううまくはいかないので、キーワード引数は非常に助かります。
キーワード引数はRuby2.0でもサポートされるみたいですね(デフォルト値の仕組みはすでにありますが)。

Learning Python

Learning Python

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

DevLove2012に行ってMyTDDを見直そうと思った

DevLove2012に行って来ました。
登壇者の皆さん、スタッフの皆さん、参加者の皆さんお疲れ様でした!

さて、2日間ぶっ通しでたくさん中身の濃いセッションが行われましたが、僕にとって今回のDevLoveは自分がやってきたTDDを見直すきっかけとなりましたので、覚書としてブログに起こしておきます。

TDDとの出会い

僕が開発でTDDを取り入れるようになったのは今年の9月。
当時テストというと、単体すっとばして結合をやったりしてました。単体テストもせいぜいインタプリタでちょろっと動かす程度でした。
(それでも大きな問題なく開発できてましたが)

ところで、僕には以前から「美しいコードを書きたい」という思いがあります。
リファクタリングが美しいコードを書く有効な手法だと感じているのですが、風の噂で「TDDをやるとリファクタリングがやりやすくなる」みたいな話を小耳に挟んだので、試しにケント・ベック本を読んでみて、「これは良さげ!」と感じTDDを取り入れてみました。
確かにテストがあればリファクタの結果デグレしてないってことを保証できるので、コードを綺麗にするスピードと既存のコードに手を入れる安心感が高まると感じたんです。

My TDD

私のやったTDD。
早速テストファースト原則を破ります。なぜなら、「テストでリファクタをやりやすくしたい」っていう目的なら初めにテスト書く必要なんてないと思ったからです。リファクタしよう!って思ったときにその箇所のテスト書けば済む話ですから、順序なんてどうでも良いって思ってました。
勿論、テストを最初に書くことでインターフェースが洗練するって話も本では読みましたが半信半疑でした。

My TDDの結果・・・

期待通り、リファクタが捗りました。インタプリタで手打ちして確認してたのが馬鹿らしくなりましたね。
ただ、テストが書きづらいケースなんかも出てきて、これは設計が汚いか、テストが書きやすくない設計か、その両方かって疑問を持ったのが最近です。
テストが書きづらいとリファクタが進みません。テストのメンテナンスコストも高まります。テストを書きやすくするにはテストを先に書くのがよさそうだ。これはテストファーストってやっぱ大事かもと思ったわけです。

DevLoveで語られたTDD

さて、今回のDevLoveでは以下の3つのTDD関連セッションに参加しました。

  1. 「テストに開発をもっと駆動させたい」(諸橋恭介さん)
  2. 「世界を少しだけ前に動かすということ」(和智右桂さん)
  3. 「愛せないコードを書くには人生はあまりにも短い」(和田卓人さん)

それぞれのセッションで感じたことを簡単にまとめます。

諸橋さんのセッション

印象的だったのは、「テストは将来のための高い保険料を払うようなものではない」ってとこ。「テストによるリファクタのしやすさ向上や品質向上は副次的効果」とバッサリでした。
自分はTDDはリファクタありきだと思っていたのでちょっとショック。諸橋さんは、テストをまさに今現在の開発を駆動させるために使ってるんだなと感じました。

講演資料
devlove2012-let-yor-test-drive-dev-more // Speaker Deck

和智さんのセッション

GOOSという本の訳本(実践テスト駆動開発)を出したそうで、ケント・ベック本に続くバイブルとか言われてるそうです。
モックについて語らてるらしいです。モックってすげー便利だけどなんだかうまく使えてない感が激しかったので(モック差し込み周りのコードがゴチャゴチャしやすい)、藁をも掴む思いで読んでみようとおもいます!
(「モックは設計の手法として価値がある」ようなことも仰ってましたので余計に気になりました)

講演資料
世界を少しだけ前に進めるということ

和田さんのセッション

プログラミングの楽しさの源泉は動いたときの喜び。それを思い起こさせてくれる技術としてTDDが有効だとの事。確かに。
このセッションでは、Unix、REST、SQLといった長年生き残ってきた技術から学ぶ、という話が印象的でした。
これらの技術群に共通することは以下であると仰ってました。

  • 少ないインターフェース
  • 実装に依存しない
  • 再利用が時間を跨いでいる

この特徴の結果、以下の事が学べます。

  • シンプル、それぞれのモジュールが直交している
  • クリーンでリーダブル
  • 力技ではなく必要な抽象度、穏当なコード

講演資料
愛せないコードを書くには人生はあまりにも短い

これからのMy TDD

これらのセッションから感じたことは、TDDはリファクタをやりやすくしたり品質を保証するだけでなく、設計を美しする、更には仕事を楽しくするっていう力を秘めてるんではないかということです。
今自分がやってるTDDは、「テスト駆動開発」というか「テスト駆動リファクタリング」であったわけです。話を聞くに、テストを書くことが、どんな設計にするか考える事にも役立つというのは本当っぽいので、とりあえず愚直にTDDの原則(テストファースト)に立ち返ってコードを書いてみたいと思います。「守破離」の「守」って大事ですね。

テスト駆動開発入門

テスト駆動開発入門

  • 作者: ケントベック,Kent Beck,長瀬嘉秀,テクノロジックアート
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2003/09
  • メディア: 単行本
  • 購入: 44人 クリック: 1,022回
  • この商品を含むブログ (154件) を見る

実践テスト駆動開発 テストに導かれてオブジェクト指向ソフトウェアを育てる (Object Oriented SELECTION)

実践テスト駆動開発 テストに導かれてオブジェクト指向ソフトウェアを育てる (Object Oriented SELECTION)

Backbon.jsのextendの仕組み

Backbone.js Advent Calendarの13日目を担当しますAttsun_1031です。普段はpythonとjs使ってます。

Backbone.js使いでもないんですが、javascriptでコード再利用のパターンを検討している時にBackbone.jsのextendがヒッジョーに参考になったので、その仕組みについて書きます。(バージョンは0.9.2)
どうでも良い話ですが、python(ニシキヘビ)って背骨あるんでしょうか。

extendって?

新しいクラスを定義するために使います。extendの引数に渡したオブジェクトがそのクラスのインスタンスのメンバーになります。第2引数に渡したオブジェクトはクラスの静的なメンバーになります。利用例は以下。

// Personクラスを定義する
var Person =  Backbone.Model.extend({
  // initializeはBackbone.jsで規定されている初期化処理で、newした時に呼ばれます。
  initialize: function(name, age) {
    this.name = name;
    this.age = age;
  },

  say: function() {
    return "I am " + this.name;
  }
}, {
  TYPE: "Mammal"
});

// Personのインスタンスを生成
var me = new Person('Attsun_1031', 26);
console.log(me.say());
> 'I am Attsun_1031'
console.log(Person.TYPE);
> 'Mammal'

本来、プロトタイプベースのオブジェクト指向言語であるjsにはクラスやインスタンスといった概念が存在しないのですが、Backbone.jsではそれをエミュレートすることでコード再利用の方法を提供しています。
もちろん、こんな仕組みなくてもコード再利用は可能なんですが、クラスベースOOPに慣れてる人が圧倒的に多いからこうしてるんでしょうかね。
私もJavaPythonのようなクラスベースのOOPを触っているのでクラス・インスタンスという概念があるほうが書きやすいです。

extendの仕組み

では本題に戻ってextendのソースコードを見ながら仕組みを紐解いていきます。

  var extend = function (protoProps, classProps) {
    var child = inherits(this, protoProps, classProps);
    child.extend = this.extend;
    return child;
  };

これがextendのコードです。
protoPropsというのがインスタンスメンバー、classPropsというのがその名の通りクラスの静的なメンバーです。
動作は、inherits関数を呼んでchildを生成し、そのchildにextendメソッドを設定して返します。
これは、サブクラスから更なる継承を可能にするためです。

終わり。

・・・

ではなくて、肝心のinheritsメソッドの中身を見てみましょう。もとのコードからコメントを削除し、番号を振ってます。

  var ctor = function(){};

  var inherits = function(parent, protoProps, staticProps) {
    // 1
    var child;

    // 2
    if (protoProps && protoProps.hasOwnProperty('constructor')) {
      child = protoProps.constructor;
    } else {
      child = function(){ parent.apply(this, arguments); };
    }

    // 3
    _.extend(child, parent);

    // 4
    ctor.prototype = parent.prototype;
    child.prototype = new ctor();

    // 5
    if (protoProps) _.extend(child.prototype, protoProps);
    if (staticProps) _.extend(child, staticProps);

    // 6
    child.prototype.constructor = child;

    // 7
    child.__super__ = parent.prototype;

    return child;
  };

1. 戻り値となるchildを定義します。これがサブクラス(コンストラクタ関数)です。こういう長い関数において、冒頭に戻り値を定義するのは良いプラクティスですね。


2. protoPropsに 'constructor' という名前の関数がある場合、それをchildにセットします。そうでない場合は、child自身をthisとしてparent関数を呼ぶ関数をセットします。parent関数はextendを呼んでいる関数なので、冒頭の例でいえばModel関数がコールされたことになります。
Model関数の詳細は省きますが、内部でthis.initialize.applyをコールしています。つまり、constuructorの指定がなければinitializeが必ず呼ばれる、ということになります。


3. これはBackbone.jsが依存しているunderscore.jsのextendを呼んでいる(と思われます)。childにparentのプロパティ(メソッドとか)をコピーしているのです。


4. inheritsの上で定義しているctorという空の関数にparentのprototypeをセットし、childのprototypeにはそれをnewしたものをセットします。
単純にparentのインスタンスをprototypeとしてセットしたいだけなら

child.prototype = new parent();

とやってしまえば良いのですが、これだとparentのインスタンス固有の変数(parent関数内でセットされる値)をchildが受け継いでしまいます。
やりたいのは、parentのプロトタイププロパティのみ継承することなので、空の関数にprototypeをコピーし、それをnewすることで解決しています。

この辺の話を理解するにはプロトタイプチェーンの理解が欠かせません(私も最近学びました)。オライリーの「JavaScriptパターン ―優れたアプリケーションのための作法」が非常に参考になります。この一時的なコンストラクタのテクニックの他、コード再利用パターンが色々書いてあるのでオススメです。


5. child.prototypeにprotoPropsをコピーします。これが所謂インスタンスメンバーになります。また、childそのものにstaticPropsをコピーすることで、Child.HOGEHOGEのような呼び出しができる静的メンバーをセットします。


6. child.prototypeのconstructorにchild自身をセットします。このconstuructorは2で出てきたconstuructorとは別物で、javascriptのあらゆるオブジェクトが持つプロパティです。これをしないとconstructorがparentのままになってしまうので設定しています。


7. __super__にparent.prototypeをセットします。こうすることで子クラスの中で以下のように親のメソッドを呼ぶことが可能になります。

Child.__super__.parentMethod.apply(this, some_args);


以上です。
extendはクラスベースOOPにおける継承をエミュレートしていますが内部ではプロトタイプの仕組みを使っているので、非常に勉強になりました。

JavaScriptパターン ―優れたアプリケーションのための作法

JavaScriptパターン ―優れたアプリケーションのための作法