reponの勉強メモ

主に勉強したことのメモです。

Hubotの導入

Slackを始めたので、Hubotも導入することにした。

参考

とりあえず、サーバにhubotをインストールした。

nodeはインストール済み。redisが必要になる。

$ sudo pkg install redis

npmのパッケージ類のインストール。

$ sudo npm install -g yo coffee-script hubot generator-hubot

インストールにすごい時間がかかった。

botのひな形を作る

ひな形の作り方が変わっていた。

$ mkdir -p myhubot
$ cd myhubot
$ yo hubot

$ bin/hubot
myhubot> myhubot ping
PONG

以下だと怒られる

$ hubot -c myhubot
'hubot --create' is deprecated. Use the yeoman generator instead:
    npm install -g yo generator-hubot
    mkdir -p myhubot
    yo hubot

以後、動くものを作っていく。

javascriptでフィボナッチ数

一般的な書き方。

var fibo = function(n){
  if(n===0){
    return 0;
  }else if(n===1){
    return 1;
  }else{
    return fibo(n-1)+fibo(n-2);
  }
};

スタックオーバーフローになる。

状態値をもたせる方法(メモ化)。

var fibo = function(n,a,b){
  if(n===0){
    return 0;
  } else if(n===1){
    return a;
  } else{
    return fibo(n-1,a+b,a);
  }
};

a=1, b=0 と渡す

fibo(10,1,0) // 55

fibo(100,1,0) // 354224848179262000000

a,bという状態値をクロージャに持たせる方法。

var fibo = function(n){
  if(n){
    var a=1,b=0;
    var innerFunc = function(n,a,b){
      if(n===0){
        return 0;
      } else if(n===1){
        return a;
      } else {
        return innerFunc(n-1,a+b,a);
      }
    };
    return innerFunc(n,a,b);
  }
};

fibo(10) // 55

fibo(100) // 354224848179262000000

上記では、nが空の場合、処理をエスケープしている。

エスケープせずに以下の通り書くと、fibo() と引数を空にした場合に、スタックオーバーフローになる。

var fibo = function(n){
  var a=1,b=0;
  var innerFunc = function(n,a,b){
    if(n===0){
      return 0;
    } else if(n===1){
      return a;
    } else {
      return innerFunc(n-1,a+b,a);
    }
  };
  return innerFunc(n,a,b);
};

関数宣言(文)と関数式の違いがわからない

関数宣言(文)

function func(){}

関数式

var func = function(){}

ですが、クロージャを定義した際の動作が異なりました。

クロージャの作成

function func(){
  var n=1;
  return function(){
    return n++;
  }
}

または

var func = function(){
  var n=1;
  var innerFunc(){
    return n++;
  }
  return innerFunc;
}

これを関数式で実行すると、

var hoge = func();
hoge() // 1
hoge() // 2
hoge() // 3

ですが、関数宣言

func()() // 1
func()() // 1
func()() // 1

でした。

関数宣言の場合、関数の巻き上げにより 関数宣言前でも実行ができるが、 関数式の場合は変数のみが巻き上げられるため関数式以降でないと実行できない。 (関数宣言と関数式の違い)

この部分だと思うのですが、ではなぜクロージャに対して結果が異なるのか、自分ではうまく説明できません。