jshint v2.5.x 以降で、以下のようなコードを書くと、jshintさんに叱られます:
var Promise = require('bluebird');
そんな時は、.jshintrc
ファイルに以下の項目を追記しましょう:
{
"predef": [ "-Promise" ]
}
jshint v2.5.x 以降で、以下のようなコードを書くと、jshintさんに叱られます:
var Promise = require('bluebird');
そんな時は、.jshintrc
ファイルに以下の項目を追記しましょう:
{
"predef": [ "-Promise" ]
}
出来ないと思い込んでいたらすごく簡単に出来たのでご紹介。
操作としては、 iPhoneのホーム画面でアプリをグループ化するのと全く同じ方法 で出来ます!
Evernote公式のビデオがわかりやすかったので、ご覧ください。
キャプチャから方法をかいつまんで説明します。
グループ化したいノートブックをクリックしたままマウスを動かして、別のノートブック上で指を離します(ドラッグ&ドロップ)。
すると、2つのノートブックがグループ化されて一つになります。
グループを2回クリックすると、中身が展開されて、グループ化した2つのノートブックが表示されます。簡単ですね!
Evernoteでは、このグループのことを スタック(Stack) と呼んでいます。
Googleなどで検索する際にはStackと打つと情報が見つけやすいと思います。
昨日の深夜に、MongoDB v2.8.0-rc0(Release Candidate) がunstableでリリースされました。Stable releaseまでいよいよ秒読み開始です。
個人的にアツイのは「Improved Concurrency」なので少し説明します。
待ちに待ったdocument-level lockingです。
MongoDBは書き込みが弱い事が自分の中で有名(笑)ですが、それが大幅に改善されます。
MongoDB 2.6(stable)では、データベースレベルの書き込みロックです。
つまり、あるデータベースのコレクションに対して書き込みを行っている間は、同じデータベースのどのコレクションに対する読み書きもできないということです。
これがドキュメントレベルになることによって、同一のドキュメント以外なら読み書きできるようになる、という事です。
下図は、カンファレンスでのデモンストレーションの様子のキャプチャです。
同時に複数のクライアントが書き込みオペレーションを実行しています。
赤いグラフで縦軸が書き込み数です。左側の小さい山がdb-level lockingで、右の大きな山がdoc-level lockingです。
書き込みパフォーマンスが大幅に改善している事がわかります。
昔は書き込みロックはグローバルだったのを考えると、やっとまともに使えるようになったなぁという感じです。
MongoDBのストレージエンジンはあんまり性能が良くない事で評判なんですが、プラッガブルになった事でMySQLみたいに付け替え可能になりました。
これで有志による性能がより高いストレージエンジンの開発が期待されます。
On-dick compressionによってI/O効率が30〜80%よくなるそうです。
さらに詳しい情報は以下をチェックしてください。
koaのソースコード を読んで知ったのでメモ。
JavaScriptではオブジェクトにSetter/Getterを定義できます。
Setter/Getterとは、プロパティの設定時・参照時に呼び出されるメソッドのことです。
一般的には以下のように定義します:
var o = function() {};
o.prototype.__defineGetter__("b", function() { return this.a + 1; });
o.prototype.__defineSetter__("c", function(x) { this.a = x / 2; });
var i = new o();
i.c = 10;
console.log(i.b);
このSetter/Getterは、オブジェクト初期化子を使っても定義できます。
var o = {
a: 7,
get b() { return this.a + 1; },
set c(x) { this.a = x / 2; }
};
var i = Object.create(o);
このように、get
, set
プレフィックスをつけて関数を定義します。
MDNのドキュメント によると、ブラウザ実装状況は以下の通りです:
機能 | Firefox (Gecko) | Chrome | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
基本サポート | 2.0 (1.8.1) | 1 | 9 | 9.5 | 3 |
サポートされていない場合 (特にIE6-8において) 、スクリプトはシンタックスエラーを引き起こします。
今月(2014年10月10日)のことですが、Amazon DynamoDBがいろいろアップデートしました:
その中でもJSONデータサポートは注目のアップデートです。
これは具体的にどういうことか説明します。
DynamoDBはスキーマレスのNoSQLです。
これまで、カラム(属性)には単一データまたはセット(重複を許さない配列)が格納できました。
しかしながら、入れ子構造は格納できませんでした。
JSONデータのサポートとは、この入れ子構造が取り扱えるようになったということです。
つまり、MongoDBのように、JSON形式のデータをそのままデータベースに格納できるようになったのです。
node.js向けのODMライブラリにはいくつかあります。
vogels はその中でもいい感じのライブラリです。
しかし残念ながら、あまり精力的にメンテナンスされてるとは言いがたく、今回のアップデートに対してもまだ対応していない様子です。
そこで、自分で対応させてみることにしました。
フォークしたものがこちらにあります:
いちおうプルリクしてありますが、マージされるのを待てません笑
まずは基本的な使い方をドキュメントから引用してざっくり説明します。
次に、入れ子構造のデータを扱うための方法を説明します。
AWS SDKのキーをファイルから設定します。
var vogels = require('vogels');
vogels.AWS.config.loadFromPath('credentials.json');
もちろん直接値を渡して設定もできます。
var vogels = require('vogels');
vogels.AWS.config.update({accessKeyId: 'AKID', secretAccessKey: 'SECRET'});
データモデルの定義方法は以下のとおりです:
var Account = vogels.define('Account', function (schema) {
schema.String('email', {hashKey: true});
schema.String('name').required(); // name attribute is required
schema.Number('age'); // age is optional
schema.Date('created', {default: Date.now});
});
ハッシュとレンジキーを指定しての定義:
var BlogPost = vogels.define('Account', function (schema) {
schema.String('email', {hashKey: true});
schema.String('title', {rangeKey: true});
schema.String('content');
schema.StringSet('tags');
});
書き込み:
Account.create({email: 'foo@example.com', name: 'Foo Bar', age: 21}, function (err, acc) {
console.log('created account in DynamoDB', acc.get('email'));
});
読み込み:
Account.get('test@example.com', function (err, acc) {
console.log('got account', acc.get('email'));
});
簡単ですね!
クエリやセカンダリインデックスなどの使い方はドキュメントを参照してください。
ここからが本題です。
DynamoDBでは、MapとListという新しいデータ型を追加することで入れ子構造の格納を実現しています。
先述の通り、vogelsではスキーマを定義して、それに合わせたデータを出し入れします。
vogelsで入れ子構造を取り扱うには、このスキーマをMapとListを使用して定義します。
MapはJavaScriptでいうオブジェクトです。まずは以下の例をみてください。
var Photo = vogels.define('Photo', function (schema) {
schema.String('userid', {hashKey: true});
schema.Map('location');
});
Photo.create({userid:'john', location: {name: "東京タワー", latitude:35.65858, longitude: 139.745433}}, console.log);
この例では、Photo
モデルのlocation
属性がMap
型として定義されています。
中身には、場所に関するデータが格納されています。
単純ですね!
もちろん、このlocation
の中身もスキーマで定義できます。
var Photo = vogels.define('Photo', function (schema) {
schema.String('userid', {hashKey: true});
schema.Map('location', function(schema) {
schema.String('name');
schema.String('latitude');
schema.String('longitude');
});
});
Mapの中に更にMapを格納することもできます。
Mapの中身のスキーマを定義しなかった場合、未定義となり制約は与えられず、自由なフォーマットのデータが格納できます。
ListはJavaScriptでいう配列です。使い方は以下のとおり。
var Photo = vogels.define('Photo', function (schema) {
schema.String('userid', {hashKey: true});
schema.List('likes');
});
Photo.create({userid:'john', likes: ['emily']}, console.log);
こちらも直感的ですね。
Listの各要素の形式が同じで尚且つMap型の場合は、以下のように要素のスキーマを定義できます。
var Photo = vogels.define('Photo', function (schema) {
schema.String('userid', {hashKey: true});
schema.List('likes', function(schema) {
schema.String('userid');
schema.Date('likedAt');
});
});
JSON形式のドキュメントがそのまま格納できるDBMSとして、有名なのはMongoDBです。
今回のJSONサポートによって、DynamoDBはMongoDBと同じフォーマットでデータを取り扱えるようになりました。
これは、「併用しやすい」という事です。
併用すると何が嬉しいか、考えてみます。
DynamoDBは運用コストが低くスケーラビリティが高いのがウリのデータベースです。
その代わり、検索の柔軟性を犠牲にしています。
それに対してMongoDBは検索の柔軟性が高いのが強みです。
しかしながら、DaaSは価格が高いし自分で運用するのは大変です。
DynamoDBとMongoDBを併用することによって、互いの弱みを補い合えるかもしれません。
MongoDBを既に使っていた人にとっては、すごい良いニュースではないでしょうか。
iPhotoである問題に数年間苛まれていて、ずっと解決じまいでした。
それは、iPhotoを使っていて一旦Finderなど別のアプリに切り替えてからまたiPhotoへ切り替えた時、どの画面を表示していようと強制的に「最後の読み込み(英語だと”Last Import”)」画面に遷移してしまうというものです。
「最後の読み込み」画面とは、iPhoneやiPadから最後に取り込んだ写真の一覧を表示する画面です。
僕の場合、以下の手順で解消しました:
iPhoto Library
があるフォルダを開く(通常は ホーム > 写真)フォルダの中身ですが、Finderだと隠しファイルが表示されません。
隠しファイルを削除するには、「ターミナル」を起動して以下のコマンドを打ち込みます。
$ cd "iPhoto Libraryへのパス"
$ ls -la "Auto Import/"
$ rm "Auto Import/.*"
これで無事直りました。よかったよかった!
Locate your iPhoto Library ? in home > Pictures.
Bring up the contextual menu on iPhoto Library and select Show Package Contents.
Locate the “Auto Import” folder and open it.
Remove its contents ? which probably consist of empty folders or other stuff that can’t be imported.
Appleから受け取ったクラッシュログは、クラッシュした状態のスタックトレースをバイナリ上のアドレスで示されています。
このままだと、内容を見てもソースコード上のどこが悪いのかさっぱり分かりません。
シンボリケートとは、主にバイナリ上のアドレスからソースコードの場所を突き止める事をいいます。
クラッシュログのシンボリケートにはsymbolicatecrash
コマンドを使用すると便利です。
XCode 6では以下のパスに存在しています。
/Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash
/usr/bin
あたりにシンボリックリンクを貼っておくと吉。
クラッシュログを吐いたバイナリと同じビルドのもので、以下が必要です:
XCodeのOrganizerを開き、アーカイブ一覧から該当のビルドを探します。
次に、該当ビルドの項目を右クリックしてShow in Finder
します。
開かれたディレクトリに、上記二つのファイルが存在します。
以下のように実行します。
export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
symbolicatecrash -v crashファイル dSYMファイル appファイル
DEVELOPER_DIR
を予め設定しておかないと、以下のようなエラーが出ます。
Error: "DEVELOPER_DIR" is not defined at /Applications/Xcode.app/[snip]Resources/symbolicatecrash line 53.