coffee script でエラーが出て全然開発がすすまない!!

最近、Hubotで遊んでいるのですが、Hubotではおもにcoffee scriptを使ってBotを作っています。

ただ、まだcoffee scriptに慣れていないためよく、エラーが出て止まってしまいます。。

/V/M/D/mybot ❯❯❯ bin/hubot
mybot> [Thu Sep 15 2016 18:15:16 GMT+0900 (JST)] ERROR Unable to load /Volumes/MacintochHD/Documents/mybot/scripts/redis: SyntaxError: unexpected OUTDENT

エラー箇所がすぐにわかればいいのですが、ターミナルではエラー箇所を教えてくれないので、場合によっては時間がかかってしまう時があります。。

そんなときは coffee scriptの公式へ!

すぐにエラー箇所がわからない場合は、迷わず公式に行きましょ。

CoffeeScript

上に並んでるなかから「TRY COFFEE SCRIPT」を開きます。
すると、コンソールが開いて、「Javascript で展開したらこうなるよ!」っていうのを教えてくれます。

親切なことにcoffee scriptでエラーがあると、Error on line 2: missing "みたいにエラー箇所を教えてくれます。

これをうまく使っていけば、Hubotの開発も少しは楽になるかもしれません。

Redisについて dotinstall で勉強しました。

HubotでBotを作る際、Redisを使うけど、「Redisとはなんぞや??」と思い調べたので、メモ。 ほとんど(というか大半)は dotinstall そのままなので、dotinstall見たほうがいいかも。。。

Redis入門: http://dotinstall.com/lessons/basic_redis

redisとは?

#01 Redisとはなにか?

特徴

  • メモリ上に作成されるDB
  • すごく早い!
  • メモリ上に作成されるので、容量にはシビア
  • 定期的にデータをディスクに書き出す永続化という仕組みを採用
  • 公式: Redis.io

KVSとは?

#02 KVSとはなにか?

KVS (Key Value Store)

  • key と valueをセットで保存するDB

Data Type

Redisにはデータタイプとしていくつか用意されている

  • String
  • List
  • Set
  • Sorted Set
  • Hash

Data Type

#03 Redisで扱えるデータ型について

String

  • Redisで最も基本的なデータタイプ
  • どのようなデータでも保存できる
  • 文字列は最大1GBまで扱うことが出来る
  • リスト型、セット型、ソート済みセット型、ハッシュ表型で保持される各要素は文字列型である redis 2.0.3 documentation

List

  • 順番に並べた複数の要素
  • 時系列的なデータ
  • 新しい要素をリストの先頭(左側)または末尾(右側)に追加することが

Set

  • 順不同の複数の要素。重複を許さない
  • 集合の演算ができる
  • タグ、ソーシャルグラフなどで、共通のタグを抽出したり、共通の友達を検索したり用いられる。

Sorted Set

  • Setの特徴を持ちつつ、個々の要素にスコア付き
  • 追加した要素をスコアに応じて並べ替える
  • ランキングなどで用いられる

Hash

Redisを使ってみる

#04 Redisを起動してみよう

起動と終了

  • 起動: `$ redis-server'
  • 終了: Ctrl + C

クライアント(CLI)の起動と終了

  • 起動: $ redis-cli
  • 終了: exit
  • 終了: shutdown exitshutdownの違いは、shutdownの方はその時点でのデータをディスクに書き出してくれる

データベースの選択

  • select #{DBの番号}
  • デフォルトで0が選択されている

データの保存

  • bgsave

保存されたデータ

  • redis-serverを立ち上げたディレクトリに dump.db という名前で保存され、次回起動時に読み込まれる

確認

 # Redisの起動
$ redis-server

 # 別タブでcliを起動
$ redis-cli

 # 値をセット
127.0.0.1:6379> set key_1 1
OK

 # 確認
127.0.0.1:6379> get key_1
"1"

この時点では作業ディレクトリにdump.dbが作成されていないことを確認

 # おもむろにCLIを終了
127.0.0.1:6379> exit

 # CLIは終了したが`dump.db`は作成されていないことを確認
$ ls
$ 

 # 再度起動
$ redis-cli

 # 書きだされてはいないが、メモリ上に値が保存されていることを確認
127.0.0.1:6379> get key_1
"1"

 # 値を保存
127.0.0.1:6379> bgsave
Background saving started

この時点で作業ディレクトリには dump.dbが作成されている

 # いったん作成された`dump.db`を削除して、今度はshutdownしてみる
127.0.0.1:6379> shutdown
$ 

作業ディレクトリにdump.dbが作成されていることを確認 また、別タブで起動していたredis−serverも終了していることが確認できる。

String型

#06 String型を使ってみよう

 # 値をセットする
127.0.0.1:6379> set key value
127.0.0.1:6379> OK

 # 確認
127.0.0.1:6379> get key
"value"

 # 複数の値をセットする
127.0.0.1:6379> mset key1 value1 key2 value2 key3 value3
127.0.0.1:6379> OK

 # 確認
127.0.0.1:6379> mget key1 key2 key3 
1) "value1"
2) "value2"
3) "value3"

 # scoreに"120"を追加
127.0.0.1:6379> set score 120
127.0.0.1:6379> OK
127.0.0.1:6379> get score
"120"

 # 1ずつ増減
127.0.0.1:6379> incr score
(integer) 121
127.0.0.1:6379> get score
"121"
127.0.0.1:6379> decr score
(integer) 120
127.0.0.1:6379> get score
"120"

 # 10ずつ増減
127.0.0.1:6379> incrby socre 10
(integer) 130
127.0.0.1:6379> get score
"130"
127.0.0.1:6379> decrby score 10
(integer) 120
127.0.0.1:6379> get score
"120"

KEY の操作

#07 KEYの操作を覚えよう

$ redis-cli

 # 格納されているKEYを確認。ワイルドカードで一覧を取得できる
127.0.0.1:6379> keys *
1) "score"
2) "key1"
3) "key3"
4) "key"
5) "key2"
6) "key_1"

 # KEY の存在を確認
127.0.0.1:6379> exists key1
 #結果がtrue(存在する)場合、`(integer) 1`が返ってくる
(integer) 1

127.0.0.1:6379> exists key4
 # 結果がfalse(存在しない)場合、`(integer) 0`が返ってくる
(integer) 0

 # 名前を変更
127.0.0.1:6379> rename key key4
OK

 #確認
127.0.0.1:6379> keys *
1) "key4" <= 変わってる
2) "score"
3) "key1"
4) "key3"
5) "key2"
6) "key_1"

 # KEYの削除
127.0.0.1:6379> del key4
(integer) 1

 # 確認
127.0.0.1:6379> keys *
1) "score" <= 1) "key4"が削除されてる
2) "key1"
3) "key3"
4) "key2"
5) "key_1"
127.0.0.1:6379>

List型

#08 List型を使ってみよう (1) #09 List型を使ってみよう (2)

 # KEY: mycollor にvalueを追加
127.0.0.1:6379> rpush mycolor red
(integer) 1

 # 確認
127.0.0.1:6379> lrange mycolor 0 -1
1) "red"

 # mycolorの先頭にvalueを追加
127.0.0.1:6379> lpush mycolor blue
(integer) 2

 # 確認
127.0.0.1:6379> lrange mycolor 0 -1
1) "blue" <= 先頭に追加されてる
2) "red"

 #末尾に複数追加
127.0.0.1:6379> rpush mycolor yellow green
(integer) 4

 # 確認
127.0.0.1:6379> lrange mycolor 0 -1
1) "blue"
2) "red"
3) "yellow" <= 追加した順番で追加されてる
4) "green" <= 追加した順番で追加されてる

 # 範囲を指定して確認
127.0.0.1:6379> lrange mycolor 0 1
1) "blue"
2) "red"

127.0.0.1:6379> lrange mycolor 0 0
1) "blue"

 # 先頭の値を削除
127.0.0.1:6379> lpop mycolor
"blue"

 # 末尾の値を削除
127.0.0.1:6379> rpop mycolor
"green"

 # 確認
127.0.0.1:6379> lrange mycolor 0 -1
1) "red"
2) "yellow"

 # 再度末尾に値を追加
127.0.0.1:6379> rpush mycolor green blue
(integer) 4

 # 確認
127.0.0.1:6379> lrange mycolor 0 -1
1) "red"
2) "yellow"
3) "green"
4) "blue"

 # 要素の数を返す
127.0.0.1:6379> llen mycolor
(integer) 4

 # ○番目にある要素を返す
127.0.0.1:6379> lindex mycolor 3
"green"

 # 先頭から2までに値を制限
127.0.0.1:6379> ltrim mycolor 0 2
OK

 # 確認
127.0.0.1:6379> lrange mycolor 0 -1
1) "red"
2) "yellow"
3) "green"
      <= 4)が消えてる

Set型

#10 Set型を使ってみよう

 # myset1というSetに値を追加
127.0.0.1:6379> sadd myset1 a
(integer) 1
127.0.0.1:6379> sadd myset1 b
(integer) 1
127.0.0.1:6379> sadd myset1 c
(integer) 1
127.0.0.1:6379> sadd myset1 d
(integer) 1

 # myset1を確認
127.0.0.1:6379> smembers myset1
1) "d"
2) "b"
3) "c"
4) "a"

 # myset2というSetに値を追加
127.0.0.1:6379> sadd myset2 d
(integer) 1
127.0.0.1:6379> sadd myset2 c
(integer) 1
127.0.0.1:6379> sadd myset2 ce
(integer) 1
127.0.0.1:6379> sadd myset2 f
(integer) 1

 # myset2を確認
127.0.0.1:6379> smembers myset2
1) "f"
2) "ce"
3) "d"
4) "c"

 # myset1とmyset2の和集合を確認
127.0.0.1:6379> sunion myset1 myset2
1) "f"
2) "ce"
3) "d"
4) "c"
5) "b"
6) "a"

 # 和集合から新たなセットを作成
127.0.0.1:6379> sunionstore myunion myset1 myset2
(integer) 6
127.0.0.1:6379> smembers myunion
1) "f"
2) "ce"
3) "d"
4) "c"
5) "b"
6) "a"

  # myset1とmyset2の積集合を確認
127.0.0.1:6379> sinter myset1 myset2
1) "d"
2) "c"

 # 積集合から新たなセットを作成
127.0.0.1:6379> sinterstore myinter myset1 myset2
(integer) 2
127.0.0.1:6379> smembers mydinter
(empty list or set)
127.0.0.1:6379> smembers myinter
1) "d"
2) "c"

 # myset1とmyset2の差を確認
127.0.0.1:6379> sdiff myset1 myset2
1) "b"
2) "a"

 # 差から新たなセットを作成
127.0.0.1:6379> sdiffstore mydiff myset1 myset2
(integer) 2
127.0.0.1:6379> smembers mydiff
1) "b"
2) "a"

恥ずかしながら和集合、積集合の意味がわからなかったので、調べた。
和集合: 和集合は合併とも言う。要素(元)を合わせた集合。
積集合: 積集合は共通部分の集合のこと。両者に共通の要素(元)だけを合わせた集合。
和集合と積集合の違いを教えてください。 よろしくお願いします。

Sorted Set型

#11 Sorted Set型を使ってみよう

 # hs というkeyに値を追加
127.0.0.1:6379> zadd hs 22 taguti
(integer) 1
127.0.0.1:6379> zadd hs 40 tanaka
(integer) 1
127.0.0.1:6379> zadd hs 79 kobayasi
(integer) 1
127.0.0.1:6379> zadd hs 50 satou
(integer) 1

 # hsを表示
127.0.0.1:6379> zrange hs 0 -1
1) "taguti"
2) "tanaka"
3) "satou"
4) "kobayasi" <= スコアが低い順に並ぶ

 # 逆順にソートする
127.0.0.1:6379> zrevrange hs 0 -1
1) "kobayasi"
2) "satou"
3) "tanaka"
4) "taguti" <= 逆順にソートされてる

 # 順位を求める(0から始まる)
127.0.0.1:6379> zrank hs taguti
(integer) 0
127.0.0.1:6379> zrank hs tanaka
(integer) 1

 # 逆順のランキングを求める
127.0.0.1:6379> zrevrank hs tanaka
(integer) 2

Hash型

#12 Hash型を使ってみよう

 # userというhashにkeyとvalueを追加
127.0.0.1:6379> hset user name taguti
(integer) 1

 # 複数追加
127.0.0.1:6379> hmset user email taguti@gmai.com score 120
OK

 # 値を表示
127.0.0.1:6379> hget user name
"taguti"

 # 複数表示
127.0.0.1:6379> hmget user name score
1) "taguti"
2) "120"

 # 長さを表示
127.0.0.1:6379> hlen user
(integer) 3

 # keyの一覧を表示
127.0.0.1:6379> hkeys user
1) "name"
2) "email"
3) "score"

 # value の一覧を表示
127.0.0.1:6379> hvals user
1) "taguti"
2) "taguti@gmai.com"
3) "120"

 # keyとvalueの一覧を表示
127.0.0.1:6379> hgetall user
1) "name"
2) "taguti"
3) "email"
4) "taguti@gmai.com"
5) "score"
6) "120"

Sort

#13 sortを使ってみよう

 # mynumberというkeyに値を追加
127.0.0.1:6379> rpush mynumber 10
(integer) 1
127.0.0.1:6379> rpush mynumber 20
(integer) 2
127.0.0.1:6379> rpush mynumber 15
(integer) 3
127.0.0.1:6379> rpush mynumber 100
(integer) 4

 # mynumberを表示
127.0.0.1:6379> lrange mynumber 0 -1
1) "10"
2) "20"
3) "15"
4) "100"

 # mynumberをソート
127.0.0.1:6379> sort mynumber
1) "10"
2) "15"
3) "20"
4) "100"

 # mynumberを逆順にソート
127.0.0.1:6379> sort mynumber desc
1) "100"
2) "20"
3) "15"
4) "10"

 # 表示数を制限してソート
127.0.0.1:6379> sort mynumber desc limit 0 2
1) "100"
2) "20"

multi/exec

#14 multi/execを使ってみよう

 # visitor と counterというkeyにvalue:1をセット
127.0.0.1:6379> get visitor
"1"
127.0.0.1:6379> get counter
"1"

 # まとめて処理をする
127.0.0.1:6379> multi
OK

 # 値を10ずつ増やす
127.0.0.1:6379> incrby visitor 10
QUEUED <= Queに入る
127.0.0.1:6379> incrby counter 20
QUEUED <= Queに入る

 # 実行
127.0.0.1:6379> exec
1) (integer) 11
2) (integer) 21

 # 確認
127.0.0.1:6379> get counter
"21"
127.0.0.1:6379> get visitor
"11"

ざっくり概要はわかった。
これで何ができるかはまだわからないけど、それは色々やってみて覚えていこう。

ページ遷移後にスムーススクロールがしたかった

ページ遷移後に 、任意IDの場所までスムーススクロールをさせたいという要望があり、調べたのでメモ

まず、要件をまとめます。 - 対象ブラウザは、IE8〜11、ChromeFirefoxSafari - ページ遷移したあとで、任意の場所にスムーススクロールをさせたい - URLには、パラメータ(?◯◯)が付くので、ハッシュ(#◯◯)という形にして欲しい

同一ページ内のスムーススクロールならさほど難しくないが、ページ遷移を挟むとちょっと難しい。

調べてみると以下のページが見つかる。 リンク先のページでスムーズスクロールさせる方法
【jQuery】ページ遷移後のスムーススクロール簡易型?になったと思います。

うーん、悪くはないのですが、今回の要件は、#で遷移できるようになので、今回は見送ります。

こんな時は英語で検索。「jquery smooth scroll other page」で検索すると、Stack Overflowにいいのが見つかりました。

jquery page scroll to different page

デモはこんな感じ。
デモ

確かにページ遷移してもスムーススクロールが動作しています。

ここで使われているソースをちょっと修正したのが、以下のソースです。

// ページ遷移後にスムーススクロール
jQuery(function($) {
  // 関数jumpを定義
  var jump=function(e) {

  // #で始まるURLの場合
  if (e){
    e.preventDefault();
    var target = $(this).attr('href');
  }else{
    // targetに別ページにある#を代入
    var target = location.hash;
  }

  // 変数targetの位置までスクロール
  $('html, body').animate({
    scrollTop: $(target).offset().top
    },800,function() {
      // スクロールしたあとにハッシュを変更
      location.hash = target;
    });
  };

  // ハッシュがページを開いたときに動作しないように、htmlとbodyを削除
  $('html, body').hide();

  $(document).ready(function() {
    // #から始まるリンクをクリックした場合、関数jumpを実行
    $('a[href^=#]').bind('click', jump);

    // URLにハッシュがあれば以下を実行
    if (location.hash){
      // 0秒後に実行
      setTimeout(function(){
        // 一度、ページの一番上まで移動して、html、bodyを表示。その後関数jumpを実行
        $('html, body').scrollTop(0).show();
        jump();
      }, 0);
    }else{
      // #がURLにない場合、そのままhtml、bodyを表示
      $('html, body').show();
    }
  });
});

無事実装できました。
迷ったときは、がんばって英語のリソースを当たることも必要ですね。

Visual Studio Code のDiffをちょっといじってみる

またまたVisual Studio Code (以後、VSCode) についてです。 Sublime TextではFileのDiffは FileDiffs を使ってたのですが、VSCodeでは何使おうかなと思っていていいのが見つかりました。

github.com

VSCodeではデフォルトでDiffが入ってた!

別に拡張機能を入れなくてもデフォルトで入ってました。 cmd + shift + pでコンソールを出して、compareとタイプすると比較するファイルを開く枠が出てくるので、そこで比較したいファイルを選んでやるだけでOKです。

でも、めんどくさくね?

とはいえ、Diffとるたびに cmd + shift + p押して、compareって入れて、ファイル選択して・・・ってはっきり言ってめんどくださいです。

ショートカットで一発でできたほうがいいに決まっています。 でもデフォルトでは用意されてないっぽい・・・

ないなら作ってしまいましょう。

幸いにもkeybinding.jsonで設定できるようなので、設定してみましょう。

左上の「Code」から、「基本設定 > キーボードショートカット」をクリック。すると、既定のキーボードショートカットとユーザー設定のjsonファイルが2つ開きます。

既定のキーボードショートカットから compare で検索すると、 コメントアウトされたworkbench.files.action.compareFileWithという項目が見つかります。 どうやらこいつでキーボードショートカットを設定してやればよさそうです。

後は、なるべくかぶらなそうな組み合わせでキーボードショートカットを設定してやればいいです。

私は cmd + shift + control + d(Diffのd) で作りました。

[
  {
    "key": "ctrl+shift+cmd+d",
    "command": "workbench.files.action.compareFileWith"
  }
]

試してみよう

適当なファイルを開いて、おもむろにcmd + shift + control + dを押してみると・・・、 一発で比較したいファイルの選択画面を開くことが出来ました。

デフォルト: cmd + shift + pcompare > ファイル選択 今回の変更: cmd + shift + control + d > ファイル選択

という感じで1手減らすことが出来ました。

たかが一手、されど一手です。

今回のことで他にも色々遊べそうだということがわかったので、これからもショートカット作ったり遊んでいきたいと思います!

MacでVisual Studio Code の設定を同期してみる

qiitaの方にVisual Studio Code(以後、VSCode)の絶賛記事をかいたのですが、続報はこちらで。

qiita.com

設定を複数のMacで同期したい!!

Sublime TextやAtomを使っている人にとって当たり前にやりたいことだと思うので、VSCodeでもできるんじゃないかと思って調べたらできた。 ちなみにWindowsの方はqiitaにあるけど、当方Macなので、その方法を紹介。

Visual Studio Code のユーザ設定を複数PCで使いまわす(Dropbox経由) - Qiita

VSCodeの設定ファイル

VSCodeでは設定ファイルは2つあるみたいです。

  • 基本設定 > /Library/Application Support/Code/User/
  • 拡張機能 > /Users/{ユーザー名}/.vscode

これを例に倣ってDropboxに置いてシンボリックリンクを貼ってやればOKです。

ここからターミナルでの作業

# Dropbox内の適当なディレクトリにファイルを移動
$ mv /Library/Application Support/Code/User /Users/{ユーザー名}/Dropbox/setting/vscode
$ mv /Users/{ユーザー名}/.vscode /Users/{ユーザー名}/Dropbox/setting/vscode

# シンボリックリンクを貼る
$ ln -s /Users/{ユーザー名}/Dropbox/setting/vscode/User /Library/Application Support/Code/
$ ln -s /Users/{ユーザー名}/Dropbox/setting/vscode/.vscode /Users/{ユーザー名}/

後は複数のMacでVSCodeを立ち上げてみて、設定が同期されていればOK。

簡単に出来ました。 これで快適なコーディングライフが送れますね!!

はじめまして、こんにちは

ブログを始めてみました。

最近、読んだ本の中で「アウトプットを意識した読書」というのがよく書かれていました。

それによると、アウトプットを意識すると・・・

  • 本を読む目的がはっきりする
  • 目的があると、本の中で必要な箇所がわかる
  • 必要な箇所がわかれば、その部分を重点的に読むので、速読につなが-。
  • 記憶が定着しやすい

などなど、いいことがいっぱいでした。

これはやるしかない、ということでブログを始めてみました。

これから書いていきたいこと。

これから、このブログで書いていきたいことは・・・

  • 読書メモ
  • 勉強したこと
  • いろいろ感じたこと

について書いていければと思っています。

いつも3日坊主な私ですが、少しでも続けていければと思っています。

それでは、「とにかくアウトプットするブログ」スタートです!