Node.js日誌β

あいつの日誌です。

2012-05-16

mongodの罠

こんな感じで mongodにマスタデータを投入する約束をしているときに

mongoimport -d my_test_database -c MyTestTable myTestTable.json

こんな感じで既に存在しているidがあるのにそれを修正しないでマスタデータを追加してしまった場合

{ "_id" : "hoge", name:'fuga' }
{ "_id" : "hoge", name:'fugafuga' } // 追加した人はこれが反映されると信じている。

何故か次のような結果になりお昼ごはんを食べ損ねる人がでてきたりするので諸卿も気をつけるとよい。

% mongo
MongoDB shell version: 2.0.2
connecting to: test
> show dbs
local   (empty)
my_test_database        0.203125GB
...

> use my_test_database
switched to db my_test_database

> show collections
MyTestTable
system.indexes

> db.MyTestTable.find()
{ "_id" : "hoge", "name" : "fuga" }

とりあえず2.0.2の話。他のバージョンの事は知らない。

2012-04-26

javascript の オブジェクトが空かどうかを調べる場合

javascript の配列はこんな感じで空かどうかを判定できたりします。

var array = ['fuga', 'moga'];

console.log(array.length > 0); // true

で、オブジェクト(Perlでいうとhash)のプロパティが一個以上あるかどうかを調べたい場合は
for in 使うのなんかやだなので調べたらこういう書き方ができたっていう話。

var hoge = { 
    fuga: 1,
    moga: 2,
};

console.log(Object.keys(hoge).length === 2); // true

ひさびさに書いた記事がこんなのでごめん。

2012-03-07

勝手に添削をこっそり添削

404なお方の「勝手に添削」をこっそり添削してみた

元のコード

    my $result_text = '';
    for my $word ( @{ $ma_result->{word_list} } ) {
        if ( $word->{pos} eq '動詞' ) {
            $result_text .= "全裸で$word->{surface}";
        }
        else {
            $result_text .= $word->{surface};
        }
    }
    return $result_text;

404なお方の添削結果

for my $word ( @{ $ma_result->{word_list} } ) {
    $result_text .= '全裸で' if $word->{pos} eq '動詞';
    $result_text .= $word->{surface};
}

で、おれならこーする。

sub zenrize {
    ...(中略)...
    return join '', map { _zenrize($_) } @{ $ma_result->{word_list} }
}

sub _zenrize {
    return $_[0]->{pos} eq '動詞' ? '全裸で' . $_[0]->{surface} : $_[0]->{surface}; 
}

どうだろう?ムケているだろうか?

2012-03-02

node.js でイケてる form-validator モジュールを探せ

あらすじ

form-validatorでいけてる感じのモジュールが欲しい

とりあえず検索

validator で検索するといくつかのモジュールがヒットする

% npm search validator
...(中略)...

上記から以下の順番で抽出。

  • githubのアカウントを持っている
  • フォロワー数が2桁以上

以下、結果。フォロワー数/ウォッチされている数

piton-validity は今回除外して残りを順番に見てみる事にします。

express-form

req.paramsから値を取得する前提なら良いかもしれない。チェックしたい値の受け渡しをreq.paramsでやっている場合は後述のvalidatorではなくこちらを使う選択肢もなきにしもあらず。

JSV

json の構造をチェックするモジュールのような印象を受けます。ちょっとインターフェース見た感じ使っててうれしい感はあんまり無いかもしれません。

validator

これが一番まともだと思います。ただしデフォルトで例外処理を投げるのでform-validatorとしての挙動で違和感を感じます。まあ個人差があると思いますが、そもそもform-validatorという名前空間でもないか。

READMEには以下の記述でエラーメッセージをスタックさせる事ができると書いていますので例外を投げるのに違和感がある場合はそうする事もできるので各自の好みで。

Validator.prototype.error = function (msg) {
    this._errors.push(msg);
}

Validator.prototype.getErrors = function () {
    return this._errors;
}

var validator = new Validator();

validator.check('abc').isEmail();
validator.check('hello').len(10,30);

var errors = validator.getErrors(); // ['Invalid email', 'String is too small']

「Invalid email」というエラーメッセージを日本語化したい場合はどうすればいいのかは現時点では私は不要なので追求していません。

まとめ

とりあえず以下のようなコードを書く場合、私だったらvalidatorをラップして使うんじゃないかなあ。

var myValidator =  new MyValidator(); 

var errMsgs = myValidator.checkMyCode('my-xxxxx');

if (errMsgs) {
	...
}

追記

npm search コマンドが何故か微妙なので http://search.npmjs.org/ を使った方がいいよという話を聞いたのでそちらで検索したところ amanda というモジュールも見つかりました。

モジュール探す場合はこちらのサイトを利用すると良い、という結果を得た。

2012-03-02

preview テスト駆動開発のススメ

preview テスト駆動開発のススメ

hachiojipm#14に行ってきました。そこでテスト駆動開発のハンズオンをしたいという話をしてきました。
というわけで実際にどんな事をやろうとしているのか、というのをお知らせです。

まあ単純なWebアプリを作りながらテストを書いていくハンズオンみたいな事をすると思います。

雛形作成

% module-setup MyApp
% cd MyApp

MyApp/lib 以下を Perl Module である事を認識できるようにしておきます。

% PERL5LIB=$HOME/project/MyApp/lib:$PERL5LIB

Data::Model

ディレクトリ作成

% mkdir -p lib/Collection 

製品モデルを用意します。

% vi lib/MyApp/Product.pm
package MyApp::Product;
use strict;
use warnings;

my @products = ( 
    {   
        id => 1,
        name => 'Mac Book Pro',
        description => 'Apple 13 inch Mac Book Pro Notebook',
        price => 1000,
    },  
    {   
        id => 2,
        name => 'iPad',
        description => 'Apple 64GB 3G iPad',
        price => 899,
    }   
);

1;

テストを作成します。

% vi t/product.t
#!/usr/bin/env perl
use strict;
use warnings;
use Test::More;
use MyApp::Product;

subtest 'get all products' => sub {
    my @products = MyApp::Product->all();
    ok(scalar @products == 2); 
};

subtest 'find product' => sub {
    my $product = MyApp::Product->find(2);
    ok($product->{name} eq 'iPad');
};

done_testing();

テスト実行

もちろん失敗

% prove
t/00_compile.t .. ok   
t/product.t ..... 1/? Can't locate object method "all" via package "MyApp::Product" at t/product.t l
ine 8.
...

実装

メソッドを追加

package MyApp::Product;
use strict;
use warnings;

my @products = ( 
    {   
        id => 1,
        name => 'Mac Book Pro',
        description => 'Apple 13 inch Mac Book Pro Notebook',
        price => 1000,
    },  
    {   
        id => 2,
        name => 'iPad',
        description => 'Apple 64GB 3G iPad',
        price => 899,
    }   
);

sub all { return @products; }

sub find {
    my ($class, $id) = @_; 

    for my $product ( $class->all ) { 
        if ( $product->{id} == $id ) { 
            return $product;
        }   
    }   
    return;
}

1;

テスト実行。成功

:! prove -vl t/product.t                                                          
t/product.t .. 
    ok 1
    1..1
ok 1 - get all products
    ok 1
    1..1
ok 2 - find product
1..2
ok
All tests successful.
Files=1, Tests=2,  1 wallclock secs ( 0.06 usr  0.02 sys +  0.04 cusr  0.01 csys =  0.13 CPU)
Result: PASS

まとめ

実際に私がテストを書くのでそのテストに成功するように実装してもらってテスト駆動開発を体験してもらおうかなあと思っています。

という事で興味がある人は遊びにきてね。

テスト駆動開発のススメ

3/17でなくても近くに寄ったら是非お立寄りください。

2012-02-07

Node.jsのセットアップ備忘録

Node.jsのセットアップ備忘録

環境

% sw_vers
ProductName:    Mac OS X
ProductVersion: 10.6.8
BuildVersion:   10K549

nvm を導入する

nvm は Node Version Manager の略です。

% cd ~/project
% git clone git://github.com/creationix/nvm.git

nvm へのエイリアスを張る

% ln -sf $HOME/project/nvm $HOME/.nvm

直接 $HOME/.nvm に git clone してもよいと思うのですが、私はなんとなく $HOME/project に node を置きたかったのでこうしました。

zshrc の設定

この状態だと nvm コマンドを発見できません。

% which nvm
nvm not found

次のようにすると nvm が見つかるようになります。各自で zshrc などに記述しておくと良いでしょう。

% source $HOME/.nvm/nvm.sh

ただし、この状態だと node と npm が見つかりません。

% which node
node not found
% which npm
npm not found

以下のコマンドを実行するとよいです。

% nvm ls > /dev/null
% nvm sync > /dev/null
% nvm use defaults > /dev/null

こうすると node と npm の場所を知る事ができます。

% which node
/Users/okamura/.nvm/v0.6.10/bin/node
% which npm
/Users/okamura/.nvm/v0.6.10/bin/npm

ということで zshrc などに以下を記述しておくとよいです。

source $HOME/.nvm/nvm.sh
nvm ls > /dev/null
nvm sync > /dev/null
nvm use defaults > /dev/null

本当はもっといい方法がある気がしますが分かってないので、どうすればいいのか知ってる人いたら教えて下さい。

おしまい