kidoOooOoooOOom

IT系で開発やってます

mongodbで正規表現でcollectionを指定してremove

mongodbで正規表現を指定して特定のcollectionsだけremoveしたいケースがあったので、それのメモ。
コンソールからmongoシェルを立ち上げて下記を宣言し、宣言した関数を実行してあげるとok.

var removeUserCollections = function() {
  var removeTargets = [];
  db.getCollectionNames().forEach(function(coll){
    if(coll.match(/^user_*/)){
      removeTargets.push(coll);
    }
  });
  print('remove following collctions');
  print(removeTargets);

  removeTargets.forEach(function(target) {
    db[target].remove();
  });

  print('remove done!');
};

レベルアップのゲームデザイン 読書メモ LEVEL4

「レベルアップ」のゲームデザイン ―実戦で使えるゲーム作りのテクニック

「レベルアップ」のゲームデザイン ―実戦で使えるゲーム作りのテクニック

LEVEL4 ゲームデザインドキュメント

ゲームドキュメントを作成するにあたって重要なガイドラインが示されている章。
もし、自分でドキュメントを作成・確認する機会があれば、またこの章を見直しながら作業をしたい。
ポイントを挙げると下記のような感じ。

  • GDD(Game Design Document)は、ゲームで何が起こるかを正確に説明する十分な長さが必要である
  • デザインは、ワンシート、テンページャー、GDDの順に進める事
  • ワンシートは、ゲーム全体をシンプルに1ページにまとめた概要書である
  • テンページャーはゲームの「全体を大まかに」カバーした概要書で、ゲームの背景となる要素を説明するドキュメントである
  • テンページャーはいかにおもしろく読み易いものにするかが重要
  • GDDでは、1にも2にもとにかくゲームプレイを重視する
  • ゲームデザインは生き物である。常に変化し、絶え間なく流れ、突然変異し、そして進化する

最後に、ドキュメント作成を怠りがちな現場に対して重要な引用

実は、最終的にあなた自身が自分のGDDを読む必要が出てきます。ドキュメントの作成は、チームのメンバーだけでなくあなた自身も助けてくれるのです。「頭の中に」ゲームのアイデアをしまっておこうとすると、把握しておかなければいけないことがあまりに増え、やがてパンクします。そうなると、どんな素晴らしいアイデアだって簡単に忘れてしまいます。

Effective JavaSceipt 読書メモ 項目22~26

第3章 関数の扱い

項目22 可変長引数関数を作るには、argumentsを使う

JSでは、すべての関数に暗黙のうちに提供するローカル変数 argumentsが存在する。このargumentsを使うと、下記のように可変長引数関数を自作できる。

function average() {
  for (var i = 0, sum = 0, n = arguments.length; i < n; i++) {
    sum += arguments[i];
  }
  return sum / n;
}

console.log(average(1,2,3,100)); // 26.5

ただし上記の場合、引数に配列を使いたい場合はapplyメソッドを使わなければならず、クライアント側から使うのに面倒なケースがある。
そこでお勧めされているのが、明示的に配列を受け取る「固定アリティ」関数と、「可変アリティ」の両方を提供することでクライアントの便宜をはかることができる。

// 固定アリティ
function averageOfArray(a) {
  for (var i = 0, sum = 0, n = a.length; i < n; i++) {
    sum += a[i];
  }
  return sum / n;
}

// 可変アリティ
function average() {
  return averageOfArray(arguments);
}

console.log(average(1,2,3,100)); // 26.5
console.log(averageOfArray([1,2,3,100])); // 26.5

項目23 argumentsオブジェクトを書き換えない

argumentsオブジェクトは配列のように見えるが、常に配列のように振る舞うとは限らない。arugmentsオブジェクトは標準Array型ではないため、例えばarguments.shift()を直接呼び出す事ができない。
それでもcallメソッドを用いて配列のsliceメソッドを適用すると、標準Array型のインスタンスにコピーすることができる。

function argsTest() {
  var args = [].slice.call(arguments, 2);
  console.log(args); // 30,40,50
}
argsTest(10,20,30,40,50);

項目24 argumentsへのリファレンスは変数に保存する

iteratorの挙動を期待した関数をargumentsを用いて下記のように実装する。

function values() {
  var i = 0, n = arguments.length;
  return {
    hasNext: function() {
      return i < n;
    },
    next: function() {
      if (i >= n) {
        throw new Error("end of iteration");
      }
      return arguments[i++];
    }
  }
}

しかし、上記のコードは期待した結果を得られない。

var it = values(1,2,3,4,5,6);
console.log(it.next()); // undefined
console.log(it.next()); // undefined
console.log(it.next()); // undefined

これは、argumentsがit.next()の引数をアクセスしてしまっているからである。ネストした関数からargumentsを参照する場合は、values()メソッド内のローカル変数に結合しておく必要がある。

項目25 固定レシーバを持つメソッドを抽出するにはbindを使う

関数について、そのレシーバを特定のオブジェクトに結合(bind)するバージョンを作成する場合、ES5ではbindメソッドを用いればよい。
例えば、普通に呼んでしまうとグローバルオブジェクトをレシーバーにしてしまうforEachメソッドに対し、bufferオブジェクトをレシーバにしたい場合は下記のように書く。

hoge.forEach(buffer.add.bind(buffer));

ただし、bindは新しいadd関数を作成するのであり、buffer.add関数を書き換えるわけではないとのこと。

項目26 関数をカリー化するには、bindを使う

下記のコードは、simpleURLメソッドに対し、paths.mapに無名関数を渡して反復処理させるコードである。

function simpleURL(protocol, domain, path) {
  return protocol + "://" + domain + "/" + path;
}

var paths = ["aaa", "bbb"];
var urls = paths.map(function(path) {
  return simpleURL("http", "hoge", path);
})

console.log(urls); // [ 'http://hoge/aaa', 'http://hoge/bbb' ]

しかし、このコードでは "http"と"hoge"の文字列がどの繰り返しでも同じであり、本当に必要なのは3つ目のpath引数だけである。このようなケースの時、bindを用いてカリー化を行うと効率的に書ける。

var urls2 = paths.map(simpleURL.bind(null, "http", "hoge"));
console.log(urls2); // [ 'http://hoge/aaa', 'http://hoge/bbb' ]

通常のようにbindの第1引数はレシーバの値を提供する。今回の例ではsimpleURL関数がthisを参照しないため、nullかundefinedを使うのが通例となるとのこと。
simpleURLに渡される引数は、simpleURL.bindの引数に新しい関数に対して提供された引数を連結したものになる。つまり、simpleURL("http", "hoge", path)となる。
このように関数に対して、その引数の部分集合を結合させるテクニックはカリー化と呼ばれる。カリー化を使うと、関数の委任を明示的なラッパー関数を使うよりも決まり文句が少ない簡潔な方法で実装できる。

レベルアップのゲームデザイン 読書メモ LEVEL3

「レベルアップ」のゲームデザイン ―実戦で使えるゲーム作りのテクニック

「レベルアップ」のゲームデザイン ―実戦で使えるゲーム作りのテクニック

LEVEL3 ストーリー

人がゲームを遊べば、そこで「物語」ー「こんなことが起こった後に、あんなことが起こった」という出来事の流れーが生み出される。プレイヤーが作り出す物語は無限である。
あるプレイヤーによっての物語は「雑魚敵をひたすら倒してレベルアップした」かもしれないが、別のプレイヤーの物語は「雑魚敵をスルーして低レベルで進んだ」かもしれない。ゲームデザイナーは、起こる可能性があるすべての物語を把握し、どうやったらすべての物語が面白くなるかを考える必要がある。

またストーリー上発生するキャラクターの死は、プレイヤーによって意味のあるものにすると印象に残り易い。例えばFF7のエアリスは多くのプレイヤーにとって心に残っていると思われる。

ゲームにしっくりくるタイトルをつけるのはもちろん、キャラクターにもしっくりくる名前をつけた方がいい。強そうなキャラクターなのに名前が「ぴよこ」とかだとしっくりこない。

レベルアップのゲームデザイン 読書メモ LEVEL2

「レベルアップ」のゲームデザイン ―実戦で使えるゲーム作りのテクニック

「レベルアップ」のゲームデザイン ―実戦で使えるゲーム作りのテクニック

LEVEL2 アイデア

まず印象に残ったフレーズが

よいアイデアとは、ばかばかしく聞こえるものだ

よいアイデアを出すためのヒントとして下記が挙げられている。

  1. いつもなら絶対読まないものを読む
  2. 散歩する。車を運転する。シャワーを浴びる
  3. セミナーに出席する
  4. 出来の悪いゲームをプレイする
  5. 自分の情熱に従う

イデアというのは完全オリジナルなものはもはやほとんど存在しない。
各ゲームのアイデアはそれ以前のタイトルの上に成り立っている。

何かを革新的だと思ったら、それはあなたが周囲に注意を払っていない証拠だ。

という格言もある。

開発者は開発中のゲームを何百回もプレイするため、それがおもしろいかどうかというのは客観的に見る事が難しくなる。そこで、「おもしろい」と思うアイデアから作り始めたものに対し、開発過程で「おもしろくないもの」を見つけたらそれを抹殺すべきという理論が提唱されている。

これから毎日糞仕様を消そうぜ ってことだ。

「レベルアップ」のゲームデザイン ―実戦で使えるゲーム作りのテクニック

「レベルアップ」のゲームデザイン ―実戦で使えるゲーム作りのテクニック

Effective JavaSceipt 読書メモ 項目18~21 高階関数とか

第3章 関数の扱い

項目18 関数、メソッドコンストラクタの、呼び出しの違いを理解する

JSでは、関数・メソッドコンストラクタは全て関数(function)を用いた3種類の利用パターンとしてとらえる。
下記のobjは hello というメソッドを持つ。JSではメソッドは単なる「関数であるオブジェクトプロパティ」にすぎない。

var obj = {
  hello: function() {
    return "hello " + this.username;
  },
  username: 'totakeke'
};

var obj2 = {
  hello: obj.hello,
  username: 'peritutu'
};

console.log(obj2.hello()); // hello peritutu

obj2.hello()の呼び出しの結果、objではなくobj2の username が this参照されている。JSでは、thisに結合される値は、その呼び出しのレシーバと呼ばれる。

thisを使う関数を、メソッドではなく関数として呼び出すのはあまり推奨されない。
下記のコードは、ES5のstrictモードでは this がundefinedに結合されるため、実行時エラーになる。
また、非strcitモードではthisがグローバルオブジェクトになり、byebye undefinedが出力される。

function byebye() {
  return "byebye " + this.username;
}

console.log(byebye());

気をつけるべし。

項目19 高階関数を快適に使えるようになろう

高階関数とは、「ほかの関数を引数として受け取るか、結果として関数を返す関数」とのこと。高階関数に引数として渡す関数はしばしばコールバック関数と呼ばれる。
たとえば文字列を大文字に変換するという単純な例を、map関数にコールバック関数を渡して実行する例を下記に示す。

var names = ['totakeke', 'takashishi'];
var upper = names.map(function(name) {
  return name.toUpperCase();
});
console.log(upper); // [ 'TOTAKEKE', 'TAKASHISHI' ]

高階抽象には多くのメリットがある。実装にトリッキーな部分があれば、それらをまとめて高階関数の実装に局所化(localize)できる。自分が同じパターンを繰り返し書いていると気づいたら高階関数に切り替えることを学べば、よりコードが簡潔になり、生産性が高まる。

項目20 カスタムレシーバ付きでメソッドを呼び出すにはcallを使う

項目18で述べた通り、通常、関数またはメソッドのレシーバは呼び出し側の構文によって決まる。
ただし、ときにはカスタムレシーバをつけて関数を呼び出す必要が生じる。こういった場合、カスタムレシーバを提供するための組み込み関数 call()を使えばよい。

f.call(obj, arg1, arg2, arg3);

上記の記述によって、objをレシーバとしてf関数が呼び出される。

またcallメソッド高階関数を定義するときにも便利に使える。高階関数で一般的なイディオムのひとつは、オプションの引数によって関数呼び出しのレシーバを提供するものである。
例えば下記のコードは、クライアントがコールバック用にレシーバを提供できる高階関数をcallによって定義している。

var table = {
  entries: [],
  addEntry: function(key, value) {
    this.entries.push({key: key, value: value});
  },
  forEach: function(f, thisArg) {
    var entries = this.entries;
    for (var i = 0, n = entries.length; i < n; i++) {
      var entry = entries[i];
      f.call(thisArg, entry.key, entry.value, i);
    }
  }
}

table1.forEach(table2.addEntry, table2); // table1のentriesをtable2にコピー

項目21 いくつでも引数を取れる関数を呼び出すには apply を使おう

callメソッドの親戚で、引数を配列として受け取りたい場合はapplyメソッドを使うとよい。thisを第1引数で結合できるのはcallメソッドと同じである。

参考になるページ:

applyとcallの使い方を丁寧に説明してみる - あと味

レベルアップのゲームデザイン 読書メモ LEVEL1

「レベルアップ」のゲームデザイン ―実戦で使えるゲーム作りのテクニック

「レベルアップ」のゲームデザイン ―実戦で使えるゲーム作りのテクニック

興味がある分野なので読書メモを残しておきます。

LEVEL1 新人さん、いらっしゃい

この章で印象に残ったのは、メンバーの役割についての項目。
自分は一応プログラマーであるが、この本で述べられているプログラマーにとって理解が必要な下記項目は覚えておかないといけない(全然足りない)。

また、ゲームデザイナーにとって必要なスキルも印象に残った。下記のように、非常に多くの分野に渡って理解すべきである。

  • アニメーション
  • 人類学
  • 建築
  • ブレインストーミング
  • ビジネス
  • 映画撮影法
  • コミュニケーション
  • クリエイティブライティング
  • 経済学
  • エンジニアリング
  • 歴史
  • マネジメント
  • 数学
  • 音楽
  • 心理学
  • 演説
  • サウンドデザイン
  • テクニカルライティング
  • ビジュアルアート

そしてもう一つ、ゲームデザイナーが責任を負うべき職務として「開発するゲームが楽しいこと」は激しく同意したい。