OmniAICreator/Qiita-1.07M huggingface dataset:
MavericksなMacでdisplayコマンドを使う


ImageMagick便利ですよね。
`convert` とか使用しない日がないくらいですよ。
`display` は常に画面の片隅に常駐させてますよ。

この度会社マシンを新調いたしまして、OSがめでたくMacOSX最新の10.9.4になりました。
もちろん

```bash
$ brew install imagemagick
```

で入れたんですが、インストールが終わりいざ

```bash
$ display [画像] &
```

とすると

```
display: delegate library support not built-in `' (X11) @ error/display.c/DisplayImageCommand/1894.
```

あらら。。。前(10.5時代)はそのまま動かせてた気がするんだけどな。

ちょい調べてみたらちゃんと[公式](http://support.apple.com/kb/HT5293?viewlocale=ja_JP)でこんなこと言っていたんですね。

なのでXquartzもインストール。

```bash
$ brew cask install xquartz
```

インストール後、Xを立ち上げて自分の利用シェルに環境変数DISPLAYを設定しておく。
おそらく `:0.0` で大丈夫だとは思うけど、起動したX11内からターミナル（xterm）を立ち上げて

```bash
$ echo $DISPLAY
```

みたいに調べれば間違いはない気がする。

これでもまだ `display` は同様のエラーを吐くので調べたら

```bash
$ brew options imagemagick
（中略）
--with-x11
	Build with x11 support
```

必要なインストールオプションあるでやんの。

仕方ないので今度はオプションつけてもう一度

```bash
$ brew install imagemagick --with-x11
```

からの

```bash
$ display [画像] &
```

でちゃんと表示できた。

### まとめると

ちゃんとした手順としては

```bash
$ brew cask install xquartz
```

してXquartz起動後、

```bash
$ export DISPLAY=':0.0'
$ brew install imagemagick --with-x11
```

でおｋ。
Manjaro Linux 0.8.10使ってみた


# 特徴

* ArchLinuxベース
* 優秀なGUIインストーラ
* 最初からXfce4、virtualbox-guest-utils が入っている。
  * VirtualBoxのウィンドウサイズに応じてゲストの解像度変更がされる。
  * ホスト<-->ゲスト間のクリップボードの共有を確認した。
* [Manjaro Linux | SourceForge.net](http://sourceforge.net/projects/manjarolinux/) から manjaro-xfce-minimal-0.8.10-x86_64.iso をダウンロードした。

# 日本語入力

参考:

* [日本語入力](https://wiki.manjaro.org/index.php?title=%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%AE%E8%A8%AD%E5%AE%9A)


![スクリーンショット 2014-09-01 10.09.04.png](https://qiita-image-store.s3.amazonaws.com/0/25728/077602ca-496d-bec5-d185-67de0dea2979.png "スクリーンショット 2014-09-01 10.09.04.png")

```bash:パッケージインストール
$ sudo pacman -Sy fcitx-mozc fcitx-gtk2 fcitx-gtk3 fcitx-qt4
```

```~/.xprofile
export GTK2_RC_FILES="$HOME/.gtkrc-2.0"
export LANG="ja_JP.UTF-8"
export XMODIFIERS="@im=fcitx"
export XMODIFIER="@im=fcitx"
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export DefaultIMModule=fcitx
```

```bash:~/.bashrc
export GTK_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
export QT_IM_MODULE=fcitx
```


# sudoをパスワードなしで行う

* /etc/sudoers.d/10-installer が存在することに注意。

```diff:/etc/sudoers.d/10-installer
-owner ALL=(ALL) ALL
+owner ALL=(ALL) NOPASSWD: ALL
```
Atom Shellを簡単に試す方法

# 背景

Atom ShellでHTML5のAPIが使えるか、試すのに、jsonやmain.jsなんかを書くのが面倒。

# 簡単な方法

- Atom Shellを起動する。
- DevToolsを表示させる。
- location.href="<試したいHTML5が記述されたURL>"

# 動画の解説

Atom Shellで作ったデスクトップ録画ソフト[asDeskCap](https://github.com/kjunichi/asDeskCap)で録画した[やつ](http://youtu.be/QveocadHogc)

<img src="http://share.gifyoutube.com/YDke5z.gif">

youtubeの方は、もう少し鮮明で、WebGLを動かしたとこまで見えます。

- http://youtu.be/QveocadHogc
MACの有線LAN、無線LANが遅くなったと思ったら、アンチウィルスソフトを疑え！

アンチウィルスの、Sophosを利用していて、ブラウザ環境がむちゃくちゃ遅くなった。

この場合は、設定から、Web スキャンを停止して解決。

でも、それ止めたら、アンチウィルスの意味なくね？？？
ブロックせずにチャネルに値を送信する方法

チャネルに何かの値を送信したいけど、チャネルのバッファがすでに一杯ならそれ以上は送りたくない（送信待ちでブロックしたくない）という状況がある。

たとえば設定の再読み込みの責任を担っているgoroutineがいるとしよう。そのgoroutineは普段はあるチャネルで何か値が送られてくるのを待っていて、値が送られてくると動作を再開して、設定をどこかから読み込む（そのあとロックを獲得してグローバルな設定データを更新するというのが普通だが、それはここでは関係がない）。

さて、そういうgoroutineでは複数回連続して動作するのは通常特に意味がない。従って、設定再読み込みリクエストは1個でも2個でもどちらでもよくて、むしろ複数個連続してチャネルに値が送信されても1個しかキューされないようにしたいだろう。

そういうふうな動作を実現するには下のコードのようにすれば良い。

```go
// バッファサイズ1のチャネルを作成
c := make(chan bool, 1)

// ブロックせずに送信できるなら送信する。そうでなければ何もしない。
select {
case c <- true:
default:
}
```

注意： capでバッファに空きがあるかどうかを調べてからチャネルに送信するのはダメだよ。複数のgoroutineがcapを同時に実行して、両方とも空きがあると判断したら、送信のタイミングで結局どちらかがブロックしてしまうので。上のようにやること。
Goにatexitやグローバルなデストラクタがない理由

CやC++ではatexit関数で関数を登録しておくと、プログラムの終了時にその関数を自動的に走らせることができる。そういう機能はRubyやPythonにもある。

Goにはそういう機能はない。実装を忘れているのではなくて、意図的にそういう機能を持たせていないのだ。これについてIan Lance Taylorさんが[大変説得力のある説明](https://groups.google.com/forum/#!msg/Golang-Nuts/kRkZ1ibVvN0/LYXtPqnGH3AJ
)をしていた。

まず第一に、どんなプログラムでも任意の箇所でクラッシュしうるし、まったくバグのないプログラムでもいきなりkillで殺されたりマシンが電源断で落ちるということがある。従ってどんなプログラムも、突然終了させられたあとに、もう一度きちんと動くことができなければならない。つまりatexitはきれいに終了するための機能ということで、atexitが呼び出されないとうまく動かないプログラムというのはそもそも間違っているということになる。

大きなC++プログラムではたくさんのグローバルなデストラクタやatexitが走ることになる。そしてそれはプログラムのサイズに応じて、時に驚くほど長い時間を要することがある。プロセスの終了を待っている間はなにもすることはできない ―― ただ終了をじっと待つだけだ。しかもその終了処理は、本当はやらなくても再起動にはなんの支障も及ぼさないことをやっているのだ。

C++コミュニティはこの問題をよく認識していて、それを解決するために、C++11でstd::quick_exitというのを導入した。これは終了処理を走らせないでプロセスを即座に終了するための関数だ。しかし終了処理をそれでも走らせたいというひとたちのために、結局std::at_quick_exitというのも同時に導入された。こうなると冗談めいた状況になっていると言わざるをえない。

そういう状況に陥らないようにするため、Goでは最初からatexitが用意されていないし、グローバルなデストラクタも用意されていない。os.Exitはdeferも実行せずに即座に終了する。このデザインはときどき不便なことも引き起こすが（atexitが確かに便利というのは否定しない）、あるのとないのでは、ないほうがよいというのがGoのデザイン上の選択なのだ。
Goでのキューはただのスライス＋appendで実装できる

Goでキューを実装するのには特別なデータ構造は必要がない。ただのスライスを使って、キューに加えるにはappend、キューから取り出すにはスライシングを使えば十分だ。キューが空かどうかはlenが0かどうかを調べれば良い。

```go
// int型のキューを作成
q := make([]int, 0)

// キューに1, 2, 3を追加
q = append(q, 1)
q = append(q, 2)
q = append(q, 3)

// 最初の値を取得
v1 := q[0]
q = q[1:]

// 次の値を取得
v2 := q[0]
q = q[1:]
```

つまりスライスqの指している場所をqの内部配列の右側にどんどんずらしていくようなイメージだ。内部配列は必要に応じて再割り当てされるのでキューがあふれることはないし、再割り当ての際に左側の参照されていない領域は捨てられる（コピーされない）のでメモリ使用量がどんどん増えてしまうこともない。
定義されている関数のリストをリフレクションを使っても取得できない理由

Goのリフレクション（reflect）を使うと構造体のフィールドのリストやインターフェイスのメソッドセットを取得することができる。しかし定義されている関数のリストを取得することはできない。reflectはそういう機能を提供していないのである。

どうも、設定ファイルから関数名を読んで、その関数を呼び出すといったことをやりたいといったような話が定期的にあがってくるようだ。たしかにそういうことができれば便利かもしれないが、そういう機能を提供していないのにはきちんとした理由がある

Goでは使われていない関数は最終的なバイナリには入らない。定義されているけどどこからも呼ばれていない関数というのは最初から書いていないのと同じだ。逆に言うと、コンパイラとリンカに関数を削除するという最適化を許すためには、関数一覧を取得するという機能があったりすると困るのである。

では実際に使われている関数だけの一覧を取得できればよいのでは？ と思うかもしれないが、関数がインライン展開されていたりすると、その関数は、使われていてもランタイムには独立した関数としては存在しないことがありえる。それに、関係ない場所をいじったらメタプログラミングしている場所の振る舞いが変わるといった調子だとわかりにくくて仕方がない。だから関数一覧を取得する機能は単に提供しない、というのはいい割り切りだと思う。

なお、どうしても関数を名前で呼びたいときは、関数名→関数のマップを作っておいてそれを実行時にルックアップすればよい。
EOFをチェックするより前に読んだデータを処理しよう

GoのIO関係の関数は、読んだデータの長さとエラーの両方を同時に返す。もしデータの長さが0でなければ、エラーがあったとしても、読んだぶんはきちんと処理しなければいけない。たとえば次のようなコードは間違いだ。

```go
n, err := r.Read(buf)
if err != nil {
	// エラーを返す
}
// buf[:n]を処理
```

上のようなコードだと、3とEOFが返ってきたようなときに、一番最後の3バイトを取りこぼすことになる。正しくは下のような順番で書かないといけない。

```go
n, err := r.Read(buf)
// buf[:n]を処理
if err != nil {
	// エラーを返す
}
```
Goでは文字列連結はコストの高い操作

Goでは文字列は不変（immutable）なので、文字列への文字の追加は常に新しい文字列をアロケートすることになる。ランタイムはまず新しい文字列のためのメモリを割り当てて、そこに既存の文字列の内容をコピーし、新しい文字を最後に足すということを行う。

従って、文字列に+=演算子で文字列を追加していく操作は大変効率が悪い。Javaの文字列も同じだからJavaプログラマにとっては馴染みのある話だろうと思う。

文字列を構築する必要がある場合、[]byte型の値を作ってそれに文字列を追加していって、最後に値を文字列に変換するのがよい。

```go
// サイズ0、内部バッファの長さ10の[]byteの値を割り当てる
b := make([]byte, 0, 10)

// bに文字列を追加
b = append(b, "foo"...) // ...が必要
b = append(b, "bar"...)
return string(b)
```

上のコードでは、10バイトのバッファを持った値bを最初に割り当てている。bは10バイトと短いのでスタックに割り付けられる（ヒープ割り当てよりスタック割り当てのほうが速いので、これはよいこと）。その後バッファを埋めていっているが、"foo"と"bar"は合わせて6バイトなのでbが再割り当てされることはない。従って上のコードでヒープにメモリが割り当てられるのは、最後に[]byteをstringに変換しているところだけになり、効率が良い。

もしバッファが途中で10バイトより長くなればbはヒープに移されるので、そういう文字列もきちんと構築することができる。

いずれにせよ文字列を連結するよりはこちらのほうが効率的なやり方だ。
Goで不必要にメモリアロケーションの回数を増やさない方法

Goにはガベージコレクションがあるのでプログラマがメモリ管理を意識することは少ない。とはいえ無駄にメモリを割り当てまくるとそれだけメモリアロケータとガベージコレクタが走る回数が増えてプログラムが遅くなってしまう。効率の良いプログラムを書こうと思ったらある程度はどういうふうに値がメモリ上に確保されるのか意識することが必要だ。

メモリシステムへの負荷を下げるにはメモリの量だけではなく回数を減らすことが有効である。Goでは構造体のレイアウトは自分で制御できるし、interior pointer（オブジェクトの内部を指しているポインタ）を取得することもできるので、必要な値をまとめてメモリ上に確保することができる。具体的には次のように行う。

```go
type encoder {
    buf     []byte
    scratch [80]byte
    // その他のフィールド ...
}

func newEncoder() *encoder {
    e := new(encoder)
    e.buf = scratch[:]
    return e
}
```

encoderという型がbufというフィールドを持っているのだけど、encoderは同時にscratchという80バイトのバッファのフィールドも持っている。new(encoder)は一発でスクラッチバッファを含むencoder全体をアロケートする。bufがだいたい常に80バイト以内に収まるのであれば、それ以上メモリを割り当てる必要はないから、アロケーションは1回だけで済む。encoderにscratchフィールドがなくて、別のnewの呼び出しでbufにメモリを割り当てていたとしたら、newの呼び出しは常に2回になるから、1回で済むのはずいぶんな節約だ。

アロケーションを少なくするというアイデアはいろいろなところで有効である。たとえば結果のスライスの長さをあらかじめ計算することができるなら、結果の長さがどうなるかをまず計算してからきっちり同じキャパシティを持ったスライスを割り当てて、そこに結果をappendしていくほうが、長さ0のスライスにappendしていくよりずっとよい。
Unityの床をひたすらループさせる

![スクリーンショット 2014-09-01 3.46.14.png](https://qiita-image-store.s3.amazonaws.com/0/38279/6e440f6a-08e6-acca-1e8c-613601ea268b.png)

キャラクターがひたすら走っているように見せる為に床をループさせましょう。同じサイズの床を二枚並べます。

![スクリーンショット 2014-09-01 3.47.02.png](https://qiita-image-store.s3.amazonaws.com/0/38279/773333a3-bbe3-526a-04bc-e27a9677fe40.png)

以下のスクリプトを二枚の床にドラック&ドロップすればOK!です。

```csharp:FloorLoop
using UnityEngine;
using System.Collections;

public class FloorLoop : MonoBehaviour {
	public float speed;
	float size = 60;

	void Start () {
		speed = -1;
	}

	void Update () {
		transform.position = new Vector3(transform.position.x, transform.position.y, transform.position.z+speed);

		if (transform.position.z + size < 0) {
			transform.position = new Vector3(0,0,transform.position.z+size*2);
		}
	}
}
```
CentOS6.5でDRBD8.4を使ってみる - vol.4 CRM設定編

# しおり

[CentOS6.5でDRBD8.4を使ってみる - vol.0 準備編](http://qiita.com/takehironet/items/4d26198798fb4b7454f8)
[CentOS6.5でDRBD8.4を使ってみる - vol.1 インストール編](http://qiita.com/takehironet/items/c90cd89fb621e570571f)
[CentOS6.5でDRBD8.4を使ってみる - vol.2 Corosync設定編](http://qiita.com/takehironet/items/61a3da51af3b32957872)
[CentOS6.5でDRBD8.4を使ってみる - vol.3 DRBD初期設定編](http://qiita.com/takehironet/items/13518725ee7c694efe90)
[CentOS6.5でDRBD8.4を使ってみる - vol.4 CRM設定編](http://qiita.com/takehironet/items/486bcdfe5609c67d5148)

# CRMの設定

## 最低限の設定

DRBDをPacemakerで制御する最低限の設定をします。

CRM Shellで次のように入力していきます。
途中でWARNINGが表示されますが、 `WARNING: drbd: default timeout 20s for start is smaller than the advised 240` というようなものであれば問題ありません。

```plain
primitive drbd ocf:linbit:drbd params drbdconf=/etc/drbd.conf drbd_resource=r0 \
op monitor interval=10 role=Slave \
op monitor interval=11 role=Master \
op stop on-fail=block
ms ms-drbd drbd meta notify=true
commit
exit
```

`primitive drbd` 行は長いのでバックスラッシュ(表示によっては円マーク)で行を分割しています。

ここではDRBDのリソース `r0` を制御するPacemakerのリソース`drbd`を作成し、 `ms` でMaster/Slaveモードで動作するように設定しています。
Master/Slaveモードは「両方のノードでリソースを同時に起動しつつ、MasterやSlaveの状態を導入し管理する」モードです。

`Slave` で動作している場合には監視間隔を10秒、 `Master` で動作している場合には監視間隔を11秒に設定しています。
`Master` で動作していても `Slave` で動作していても状態を監視する設定なのですが、秒数を変えているのは単純に「同じ秒数だと設定が通らない」ためです。
内部的に `op` を `リソース名-アクション-インターバル` という書式のIDで管理しているのが原因です。

`ms ms-drbd` で `notify=true` としていますが、これはノードの参加や脱退、リソースの起動といったイベントごとに、 `ms-drbd` リソースに判断をさせるための設定です。

`crm_mon -Ar` を実行して次のようになっていれば成功です。

```plain
============
Last updated: Sun Aug 31 19:50:01 2014
Stack: openais
Current DC: drbd1 - partition with quorum
Version: 1.0.13-a83fae5
2 Nodes configured, 2 expected votes
1 Resources configured.
============

Online: [ drbd1 drbd2 ]

Full list of resources:

 Master/Slave Set: ms-drbd
     Masters: [ drbd1 ]
     Slaves: [ drbd2 ]

Node Attributes:
* Node drbd1:
    + master-drbd:0                     : 10000
* Node drbd2:
    + master-drbd:1                     : 10000
```

## ファイルシステムマウント

Pacemakerにファイルシステムをマウントさせる設定をします。
`/dev/drbd0` が *マウントされていない* ことを確かめておいてください。

Pacemakerに `/dev/drbd0` 上のファイルシステムをマウントさせるためには、DRBDリソースが `Primary` でなくてはなりません(同居制約;colocation)。

CRM Shellで次の設定を行います。

```plain
primitive filesystem ocf:heartbeat:Filesystem params run_fsck=no device=/dev/drbd0 directory=/mnt/drbd fstype=ext4 \
op monitor interval=15 \
op stop on-fail=ignore
colocation drbd-fs-colocation inf: filesystem ms-drbd:Master
order drbd-fs-order inf: ms-drbd:promote filesystem:start
commit
```

`primitive filesystem` については見たとおりですが、リソースの停止に失敗しても無視して処理を継続させます( `op stop on-fail=ignore` )。

`colocation` は上で述べた条件(同居制約)を実現するものです。
`drbd-fs-colocation` と名前をつけて、制約をかけています。
「 `filesystem` リソースが動作するのは、必ず( `inf:` ) `ms-drbd` リソースが `Master` ロールを持っている( `ms-drbd:Master` )ノード」というものです。

`order` はリソースの起動順序を制御するものです。
`drbd-fs-order` と名前をつけており、この順序を強制( `inf:` )しています。
`ms-drbd` リソースを昇格させ( `ms-drbd:promote` )、つづいて `filesystem` リソースを起動( `filesystem:start` )させます。
CentOS6.5でDRBD8.4を使ってみる - vol.1 インストール編

# しおり

[CentOS6.5でDRBD8.4を使ってみる - vol.0 準備編](http://qiita.com/takehironet/items/4d26198798fb4b7454f8)
[CentOS6.5でDRBD8.4を使ってみる - vol.1 インストール編](http://qiita.com/takehironet/items/c90cd89fb621e570571f)
[CentOS6.5でDRBD8.4を使ってみる - vol.2 Corosync設定編](http://qiita.com/takehironet/items/61a3da51af3b32957872)
[CentOS6.5でDRBD8.4を使ってみる - vol.3 DRBD初期設定編](http://qiita.com/takehironet/items/13518725ee7c694efe90)
[CentOS6.5でDRBD8.4を使ってみる - vol.4 CRM設定編](http://qiita.com/takehironet/items/486bcdfe5609c67d5148)

# 注意事項

ここで使用しているLinux-HA Japan配布のPacemakerは古いバージョンです。
Pacemaker 1.1.12が2015年3月現在の最新で、`corosync.conf`の設定項目が変更されていたりSysVinitではなくUpstartを使用するように変更されていたりします。
http://linux-ha.sourceforge.jp/wp/ をご確認の上、適宜設定をお願い致します。

# DRBDをインストール

CentOS 6.4 64bit版にDRBDをインストールします。

## ELRepoの導入

DRBDのRPMパッケージを配布しているELRepoを利用します。

```
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-6-6.el6.elrepo.noarch.rpm
```

## DRBD 8.4の導入

DRBD 8.4をインストールします。

```
yum install -y drbd84-utils kmod-drbd84
```

`drbd84-utils` はユーザースペースで動作するユーティリティ群、 `kmod-drbd84` はカーネルスペースで動作するDRBDのカーネルモジュールです。


## 自動起動の停止

DRBDの制御はPacemakerに任せるので、自動起動しないようにします。

```plain
chkconfig drbd off
```

# Pacemakerのインストール

## Linux-HA Japanリポジトリの導入

[Linux-HA Japan](http://linux-ha.sourceforge.jp/wp/)配布のリポジトリパッケージを利用します。

2014年8月31日時点での最新版は1.0.13-2.1です。ダウンロードして `/tmp` に展開します。今回はJAISTさんのミラーを利用させていただきます。

```
curl "http://jaist.dl.sourceforge.jp/linux-ha/61791/pacemaker-1.0.13-2.1.el6.x86_64.repo.tar.gz" | tar -zx -C /tmp
cp /tmp/pacemaker-1.0.13-2.1.el6.x86_64.repo/pacemaker.repo /etc/yum.repos.d/
```

## CentOSリポジトリを修正

CentOSのBaseやUpdatesに含まれるPacemakerパッケージと、Linux-HA Japanリポジトリに含まれるPacemakerパッケージが衝突しますので、
CentOS BaseとUpdatesから除外する設定をします。

`/etc/yum.repos.d/CentOS-Base.repo` の `[base]` セクションと `[updates]` セクションにそれぞれ以下の行を追加します。

```
exclude=pacemaker pacemaker-libs corosync cluster-glue heartbeat resource-agents
```

## Pacemakerをインストール

執筆時のLinux-HA Japan推奨はPacemaker+Heartbeatですが、ここではCorosyncを使用します。

```
yum install -y pacemaker corosync pm_extras
```

Corosyncは自動的に起動してしまうと都合が悪いので、自動起動をしないよう設定します。

```
chkconfig corosync off
```

また、pm_extrasがheartbeatに依存関係を持っていてインストールされてしまいますが、heartbeatを使用しないので自動起動をオフにします。

```
chkconfig heartbeat off
```
複数行のテキストを縦横中央揃えにする方法


横の中央揃えは margin使えば簡単なんだけど、縦の中央揃えは
何かと厄介だったりします。

親要素のサイズが決まっている場合は、以下の方法が簡単です。

html

```html
<p class="container">
	<span class="text">ここに複数行テキスト<br/>が入ります。</span>
</p>
```


css

```css
.container{
	width: 100px;
	height: 100px;
}

.container .text{
	display: table-cell;
	width: 100px;
	height: 100px;
	text-align: center;
	vertical-align: middle;
}
```

このように、
html側では中央揃えしたい要素をinline要素として置き、
css側ではその要素に対して **親要素と同じサイズ指定をした上で**

```css
display: table-cell;
text-align: center;
vertical-align: middle;
```
の3つのプロパティを設定することで実現できます。
CentOS6.5でDRBD8.4を使ってみる - vol.0 準備編

# 本稿について

DRBDをつかった高可用性ストレージを構築する際の手順をチュートリアル形式で書いています。

世間に出回っている情報と大きな違いはありませんが、一つ前のDRBD 8.3の情報が多く、DRBD 8.4がなかなか見つからなかったので敢えて書いてみました。

## しおり

[CentOS6.5でDRBD8.4を使ってみる - vol.0 準備編](http://qiita.com/takehironet/items/4d26198798fb4b7454f8)
[CentOS6.5でDRBD8.4を使ってみる - vol.1 インストール編](http://qiita.com/takehironet/items/c90cd89fb621e570571f)
[CentOS6.5でDRBD8.4を使ってみる - vol.2 Corosync設定編](http://qiita.com/takehironet/items/61a3da51af3b32957872)
[CentOS6.5でDRBD8.4を使ってみる - vol.3 DRBD初期設定編](http://qiita.com/takehironet/items/13518725ee7c694efe90)
[CentOS6.5でDRBD8.4を使ってみる - vol.4 CRM設定編](http://qiita.com/takehironet/items/486bcdfe5609c67d5148)
[CentOS6.5でDRBD8.4を使ってみる - vol.5 スプリットブレイン編1](http://qiita.com/takehironet/items/9c572035bed953e28c16)

# DRBDについて

[DRBD](http://www.drbd.org)(Distributed Replicated Block Device)は[LINBIT社](http://www.linbit.com)のOSSで、ネットワーク越しにディスクをミラーするものです。

HAクラスタでは共有ディスクを使用することで、フェイルオーバー後も同じデータを参照できるようにすることがありますが、DRBDはそれぞれのノードがデータを持つことで「シェアードナッシング」を実現できます。
「シェアードナッシング」については[Wikipediaの記事](http://ja.wikipedia.org/wiki/%E3%82%B7%E3%82%A7%E3%82%A2%E3%83%BC%E3%83%89%E3%83%BB%E3%83%8A%E3%83%83%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%BB%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3)を参照ください。

DRBDは `Primary` と `Secondary` の2つ役割(ロール)を持ち、読み書き可能なのは `Primary` のみです。
`Secondary` は読み込みすらできません。
`Primary` に障害が発生した場合には、 `Secondary` を　`Primary` に昇格させることでサービスの引継ができます。
DRBDそのものには、ロールを自動的に制御する仕組みが無いため、[Pacemaker](http://clusterlabs.org/)というOSSを組み合わせて使用します。

蛇足ですが、FreeBSDで動作するDRBDと同様な目的を果たすソフトウェアとして[HAST](https://wiki.freebsd.org/HAST)が有名です。

# 準備

DRBD(8.x)は基本的に2ノードで利用します(3ノードとか、4ノードとかも可能ですが、複雑になります)ので、マシンを2台用意します。

ディストリビューションはCentOS 6.5の64bit版を使用し、ホスト名はそれぞれ `drbd1` と `drbd2` しています。

## NICについて

基本的な構成は次のようなものですが、冗長性を高める場合には上から優先してNICを追加していきます。

* 死活監視用NIC 1枚
* データ同期用NIC 1枚
* サービス用NIC 1枚

今回は基本的かつ最低限な構成(最低限過ぎず、盛り過ぎもしない)で、上の構成にします。


## ディスクについて

ディスクについても、OSとデータと別ディスクにしたり、RAID1以上のアレイをストライプにしたりと、速度と信頼性を高める構成にするのが普通です。
しかしながら、ここではわかりやすくするために次のような構成にしています。

* OSとデータは別ディスク
* RAIDは使用しない

KVMで動作する仮想マシンで構築しているため、OSディスクは `/dev/vda` に、データディスクは `/dev/vdb` になっています。
環境に合わせて読み替えを行ってください。


## IPアドレス

IPアドレスをそれぞれ次のように設定しています。諸事情によりIPアドレスが揃っておりませんが、ご容赦ください。


### drbd1 ノード

* eth0: 192.168.100.59/24 (サービス用, SSH接続用)
* eth1: 192.168.130.18/24 (データ同期用)
* eth2: 192.168.128.15/24 (死活監視用)


### drbd2 ノード

* eth0: 192.168.100.60/24 (サービス用, SSH接続用)
* eth1: 192.168.130.19/24 (データ同期用)
* eth2: 192.168.128.16/24 (死活監視用)
C#で関数合成

C#でFuncを使って関数合成みたいなことをする。

C#は.NET2.0からジェネリクス、.NET3.0からラムダ式と拡張メソッドを使うことができるようになりました。

何番煎じか分かりませんが、今回はこれらを使って関数合成っぽいものを実装します。

#実装
とりあえず実装

```func.cs
namespace System
{
    public static class Func
    {
        public static Func<T, V> andThen<T, U, V>(this Func<T, U> f, Func<U, V> g)
        {
            return a => g(f(a));
        }
    }
}
```

これだけです。

#使い方

```usage.cs
using System;
using System.Console;

class Piyo
{
    public static void Main()
    {
        Func<int, string> intToString = i => i.toString();
        Func<string, string> repeat = str => str + str;
        var ans = intToString.andThen(repeat)(10);
        Console.WriteLine(ans); // "1010"
    }
}
```

#解説

FuncとFuncを合成して、1つのFuncにします。
先の例では、

> __intを受け取ってtoString()して返すintToString__

> と

> __stringを受け取って二度繰り返して返すrepeatを__

>合成することによって

> __intを受け取ってtoString()して二度繰り返すFuncを作っています。__

このように処理を分割、合成することで、コードの再利用性が上がります。

またメソッドの中でFuncを作る場合はスコープを制限することができます。

#注意?
Func AとFunc Bを合成したFuncを実行した時に、Aで例外が投げられると、Bでキャッチされず合成されたFuncの外に例外を投げます。従って、この方法では、「Aで投げられた例外をBでキャッチする」ということはできません。
(Aで投げられた例外をBでキャッチする方法をご存じの方がいらっしゃいましたら教えてください)

あと、Funcにした時のパフォーマンスはどのくらいになるのかも不明です。これもご存じの方がいらっしゃいましたら教えてください。
JavaScriptでfalseになるもの

JavaScriptでfalseになるものを整理してみました。

・false
・空文字
・NaN
・数値の0
・undefined
・null

(注意)
Infinityは、無限大を表す数値なためfalsyではありません。
私は、間違えてInfinityはfalsyだと思っていました。
でも、Infinityは、無限大を表すんだから普通に考えるとtruthyですよね。
ちなみに、Infinityで割ったものは全て0です。

```falsy.js
if ( !false ) {
    console.log('falseは、falsyです');
}

if ( !null ) {
    console.log('nullは、falsyです');
}

if ( !undefined ) {
    console.log('undefinedは、falsyです');
}

if ( !'' ) {
    console.log('空文字は、falsyです');
}

if ( !0 ) {
    console.log('0は、falsyです');
}

if ( !NaN ) {
    console.log('NaNは、falsyです');
}

//注意
if ( Infinity ) {
    console.log('Infinityは、truthyです');
}
```

以上、お役に立てれば幸いです。
Mecanimで単純なアニメーション

 Mayaでキーフレームアニメーションをつけた後、FBX形式などで書き出したものを Unityに取り込んだらInspectorのAnimationsタブからClipsでアニメーションのキーフレームを設定します。
※両側のオブジェクトが開いたり閉じたりするアニメーションをつくりました。

![スクリーンショット 2014-09-01 1.59.34.png](https://qiita-image-store.s3.amazonaws.com/0/38279/f061e923-e425-13cb-e5b1-97b4b0c500c6.png)

![スクリーンショット 2014-09-01 1.55.23.png](https://qiita-image-store.s3.amazonaws.com/0/38279/f2c2be1b-de01-7212-c6c2-79de6c7d4411.png)

Hierarchryにモデルデータをドラック&ドロップしたらAddComponentからAnimatorを選択します。
Animation Controllerを作り、Controllerにアサインします。

![スクリーンショット 2014-09-01 2.03.03.png](https://qiita-image-store.s3.amazonaws.com/0/38279/dcf0652c-2a7e-641a-34e2-caf721df11f2.png)

AキーとSキーを押す事でモデルが開いたり閉じたりするアニメーションをするようにAnimatorを設定します。
静止しているアニメーション
開く、閉じるのアニメーションと４つのStateで構成しました。
アニメーション間の管理は、ParametersのBoolにしています。
これ超便利です。

![スクリーンショット 2014-09-01 1.55.03.png](https://qiita-image-store.s3.amazonaws.com/0/38279/c105ea3e-93f0-ff86-8e3a-c80248347a53.png)

スクリプトは以下のようにしました。
超シンプルで簡単です。

```csharp
using UnityEngine;
using System.Collections;

public class MecanimTest : MonoBehaviour {
	Animator animator;
	void Awake(){
		animator = GetComponent<Animator> ();
	}
	void Start () {
		animator.SetBool ("open_bool", false);	
	}
	void Update () {
		if (Input.GetKey ("a")) {
			animator.SetBool ("open_bool", true);
		} else if (Input.GetKey ("s")) {
			animator.SetBool ("open_bool", false);
		}
	}
}
```

これで、以下のような感じで開閉させました。
![スクリーンショット 2014-09-01 1.54.35.png](https://qiita-image-store.s3.amazonaws.com/0/38279/51281c14-a31c-2051-73d9-2e322da5d8d1.png)

![スクリーンショット 2014-09-01 1.54.26.png](https://qiita-image-store.s3.amazonaws.com/0/38279/49d33ce6-f105-100b-2cab-d716c77292af.png)
zen-codingをターミナルに導入し爆速でhtmlコーディングをする。

htmlタグはいちいち終わりタグを書くのもめんどくさいし、同じクラスを持ったliを何度も複製するのもめんどくさい…。そんな中で見つけたのがこのzen-coding。

例えば、

```
nav#sidebar>ul#menu>li.sub*3
```
 と入力し

```
[ctrl+y + ,]
```

を押すと、

```
<nav id="sidebar">
        <ul id="menu">
                <li class="sub"></li>
                <li class="sub"></li>
                <li class="sub"></li>
        </ul>
</nav>
```
このように展開してくれる。今回は、このzen-codingをMacのターミナル環境に導入する方法を記録する。

### 1.zen-codingのプラグインをダウンロード・zip解凍

[zen-coding ダウンロード](http://www.vim.org/scripts/script.php?script_id=2981)

※この中の emmemt-vim.zip ではなく、zencoding-vim.zip の最新版をダウンロードすることに注意。

### 2.展開したフォルダの中から必要なフォルダを移動（コピー）

*autoload
*doc
*plugin

この3つのフォルダを、~/.vim/plugin/html/ に移動（コピー）する。ダウンロードフォルダに展開したフォルダがある場合は、

```
（移動 ver.）$ mv ~/Downloads/zencoding-vim/* ~/.vim/plugin/html/

（コピー ver.）$ cp -r ~/Downloads/zencoding-vim/* ~/.vim/plugin/html/
```

で必要なフォルダに移動（コピー）出来る。
あとは、ファイル編集時にコマンドを入力していくだけ。htmlファイルに限らず、ファイル編集時にzen-codingは適用されているため、phpファイルでもガンガン使える。

---

構文等については以下を参照。
[zen-coding 構文](https://code.google.com/p/zen-coding/wiki/ZenHTMLSelectorsEn)
sass+compassのインストールにMacOS10.9+ruby2.0.0の環境で失敗したら。

パソコンを買い替えてMacOSがMarvericksになり、cssを入れ子構造で記述出来るsass+compassを導入することにした。
まず、gemのsystem周りを最新版にアップデート。ついでにsass+compassのアンインストールコマンドを念のため打っておく。

```
$ sudo gem update --system
$ sudo gem uninstall sass
$ sudo gem uninstall compass
```

続いて、homebrewも最新版に。

```
$ brew update
```



しかし、ここでエラー。。エラーの最後の二行はこう表示されている。

```
Gem files will remain installed in /Library/Ruby/Gems/2.0.0/gems/ffi-1.0.9 for inspection.
Results logged to /Library/Ruby/Gems/2.0.0/extensions/universal-darwin-13/2.0.0/ffi-1.0.9/gem_make.out
```


ffiに関してのエラーが出ているので、ffiをインストール・アップデートしようと思ったがそれもエラー。もしかしたらruby2.0.0がhomebrewと相性悪いのかもしれないと考え、rubyをバージョンアップしてみることに。


```
$ curl -L get.rvm.io | bash -s stable
$ ruby -v
…
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0]
```

無事 ruby2.1.2 が入ったようなので、homebrewのアップデート、sass+compassのインストールを実行してみる。
それぞれに必要なパッケージも一緒にインストールしたいので、 --pre を末尾につける。

```
$ brew update
$ sudo gem install sass --pre
$ sudo gem install compass --pre
```

これで、無事にインストール出来た。


##結論

どうやら、ruby2.0.0とhomebrew、compassは相性が悪いらしい。やっぱりこういうのは出来るだけ最新版にする必要がありそう。
hombrewのupdateがsslエラーで実行されない時は。

```
$ brew update
```
をすると、sslのエラーが返って来る。(↓)


```
fatal: unable to access 'https://github.com/mxcl/homebrew/': SSL certificate problem: Invalid certificate chain
Error: Failure while executing: git pull -q origin refs/heads/master:refs/remotes/origin/master
```

どうやらsslとgit周りで問題が起こっているらしく、ググっていると、期限が切れたsslのとある証明書を削除する必要があるらしいことが分かった。（↓）

[[sslの証明書が期限切れのものを削除する]](https://blog.digicert.com/expired-intermediate-certificate/)

その後、

```
$ brew update
…
Already up-to-date.
```

で無事完了。
MySQLをKVS的に使う

# MySQLをKVS的に使う

* とはいえ、KVSなんてよく使われるので別に書くほどのことでもないと思ってたりする
    * ストックとかせずに流し読んでへー、知ってたとか思って下さい
* じゃ、なんで書いたの?
    * 知らないヒトと出会ってしまったから
* あと、この辺の記事見たから
    * [ほんとにあったスキーマの話「ソーシャルゲーム」と題して、YAPCのトーク応募してみた](http://kfly8.hatenablog.com/entry/2014/07/04/160819)
* 今年はYAPC行きたかった。。 
* もっとヒドイなスキーマを目の当たりにしたけど、記憶の片隅にも留めたくないので語りません

## KVSとは？

* key-value-store(キーと値のペア)
    * ハッシュとかマップとか連想配列って言った方がなじみ深いと思う

## MySQLでKVS?

* 別に難しい話じゃない
    * あくまでkye-valueの形を作るだけ


### 必要なもの

* キーと値の組み合わせ
* それらを格納するテーブル

### どうやって使うの？

* 例えば、以下の様なモデルがあったとして
 * サンプルはPerl/JavaScriptをそれなりに分かっているという前提

```
foo = [bar => 'baz', hoge => 'fuga']
```

* こうなる
    * PKがauto_incrementかどうかは知りません
    * キーを複合にしたい場合はlabelが増えると思います


| id | label| value | etc |
| 1 | bar| baz| etc |
| 2 | hoge | fuga | etc |

### 何が便利なの?

* カラム追加が頻繁に起こりうるテーブルに対して、動的に行を列として代入可能
    * keyが悲しくも予約語なので、カラム名は(プルダウンリストから推測しやすい)label-valueがいいと思います

### 本当に便利なの？

* キーが膨れてしまった時点でカオスになります
* 万能に見えて乱用したくなりますが、キーが増えると管理出来なくなります
    * 確実に増えるカラムは素直にALTERかけましょう
* 使用上の注意をよく読み用法、用量を守り正しくお使い下さい
    * あくまでレコード量、更新頻度、インデックスとの相談です

### よくわかんない

* 補足テーブルと言った形で使います
** 例えば、以下の様なテーブルがあるとします

| id | prop1 | prop2 |
| 1 |マサカリ | 投げる |
| 2 | 椅子 | 投げる |

** そこに補足情報を付けます

| id | label | value |
| 1 | マサカリ |脳天に |
| 2 | 椅子 |思いっきり |

* 補足情報を付けるとこうなります

| id | prop1 | label |prop2 |
| 1 | マサカリ | 脳天に |投げる |
| 2 | 椅子 | 思いっきり |投げる |

### 結論

* ニヤニヤしてくれたら嬉しい
keyframes の 0% と minify

# @keyframes の 0%
CSSを書く際、「0px」「0%」など「0」である際には単位を付けないで書くのが通例であるが、
CSS Animation を記述する @keyframes 内の各keyframe selector に用いる「%」値においては、仕様書にある以下の記述の通り

>Note that the percentage unit specifier must be used on percentage values. Therefore, 0 is an invalid keyframe selector.
http://dev.w3.org/csswg/css-animations/#keyframes

単位を省略した「0」は invalid であり、「0%」としないといけないと定められています。

```lang:invalid_keyframes.css
@keyframes invalid {
  0 { left: 0; }
  100% { left: 100%; }
}
```

こちらは説明の通り「0%」としないといけないところを「0」としているため、invalid

```lang:valid_keyframes.css
@keyframes valid {
  0% { left: 0; }
  100% { left: 100%; }
}
```

こちらが、valid な @keyframes の記述。

# 0% と minify
@keyframes における「0%」の扱いはわかったかと思うので、知っていれば何ら問題ないかと思いきや、一つ落とし穴がります。

それが、minifyツール。

minifyツールは minify の過程において、「0」な値のものから単位を削る処理を行ってくれます。
そう、@keyframes の仕様に即していないツールの場合、「0%」でないといけないものまで「0」とされてしまうことがあるのです。

## 0となってしまったらどうなるのか
これはブラウザに因ってしまいますが、以下2つの場合を確認しています。

* 0 { rule } 部分だけが無視される
* 0 { rule } を含む @keyframes と その @keyframes のすぐ次のルールセットも無視される

ほとんどのブラウザは前者。
アンドロイドの1つの端末でのみ後者を確認。

# 対処法
問題のある全ての minifyツールで有効かはわかりませんが、「0%」を「0.00%」の様に記述することで回避できることがあります。
もしくは、「0%」を「from」に置き換えるというのも手かもしれません。（※ブラウザ対応状況は確認していません）

対処法ではないですが、複雑になってきたCSSを考えると、minifyせずにconcatだけに留めておくというのも今現在においては安全で有効な手段かもしれないですね。
Ruby で Brainf*ck の派生言語を作成するための gem 『orenono』を作成してみた

# Ruby で Brainf*ck の派生言語を作成するための gem 『orenono』 を作成してみた

## 概要
Ruby で Brainf*ck の派生言語を作成するための gem 『orenono』 を作成してみました

Brainf*ck を知らない、という方はこちらを参照ください。
http://ja.wikipedia.org/wiki/Brainfuck

## 経緯
CodeIQ の出題をしている関係で、 Brainf*ck と戯れる機会は多かったのですが、
書籍「Rubyで作る奇妙なプログラミング言語 ~Esoteric Language~」
の購入をきっかけに Brainf*ck の処理系を作ってみることに。
ここで、処理系を作った後に基本命令の 8 つをネタ系の内容に置き換えるところまでが定番になりますが、
どうせなら自由に Brainf*ck 派生言語を作成できる gem を作ろう、と思い立ちました。

既に誰かが同じことをしていたらごめんなさい。

## 仕様
* gem 名 orenono
    俺の脳（みんな自分の脳内の好きなワードで Brainf*ck を派生させてね、ということで。

* 文法は Orenonofile で管理
    Gemfile とかと同じように使う Ruby の内部DSL形式の設定ファイル。
    `orenono init` または `orenono i` でひな形を生成できる。
    デフォルトのままか、このファイルを生成しないで `orenono` コマンドを実行すると、
    通常の Brainf*ck の文法で動作します。

* 実行
    `orenono execute some_file.bf` または `orenono e some_file.bf` で実行。
    拡張子はなんでもいい。
    カレントディレクトリにある、 *Orenonofile* ファイルの内容で採用する文法を決定します。

## 利用例
### デフォルト

* orenono.bf

Brainf*ck のソースコードを用意。

~~~
+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.
------------.<++++++++.--------.+++.------.--------.>+.
~~~

* execute

実行するだけ。

~~~bash
$ orenono execute sample.bf
Hello, world!
~~~

execute は e だけでもよい。

~~~bash
$ orenono e sample.bf
Hello, world!
~~~

### 文法を変更する場合

* Orenonofile のひな形生成

~~~bash
$ orenono init
~~~

* Orenonofile に好きな文法を定義

※各ワードを正規表現で /足す|引く|はじめ|おわり|次|前|出|入/ のようにして
トークン分割を行うので、この正規表現で一意の文法として抽出できないような設定の場合は正しく動作しない

~~~ruby:Orenonofile
# encoding: utf-8

increment "足す"
decrement "引く"
start_loop "はじめ"
end_loop "おわり"
next_cursol "次"
previous_cursol "前"
display "出"
read "入"
~~~

~~~ruby:orenono.bf
足す足す足す足す足す足す足す足す足すはじめ次足す足す足す足す足す足す足す足す次足す足す足す足す足す足す足す足す足す足す足す次足す足す足す足す足す前前前引くおわり次出次足す足す出足す足す足す足す足す足す足す出出足す足す足す出次引く出
引く引く引く引く引く引く引く引く引く引く引く引く出前足す足す足す足す足す足す足す足す出引く引く引く引く引く引く引く引く出足す足す足す出引く引く引く引く引く引く出引く引く引く引く引く引く引く引く出次足す出
~~~

* execute

~~~bash
$ orenono e orenono.bf
Hello, world!
~~~

## オリジナルの派生言語を作りましょう
Orenonofile ＋ 何か好きなネタ（アニメや時事ネタなど）でオリジナル言語を作って遊んで貰えれば幸いです。

## 補足
その他詳細は、 GitHub の README 参照。

https://github.com/tbpgr/orenono

### orenonoスライドショー
http://tbpgr.github.io/orenono_slide/#/

## 参照
* RubyGems orenono gem
https://rubygems.org/gems/orenono

* GitHub orenono
https://github.com/tbpgr/orenono

* Brainf*ck Wikipedia
http://ja.wikipedia.org/wiki/Brainfuck
MacOS10.9でrvmインストール時にcurlのsslエラーで怒られた時の対処


```
$ curl -L get.rvm.io | bash -s stable
```

でインストールしようとすると、

```
curl: (60) SSL certificate problem: Invalid certificate chain
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.
```

と怒られる。調べた結果、

[curlのssl証明書エラーが出た時の対処法]（http://origami-works.com/2014/05/10/homebrew）

 を参考に、設定ファイルを作成

```
$ echo insecure >> ~/.curlrc
```


すると、インストールに成功する。
Pandoc+beamer+GraphvizでAWSの図を描く

## 動機

AWS (Amazon Web Services)の図を含むプレゼン資料を、テキストベースで作成したい

## 手段

以下の組み合わせで実現する

<dl>
<dt>pandoc</dt>
<dd>Markdown等様々な文書フォーマットの変換器。MarkdownをBeamer形式に変換し、さらにそのままLaTeXを呼び出しPDFに変換させられる</dd>
<dt>Beamer</dt>
<dd>LaTeXに基づきパワポのようなスライド資料PDFを作成するソフトウェア</dd>
<dt>Graphviz</dt>
<dd>グラフの論理表現を可視化レイアウトしたベクタまたはラスタ画像に変換するツール</dd>
<dt>AWSアイコン</dt>
<dd>AWSのサイトからeps, SVG形式のものがダウンロードできる</dd>
</dl>

## 環境

詳細は省略します(メモを残していない…)

- Mac OS X 10.7.5 (Lion)
    - Graphvizはbrewでインストールしたもの
    - Tex Live 2014は単独でインストールした（はず）
    - pandocはHaskell Platformとそのパッケージマネージャcabalでインストールした
    - pygraphvizをpipでインストールする
- Ubuntu 14.?.?
    - pandoc, Graphviz, texliveともapt-getにあるはず
    - Ubuntu 12.?.?だと標準のリポジトリではうまくいかない
    - pygraphvizもapt-getで入れた気がする

## pandocにgraphvizの図を貼り込む

pandocにはfilterの仕組みがあり、規約に沿ったHaskellまたはPythonコードで動作をカスタマイズできる。

pandocのドキュメントからたどるとPython用のfilterの例としてpandocfiltersというものが示されており、その中に[Graphvizもある](https://pypi.python.org/pypi/pandocfilters)。PythonからGraphvizを利用するpygraphvizが使われている。

これだとMarkdown中に普通に以下のように書いた部分がGraphvizの図に置き換わる。

~~~markdown
    ~~~graphviz
    digraph {
       a->b
    }
    ~~~
~~~

ただあくまでサンプルであり自分の資料を描く上で問題になった点があるので、以下の改造を行った。

- Graphvizの中で日本語のキーワードを使うとエラーになったので対策
- C Preprocessorを通すようにしマクロが定義できるようにした
- Beamerのときにpngでなくpdf画像を生成するようにした
- 画像のサイズを微調整できるようにした
    - `~~~{.graphviz prog="dot" width="0.8" height="0.8"}~`といった感じで指定する

改造したものはこちら。
https://github.com/ooharak/pandocfilters/blob/customize/examples/graphviz.py

###これを使って、絵を描くとこんな感じ

#### ソース
~~~markdown:a.md
    ## サンプル
    
    ~~~{.graphviz width="0.8"}
    #define ICON(name) peripheries=0 image="awsicons/"+name+".png"
    digraph {
     ELB [ICON("elb")]
     インスタンスa [ICON("instance")]
     インスタンスb [ICON("instance")]
     ELB -> {インスタンスa インスタンスb}
    }
    ~~~
~~~

#### コマンドライン

~~~sh
pandoc -s a.md -t html5 --self-contained -o a.html
~~~

#### 出力

![example1.png](https://qiita-image-store.s3.amazonaws.com/0/53185/db4354ef-a57e-cff7-6101-9e6900a476c2.png)


### もうちょっと凝ったもの

#### ソース/コマンドライン

https://gist.github.com/ooharak/4e2a79dce7216bc5360d

#### 出力

![example2.png](https://qiita-image-store.s3.amazonaws.com/0/53185/56bbbb1e-f2f8-f185-955a-3d709373fd22.png)

## BeamerでAWSアイコンをちゃんとベクタで出したい

BeamerでPDFを作るのだから、Graphvizの図を拡大してもギザギザが出ないようにしたい。

前述の改造を施した`graphviz.py`を使うと、pandocでBeamer経由で生成したPDFに貼り込まれるGraphvizの図もPDF形式で作られるので、Graphviz組み込みの図形はベクタになる。

問題は、そのGraphvizの中でさらにイメージとして読み込ませているAWSのアイコンである。
結論を先に言うと、私のMac環境ではsvg形式で読み込ませる必要があった。つまりGraphvizの文法でいうと`インスタンス [image="instance.svg"]`といった具合である。

先に紹介したgithub上のサンプルコードの`aws.inc`では、Cプリプロセッサの`#if`ディレクティブを使って、出力フォーマットによって拡張子を切り替えることで、Beamer向けにも、HTMLなどのほかのフォーマット向けにも、両対応したソースを書けるようにしてある。

### Ubuntuでは~~失敗~~ →解決

このときGraphviz内部ではsvgをrsvg, Cairoというライブラリを通してPDFに変換する。しかしビルドの仕方等によりrsvgサポートが組み込まれない状態のGraphvizでは、この変換は失敗してしまう。Ubuntu14.?.?のGraphvizがこれに相当して駄目だった。

Ubuntuの場合はrsvgを使うようにコンパイルオプションを指定した版を使う必要があるのだろう。

→追記2014.9.2：その通りだった。[Graphvizの中でSVGシェイプを使うとエラーになる件の対処(解決)](http://qiita.com/ooharak/items/2b43e11986b43cdd3299)に解決策を記した。


## その他の留意点

[AWSシンプルアイコンをGraphviz等で使うときのTIPS](http://qiita.com/ooharak/items/12c3c812c2a30753f52e)も参照のこと。
Google Apps ScriptでMobageの課金状況を確認する


## 図に乗ってMobageに課金してたら、「今どれくらい投資しているのか」が気になった。

技術的には新しい内容ではありません。あくまでも、AppsScriptの事例ということで…。

## 使うもの（必要知識）
* GmailApp
* SpreadsheetApp
* ライブラリの追加
* moment.js

## ライブラリの追加
Moment.jsのAppsScript移植版ライブラリがあるのでライブラリに追加します。（キー：MHMchiX6c1bwSqGM1PZiW_PxhMjh3Sh48）
![momentjs.png](https://qiita-image-store.s3.amazonaws.com/0/11925/2ae13622-7fd3-3a7f-505b-50d4e3c3e96a.png "momentjs.png")


## 最初のプログラム（仕様）
1. Gmailに届く、件名が「Google Playのご注文明細」を含むメールを検索する。
1. そのメール本文には、課金した金額が書かれているので、その金額を抜き出す。
1. Spreadsheetに書き出し、sum()で集計して確認する。
1. 月ごとの集計とかは、考えない。ひとまず今までの合計を。

```js:コード.gs
function myFunction() {
  var moment = Moment.load();
  var startTime = moment();
  var data = [];
  var th = GmailApp.search("subject: Google Playのご注文明細");
  
  for(var i = 0; i < th.length; i++) {
    var messages = th[i].getMessages();
    
    for(var j = 0; j < messages.length; j++) {
      var message = messages[j].getPlainBody();
      if( message != null) {
        if(message.indexOf('株式会社ディー・エヌ・エー') >= 0) {
          
          var start = message.indexOf('合計:');         // "合計:"と書かれた位置を検索。
          var end = message.indexOf('（', start);       // 次の（までの位置を取得。
          
          if( start >= 0 && end >= 0) {
            var rows = [];
            var date = messages[j].getDate();
            var sum = message.substring(start, end).match(/\d/g).join("");    // "合計:"の次に金額が書かれている。            
            
            rows.push(date);
            rows.push(sum);
            
            data.push(rows);
          }
        }
      }
    }    
  }
  
  var ss = SpreadsheetApp.getActive();
  ss.getRange("A:E").clearContent();          // A行からE行までを全てクリア
  
  var range = "A1" + ":" + "B" + data.length;
  ss.getRange(range).setValues(data);
  ss.getRange("C1").setValue("投資金額");
  ss.getRange("D1").setFormula("sum(B1:B" + data.length + ")");
  ss.getRange("E1").setValue(moment().diff(startTime));
}
```

## 承認をする。
2つに分かれていますが、サンプルコードを貼り付けたら1回で済みます。
![権限のリクエスト_GmailApp.png](https://qiita-image-store.s3.amazonaws.com/0/11925/de1e342f-ad19-3bd9-7699-9c204f2c5e5d.png "権限のリクエスト_GmailApp.png")

![承認_SpreadsheetApp.png](https://qiita-image-store.s3.amazonaws.com/0/11925/ceef5b63-79b5-443d-cc5b-f28aa57ca650.png "承認_SpreadsheetApp.png")


## 実行
実行時間は、55件のメール（幾つか、スレッド内にメールが複数ある）で162秒程度かかっていました。
これは遅い！


## 遅いのでチューニングしよう。
と、思ったのですが、JavaScriptのindexOf()、search()を比べると、indexOf()が一番早いということなので、変えられず、DeNA以外の購入通知も届くので、メールごとに微妙に文字位置も変わってしまうので、最初の1回だけ読みだして…。というわけにもいかず。
もし、興味が湧いたら、速度向上のチューニングに挑戦してみてください。

## 結論
課金はほどほどに…。


## Disclaimer
* Google Playから送られてくる課金通知のフォーマットが変わったらプログラムは使い物にならなくなります。
* この記事は個人的なものです｡私の雇用者とは全く関係はありません｡（一応つけておきます）

## 参考資料
https://support.google.com/mail/answer/7190?hl=ja
http://catprogram.hatenablog.com/entry/2013/05/13/231457
http://qiita.com/FiNGAHOLiC/items/d80641251aff8f2d135a
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf
https://plus.google.com/+EricKoleda/posts/ThnVjUgU3E9
http://momentjs.com/docs/#/displaying/difference/
Ansibleで作るnata2


[ISUCON4](http://isucon.net/archives/38857424.html)に向けて、参加予定の友人とMySQLのスロークエリを可視化出来れば良いね、という相談をしていたところ、nata2という素晴らしいアプリがあったので、Ansibleで構築してみました。

# インストールするもの。 
+ [nata2](https://github.com/studio3104/nata2)  

> (紹介文引用)
> パーズされたスロークエリログをHTTP Postで登録し、件数グラフ、スロークエリログの履歴、mysqldumpslow相当のサマライズなどの表示が出来るウェブアプリケーションです。

今回は、nata2の構築まででMySQLサーバの設定などは記載しません。  


作者のstudio3104さんによる、機能などの詳しい紹介はこちらです。

+ [MySQL Casual Talks vol 6.でNata2について発表してきた](http://studio3104.hatenablog.com/entry/2014/07/22/234953)


# AnsibleのPlaybook
https://github.com/volanja/ansible-nata2

構成の基本的な設計方針は以下の記事に書いています。
[Ansibleで作るxxxの基本設計](http://qiita.com/volanja/items/1eb54b99fe77bd8668bc)
ただし、もととも認証機能があるソフトウェアでないので、認証連携はありません。
MySQLサーバからのログ送信先はポート80なので注意してください。

# ソフトウェア構成図
![ansible-Gitlab.png](https://raw.githubusercontent.com/volanja/ansible-nata2/master/img/ansible-nata2.png)


# 対象環境(Nata2をインストールされる側)
CentOS 6.4 64bit   (virtualbox + vagrantで構築)

# 実行環境(Ansibleを実行する側)

```
$ ansible --version
ansible 1.6.8 (release1.6.8 5a4f39bfbf) last updated 2014/07/30 23:46:08 (GMT +900)

$ ruby -v
ruby 2.0.0p353 (2013-11-22 revision 43784) [x86_64-darwin11.4.2]

$ gem list |grep serverspec
serverspec (0.13.7)
```

# このPlaybookでインストールするもの
+ ruby 2.0.0p353 (/home/redmine配下にrbenvでインストール)
+ MariaDB 5.5.33a
+ Nginx
+ nata2

# 実行手順
## 1. hostsファイルの設定変更  

```
git clone https://github.com/volanja/ansible-nata2.git
```
clone後、hostsファイル内の対象サーバのIPアドレスを変更してください。

```hosts
[server]
192.168.0.138
```

## 2. SSH公開鍵認証の準備  
対象サーバにSSH公開鍵認証方式でログイン出来るように準備してください。

## 3. ansible playbook 実行  
対象サーバのドメイン名を`site.yml`内の`server_name`に定義(デフォルトはcadence)してください。  
playbookの変数は次のようになっています。パスワード等は必要に応じて変更してください。  
  
```
+------------------------------------------------------------------+
|             File             |         Key          |   Value    |
+------------------------------------------------------------------+
| site.yml                     | server_name          | cadence    |
| site.yml                     | user                 | nata2      |
| site.yml                     | nata2_version        | master     |
| roles/mariadb/vars/main.yml  | mysql_root_password  | password   |
| roles/nata2/vars/main.yml    | mysql_nata2_password | password   |
| roles/nata2/vars/main.yml    | mysql_nata2_database | nata2      |
| roles/packages/vars/main.yml | www_port             |         80 |
| roles/ruby/vars/main.yml     | ruby_ver             | 2.0.0-p353 |
+------------------------------------------------------------------+
```

次のコマンドで実行します。
  
```
$ ansible-playbook site.yml -i hosts  
```

## 4. テストの実行  
次のコマンドで実行します。  

```
$ rake serverspec:Install-Nata2
```

## 5. nata2へのアクセス  
アクセスするPCでは、あらかじめhostsファイルを次のように変更しておきます。  

+ Windows... C:/Windows/System32/drivers/etc/hosts  
+ Linux,Mac... /etc/hosts  

```
IP-ADDRESS nata2.cadence
```

アクセスするPCのブラウザを開き、次のURLでアクセスできます。  

```
http://nata2.cadence/  
```

以上です。
for in文とfor文　

for in文だとプロトタイプチェーン上のプロパティまで列挙されてしまう
そのため、自身のプロパティだけを判別して列挙するためにはtypeofまたはhasOwnPropertyを使います

```for_in.js
//typeofを用いた場合
for (name in obj) {
    if (typeof(obj[name]) !== 'function') {
        console.log(name+'は自身のプロパティです');
    }
}

//hasOwnPropertyを用いた場合
for (name in obj) {
    if(obj.hasOwnProperty(name)) {
        console.log(name+'は自身のプロパティです');
    }
}
```

しかし、for文だと

配列の場合

```for.js
for (i=0; i<arr.length; i++) {
    var name=i;
    console.log(name+'は自身のプロパティです');
}
```

とシンプルにかける。

オブジェクトの場合、underscorejsを用いると簡単にできます

```for_obj.js
var obj = {
    id     : 1,
    name   : 'Tanaka',
    age    : 23,
    living : true,
    birthday : '1998/12/24'
};

_.reduce(obj, function(result, value, key){
    console.log(key+'は、自身のプロパティです');
    console.log('値は、'+value+'です');
    return 0;
},0);
```

以上、お役に立てれば幸いです。
JavaScript Promiseの実行順序(Firefox31とChrome37で違うけどどっちが正しい？)

JavaScriptのPromiseで複数のthenを設定した時の動きがFirefox31とChrome37で違った。
コードは以下。

```js
var p = new Promise(function(fulfill, reject){
    console.log("start");
    fulfill("");
});

p.then(function(result){
    console.log("1-1");
}).then(function(result){
    console.log("1-2");
}).then(function(result){
    console.log("1-3");
});

p.then(function(result){
    console.log("2-1")
}).then(function(result){
    console.log("2-2");
}).then(function(result){
    console.log("2-3");
});
```

Chrome37の結果
-------------
以下のような感じ。それぞれが入れ子になりながら動いてる。

```text
start
1-1
2-1
1-2
2-2
1-3
2-3 
```

Firefox31の結果
--------------
以下のような感じ。先のチェーンが全部実行された後に次のチェーンが実行されている。

```text
start
1-1
1-2
1-3
2-1
2-2
2-3
```

で、どっちが正しいの？
------------------
[JavaScript Promiseの本](http://azu.github.io/promises-book/#promise-is-always-async) の本を見ると then は常に非同期で実行されるらしく、JavaScriptはキューに貯めてる動きなので、直感的には Chrome の動きのほうが正しく見えるのだが、いったいどっちが正しいんやろう？
商品アップロードAPI を利用してカテゴリ移動が正常に動作しない件

お世話になっております。
「商品移動API」があるのですが、操作ログとしてファイルを保存したい為に「商品アップロードAPI(type:4(項目指定)」でカテゴリー移動を行おうとしています。

処理自体は、正常終了になっているようですが、結果としてカテゴリー移動されません。
■アップロードファイル

```
path,name,code,price,sale-price
XXX,○○○○○○○○○○○○○○,9999,9999,999
ZZZ,△△△△△△△△△,9999,9999,999
```

■リクエスト内容

```
POST https://test.circus.shopping.yahooapis.jp/ShoppingWebService/V1/uploadItemFile?seller_id=セラーID HTTP/1.1
Authorization: Bearer アクセストークン
Content-Type: multipart/form-data; boundary=-16434562
Host: test.circus.shopping.yahooapis.jp
Content-Length: 252
Expect: 100-continue
-----------------------16434562
Content-Disposition: form-data; name="type"

4
-----------------------16434562
Content-Disposition: form-data; name="file"; filename="C:\Tmp\data_spy.csv"
-----------------------16434562--
```

■レスポンス内容

```
<?xml version="1.0" encoding="UTF-8"?>
<ResultSet>
  <Result>
    <Status>OK</Status>
  </Result>
</ResultSet>
```

レスポンス内容を見ても正常に終了しているように思われます。また、上記ファイルを、ストアクリエイター Pro からアップロードしたところ、正常に反映されましたので、ファイルの形式としては、問題無いように思います。

商品アップロードAPIの使い方が間違っており、カテゴリー移動には利用できないという仕様になっているということはありますでしょうか。

お手数ですが、上記利用方法又は仕様について、間違っている点があれば、教えていただけますでしょうか。

どうぞ、宜しくお願いいたします。
setuptoolsを使ったインストール時に任意の処理を実行する

setuptoolsを使ってPythonパッケージを作る際、「install実行時に任意の場所にディレクトリをコピーする」ということができなくて<sub>[1](#1)</sub>困ったので、強引にやってみた。

```python:setup.py
# coding: utf-8
import setuptools
from setuptools.command.install import install
import shutil

# 標準のinstallコマンドを拡張
class my_install(install):
  description = "install myapp"
  
  # 自分の処理に必要なオプションを追加
  user_options = install.user_options + [
    ('my-data-dir=', 'd', "base directory for installing my data files." ),
  ]
  def initialize_options(self):
    self.my_data_dir = '/opt/myapp-data' # デフォルト値を設定
    install.initialize_options(self)

  def _pre_install(self):
    # やりたいことを書く
    shutil.copytree('./data',self.my_data_dir)

  def run(self):
    # 本来のinstall処理の実行前に自分のやりたい処理を挟む。
    self._pre_install()
    install.run(self)

  def get_outputs(self):
    # get_outputsは--recordオプション指定時に呼ばれ、install時に作成したファイルとディレクトリのリストを返す。
    # pip uninstall をした時に削除してほしいものがあれば、ここで返すようにする。
    return install.get_outputs(self) + [self.my_data_dir]

setuptools.setup(
  name='myapp',
  version='1.0',
  description='my python application',
  author='kokm',
  author_email='xxx@xxx',
  url='http://xxx.xxx/yyy',

  # installコマンドを自分のものに差し替える
  cmdclass={'install': my_install},
)
```

`setuptools.command.install`を好きなように拡張して、`setup()`の`cmdclass`パラメータとして渡す。それだけ。
もちろん、install以外のコマンドも同様の方法で拡張できる。

# 実行方法
普通にsetup.pyを実行する。
追加したオプションは、`setup.py install --help`の出力にもしっかり反映されている。

```bash:
cd myapp
python setup.py install --my-data-dir=/opt/myapp-data
```

pipを使う場合は`--install-option`を使わないと自分で追加したオプションが通らないので注意。

```bash:
pip install --install-option='--my-data-dir=/opt/myapp-data' myapp-1.0.tar.gz
pip uninstall myapp
```

# 参考
<http://pythoninside.com/en/source-code/2.7.5/distutils/command/install.py>

<a name="1">1.</a> ファイル単位のコピーならinstall_dataを使うことで可能。
jq コマンドの Linux への速攻インストール

# CHANGES

1. **もうパッケージで簡単に入るからパッケージで入れればいいと思うよ**
1. jq 1.5 に対応

# やりかた

パッケージ
--------------

### CentOS 7

```
sudo yum -y install epel-release
sudo yum -y install jq
```

### Ubuntu 16.04（たぶん 18.04 も同じでは）

```
sudo apt -y update
sudo apt -y install jq
```

手動
-------------

### localがお好き

```bash
sudo curl -o /usr/local/bin/jq -L https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 && sudo chmod +x /usr/local/bin/jq
```

### localがおきらい

```bash
sudo curl -o /usr/bin/jq -L https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 && sudo chmod +x /usr/bin/jq
```

### 俺は Raspberry Pi (Raspbian) に入れたいんだ

[Raspberry Pi(Raspbian) に jq コマンドをインストールしてみた | Beyond Future Yak Shaving](https://blog.pg1x.com/2014/11/09/20141109232916/)
Django事始め その1


`Python3`をインストールした勢いで、`Django`のインストールに挑戦してみる。

##開発環境
PC: MacOS X 10.9.4
Python3.4.1
Django1.6.6

##Djangoのインストール

情報によると、`pip`というパッケージ管理ツールで`Django`がインストールできるようなので、軽く`pip3`コマンドを打ってみた。

※他にも`pip`を使用しない`django`のインストール方法(`git`や直接ダウンロード)があるようだ。

![スクリーンショット 2014-08-31 22.08.14.png](https://qiita-image-store.s3.amazonaws.com/0/3184/07ddf313-79ac-4ba2-fba9-22fd7ce35099.png "スクリーンショット 2014-08-31 22.08.14.png")

特に問題なく、あまりに呆気無く、いとも簡単にインストールされた。

##Djangoバージョンの確認

すんなりとインストールできてしまったので、お手本通りに確認してみる。

`$ python3 -c "import django; print(django.get_version())"`

上記は`Python3`コマンドで、直接スクリプトを実行している。
`django`パッケージをインポートして、`print`関数で`Django`のバージョンを出力している感じだろう。つまり、スクリプトとして正常に動作しているということだ。

もう一つのバージョンの確認方法として、`django-admin.py`スクリプトを使用した方法がある。

`$ django-admin.py --version`

![スクリーンショット 2014-08-31 22.37.41.png](https://qiita-image-store.s3.amazonaws.com/0/3184/edd9ea71-ba05-b478-235e-84309df95a27.png "スクリーンショット 2014-08-31 22.37.41.png")

一応、現時点(2014年8月末)最新バージョンである`Django1.6.6`がインストールされていることを確認できた。

##旧バージョンとのDjangoの関係

余談ではあるが、`python3`コマンドではなく、`python`コマンドを実行してみた。

![スクリーンショット 2014-08-31 22.44.25.png](https://qiita-image-store.s3.amazonaws.com/0/3184/f2dfbb99-b207-be04-f2eb-fd2700cb492c.png "スクリーンショット 2014-08-31 22.44.25.png")

予想通りに`django`モジュールが見つからないというインポートエラーとなった。
先程、`pip`ではなく`pip3`でインストールをしたことによって`python3`のパスに`Django`が正常なパスにインストールされていたことが理解できる。


##django-admin.pyスクリプト

最後に先程の`django-admin.py`をコマンド引数無しで実行してみた。

![スクリーンショット 2014-08-31 22.34.01.png](https://qiita-image-store.s3.amazonaws.com/0/3184/7fa7e429-f06b-bd4b-329a-0c81dcf7692c.png "スクリーンショット 2014-08-31 22.34.01.png")

今後使用するような、様々な`django`コマンド一覧が表示された。
だんだんと概要が見えてきて楽しみになってきた。

***Lovely Django!!***
Xamarinで遊ぶ(4) eventを試す

----
[←前](http://qiita.com/paming/items/682430866791dfba86e2) [次→](http://qiita.com/paming/items/f489df295f58c7bb490c)

[C#ラムダ式 基礎文法最速マスター](http://www.atmarkit.co.jp/fdotnet/rapidmaster/rapidmaster_01/rapidmaster_01.html)や、[プログラミングC#](http://www.amazon.co.jp/gp/product/4873116503/ref=pd_lpo_sbs_dp_ss_3?pf_rd_p=466449256&pf_rd_s=lpo-top-stripe&pf_rd_t=201&pf_rd_i=4873115175&pf_rd_m=AN1VRQENFRJN5&pf_rd_r=0T593CSQ2K5R9DZ3FDBH) を眺めながら、C#のeventを試していました。

```csharp:
	class MainClass
	{
		public class Hoge
		{
			// Actionの他に EventHandler<object o, EventArgs e> がある。
			public event Action<string> ActionHandler;
			// Actionは、 Action Action<T> Action<T1,T2> 〜 Action<T1...T16>まである。
			// http://msdn.microsoft.com/ja-jp/library/system.action(v=vs.110).aspx
			public void DoAction ()
			{
				if (this.ActionHandler != null) {
					// 1回の呼び出しに見えるが、実際には登録されたイベント全てが呼ばれる
					this.ActionHandler (@"call action.");
				}
			}
		}

		public static void Main (string[] args)
		{
			// ↓を参考にいろいろなイベント登録を試す
			// http://www.atmarkit.co.jp/fdotnet/rapidmaster/rapidmaster_01/rapidmaster_01.html
			// 
			Hoge hoge = new Hoge ();
			// Action<string> へのいろいろなイベント追加方法
			hoge.ActionHandler += m => Console.WriteLine (" event1 message=" + m);
			hoge.ActionHandler += (m) =>{
				Console.WriteLine (" event2 message=" + m);
			};
			hoge.ActionHandler += delegate(string m){ 
				Console.WriteLine (" event3 message=" + m);
			};
			hoge.ActionHandler += ActionHandlr4;
			hoge.DoAction ();

			Console.WriteLine ();
			// イベントの削除
			hoge.ActionHandler -= ActionHandlr4; // これは削除出来る
			// ラムダ式を指定いてもイベントは削除出来ない。同一かどうか判断つかないから当然
			hoge.ActionHandler -= m => Console.WriteLine (" event1 message=" + m);  // これは削除出来ない
			hoge.DoAction ();

			// クラスの外側から、eventを呼び出す事は出来ない
			// ↓はコンパイルエラーになる。
			// hoge.ActionHandlr ("hoge");
			// ↓取り出す事も出来ない（コンパイルエラー)
			// var actions = hoge.ActionHandler;
		}

		public static void ActionHandlr4(string m){
			Console.WriteLine (" event4 message=" + m);
		}
	}
```


- イベントの登録
    - +=演算子を使って複数登録できる
    - 登録出来る形は、ラムダ式や関数、delegateキーワード指定等。
        - ただしdelegateキーワードはラムダ式があるので使う場面は少なそう。
- イベントの削除
    - -=演算子で削除できる。
    - ラムダ式は、何らかの変数に代入（束縛？）して無いとイベントから削除できない。
- イベントはクラスの外側からはアクセスできない。 
    - += と -= でのアクセスに限定されている。
    - アクセスしようとしたら、コンパイルエラーになる。
- クラスの内側からイベントを呼ぶ時、１回呼ぶだけに見えるが、登録されたイベント全てが呼び出されている。
    - 順番については「登録順」に呼び出されているように見えるが、これに依存するロジックを作るとハマりそうな気がする。
- Actionには、引数無しから引数16個までのバリエーションがある。
    - http://msdn.microsoft.com/ja-jp/library/system.action(v=vs.110).aspx 
- C#の"デリゲート"と、objcの"デリゲート"は、別の概念。
    - C#のデリゲートは、"delegate"キーワードが用意されていて、「関数ポインタをオブジェクトで包んで、安全に使えるようにする仕組み」のように見える。
        - 言語仕様に組み込まれている
    - objcの"デリゲート"は、「あるクラスから各種判断を分離して別クラスに委譲するテクニック」と「委譲したクラスを参照するプロパティ名(delegate)」の事。
        - テクニックというか慣習。
一度のSQLで大量の未使用IDを取得する

大量のデータをインサートする際、パフォーマンス的な関係でメモリ上でゴニョゴニョしたものを`Prepared statement`使ってぶち込みたかったんだけど、
関連テーブルのデータを作るため、インサート前にIDが欲しかったので、ちょっと考えてみた

```sql
WITH RECURSIVE r AS (
  SELECT nextval('a_id_seq') AS id, 1 AS count

  UNION ALL

  SELECT nextval('a_id_seq'), count + 1
  FROM r
  WHERE count < 40000
)
SELECT id FROM r;
```

なにもないところから40000件のIDを生成することに成功しました
RECURSIVE 便利ー


# 追記

`generate_series`ならもっと簡単にできました。

```sql
SELECT nextval('a_id_seq') FROM generate_series(1, 40000);
```