OmniAICreator/Qiita-1.07M huggingface dataset:
物理演算エンジン、Matter.jsを使ってみた。


ゲーム作成に興味があったので、物理演算エンジン、Matter.jsを使ってみました。


## Matter.js
Matter.jsは物理演算が必要なアニメーションやWebゲームを作りたいときに使えるJSのライブラリのようです。

## インストール
まずは、本家サイトの手順（http://brm.io/matter-js/#usage） 通りに導入します。

```
<script src="matter.js" type="text/javascript"></script>
```
もしくは

```
bower install matter-js
npm install matter-js
```

## ボールを落とす
実行に必要なデモコードを書きます。

```
<!-- index.html -->

<main id="stage"></main>

<script src="js/matter-0.8.0.min.js"></script>
<script src="js/app.js"></script>
```

```
## app.js
(function() {

var Engine = Matter.Engine;
var World = Matter.World;
var Bodies = Matter.Bodies;

// Matter.js エンジン作成
var engine = Engine.create(document.body);

// 二つの箱(四角)と地面を作る
var boxA = Bodies.rectangle(400, 200, 80, 80);
var boxB = Bodies.rectangle(450, 50, 80, 80);

// isStatic:静的(完全固定)
var ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true });
 
// 二つの箱(四角)と地面を追加
World.add(engine.world, [boxA, boxB, ground]);
 
// Matter.js エンジン起動
Engine.run(engine);

})();
```

ボールが落ちてくるようになりました。

![2c0d0fcc308d3d847040b7e7cee562af.png](https://qiita-image-store.s3.amazonaws.com/0/74237/aba86e65-cd40-1476-ea96-2902543baa7f.png "2c0d0fcc308d3d847040b7e7cee562af.png")

バウンドさせたいときは、circleのオプションにあるrestitutionに任意の値を入れることで、バウンドさせることができます。

```
var boxA = Bodies.circle(375, 100, 50, {
    //バウンドさせたい場合はrestitutionに任意の値を渡す
    restitution: 0.9
}
```

![b9e451beee24553e77154976e8a441d2.png](https://qiita-image-store.s3.amazonaws.com/0/74237/89ae93ad-7ca0-003a-efae-66627ba25ae4.png "b9e451beee24553e77154976e8a441d2.png")

アニメーションの動きなどを意識せずに「ボールを落とす」という動きを実装することができました。
他、Matter.Bodyクラス、Matter.Engineクラス、Matter.Renderクラス、Matter.Vectorクラス、Matter.Commonクラスにて必要なAPIが用意されています（http://brm.io/matter-js-docs/index.html） 。回転量、速さ、マウスイベントなどを使用して、もっと色んなことができそうです。

以下作っているサンプルです。随時、更新していきます。
https://github.com/yhikishima/MatterJs-dev
 

### 【参考】
* [物理演算ライブラリ Matter.js に入門してみる](http://liginc.co.jp/web/js/other-js/155192)
* [物理演算エンジン「Matter.js」を使ってみた（スマホも対応）](http://vosegus.org/blog/2015/09/matterjs-bodies.html)
Unity Shaderことはじめ１ Shaderの追加と基本書式

# はじめに

好きな絵作りをするためにシェーダを書く必要が出てきたので勉強したときのメモ

Unityはシェーダを書いてすぐ確認できるのでUnityで勉強することにしたが、
Unityドキュメントで書式を把握するのは結構大変。

書式を気にせずサクッといじりたいのであればUnreal Engineのブループリントエディタで書くほうが楽な気もする。

# シェーダの追加

追加は簡単で、Assetフォルダで右クリックすればShaderを追加できる。
けどいきなり４種類も出てきて何がなんだか初めてのときはさっぱりわからん。

* Standard Surface Shader
* Unlit Shader
* Image Effect Shader
* Compute Shader

とあるが、上から順番にざっくりと

- Unity標準の物理ベースシェーディングの一部をいじるシェーダー
- 自力で全部書くシェーダー
- ポストエフェクトシェーダー
- コンピュートシェーダー

って感じ。

SurfaceShaderは面倒なライティングとかUnityが用意してくれるので楽チン。
UnlitShaderは全部自前でやるので面倒だけど好きに絵作りできる。
あと二つは名前の通り。

ちなみに別物シェーダーが生成されるのではなく書式テンプレが変わるだけなので、
Surface Shader生成したあとUnlit Shader書式に直せばUnlitで動く。

SurfaceShaderはUnityがコンパイルしていろいろやってくれるので
Unlitで使うPass{...}が使えなかったりするので注意。

# 自作シェーダーの適用方法

マテリアルを生成して自作シェーダーをD＆D等で指定すればよい。
Assetフォルダにマテリアルを置いたり、スクリプト上で実行時にマテリアルを生成してシェーダを割り当てたりする。
後者はImage Effect Shaderでよく使う割り当て方。

# 参考になるもの

基本だけどUnity > Standard Assetsにあるシェーダーが一番確実な資料。
Unlit > TextureとかImage Effect > Blurとか見てみるとよい。

# ざっくりとしたシェーダー構成

```
Shader "グループ名/シェーダー名" {
  //Inspectorと連携する入力パラメータ
    Properties {
        //入力テクスチャ 場合によっては自動割り当て
        _MainTex ("Texture", 2D) = "white" { }
        // other properties like colors or vectors go here as well
        //色
        _Color ("Color", Color) = (1,1,1,1)
        //小数値
        _Value ("Value", Float) = 1.0
    }
    //シェーダー実装１
    SubShader {
        CGINCLUDE
        //この間にパス共通設定記述
        ENDCG
        
        //頂点シェーダー等記述。書式はsurfaceやunlitで違う
    }
    //シェーダー実装2 実装1が使えないときはこっちが使われる
    SubShader {
    }
}
```

# Shaderの座標系

## 頂点シェーダー

頂点単位で処理される。
頂点情報はローカル座標系で渡されるのでMVP変換してビューポート座標系に変換して返す。

## サーフェイスシェーダー
## フラグメントシェーダー

頂点情報で決定された描画ピクセル毎に処理される。
ウィンドウ座標系な値を取得することもできるが、
基本的に頂点シェーダーで計算した法線やuv値の補間値を使うことになる。

# Shaderのパス

パス１で黒塗りして、パス２で本書きとパスで複数回描画指定ができる。
１シェーダーに複数機能をもたせたいときは多パス記述しておいて、スクリプトで描画のときどのパスを使うか指定したりする。

モデルに黒縁をつける絵作りでは

- Pass1 頂点を法線方向に膨らませて裏面黒塗り
- Pass2 通常描画

という２パス描画が簡単な方法として使われる。

# SurfaceShaderの複数パス

SubShader内に複数描画処理(パス)を書く際はCGPROGRAM〜ENDCGで囲む
```
SubShader{
  //1パス目
  CGPROGRAM
  ...
  ENDCG
  //2パス目
  CGPROGRAM
  ...
  ENDCG
```

# UnlitShaderの複数パス

SubShader内に複数描画処理(パス)を書く際はPass{...}で囲む
```
SubShader{
  //1パス目
  Pass {
    CGPROGRAM
    ...
    ENDCG
  }
  //2パス目
  Pass {
    CGPROGRAM
    ...
    ENDCG
  }
```
iTermやターミナルでAquaSKKの日本語入力を有効にするには

なんか巷には色々なやり方をご紹介いただいておりますが、どうもどれをやっても上手いこといかなかった。

結局、AquaSKKのキーバインドを直接設定することで回避したので、その手順をメモっておく。

## AquaSKKの設定ファイル

`/Library/Input\ Methods/AquaSKK.app/Contents/Resources/keymap.conf` にある。

これを、

`~/Library/Application\ Support/AquaSKK/keymap.conf` にコピーする。

## keycap.confの変更

```conf:keymap.conf
# ======================================================================
# event section
# ======================================================================

SKK_JMODE		ctrl::j
```

ってなってるのでここを、

```conf:keymap.conf
# ======================================================================
# event section
# ======================================================================

SKK_JMODE		ctrl::j||ctrl::0
```

ってした。

他にも何通りか試したが、数値のゼロぐらいしかいい感じのキーが無かったので、とりあえずこれにしとく。

まあせやけど、 `Ctrl+J` が一番慣れてるさかいに、不便っちゃ不便やけどもね。

以上です。
Swiftの超基本的な書き方をObjective-cと比較しながらまとめる

# 概要
毛嫌いしていたSwiftをついに触り始めました。
アプリを実際に作りながら学んでいるのですが、超基本的な部分の書き方を自分の為にもメモしておきます。
そろそろSwiftやり始めるか…！という人の為になれば幸いです。

# 変数/定数宣言
```lang:Objective-c
// 変数
NSString *name1 = @"mizuno";

// 定数
const NSString *name2 = @"takagi";
```

```lang:Swift
// 変数
var name1 = "mizuno"
var name1: String = "mizuno" //型も指定出来ます
var name1: String? // optional型での宣言方法
var name1: String! // optional型での宣言方法

// 定数
let name2 = "takagi"
```
**ポイント**
・Swiftは型指定無しでも変数/定数宣言出来ます(型推論)
・「*」はいらなくなりました

**差に驚いたこと**
・Stringの時に「@」を付けなくても良くなった
・そもそもセミコロンつけなくても良い
・「var」で宣言した変数に値を代入を一度もしないと「letにしろ！」って怒られる
・「?」とか「!」とかついてる！

**optional型について**
Swiftが良いとされている理由の1つがこのoptional型であり、これがあることで
堅牢なコードがかけると言われています。
これについては書くとめちゃくちゃ長くなるので、私が参考にしてわかりやすかったページを載せておきます。

・どこよりも分かりやすいSwiftの"?"と"!"
http://qiita.com/maiki055/items/b24378a3707bd35a31a8

・[Swift] Optional型についてのまとめ
http://qiita.com/cotrpepe/items/e30c7442733b93adf46a

結構ややこしいのですが、optional型は「包み紙」という表現が結構自分の中ではしっくりきているので、それをイメージするとすごくわかりやすいかもしれません。

# 関数
```lang:Objective-c
- (BOOL)isValid:(NSString *)word {
    return NO;
}

- (void)didTapButton {
    if(![self isValid:word])
      return;
}
```
```lang:Swift
func isValid(word :String) -> Bool {
    return false
}

func didTapButton() {
    if !self.isValid(word) {
       return
    }
}
```

**ポイント**
・引数と返り値を書く場所が違うので注意
・メソッドの呼び出し方が違うので注意

**差に驚いたこと**
・Swiftではoverrideしているメソッドはfuncの前にoverrideをつけないとオーバーライドしていることにならないので必ずつけなければならない
・Swiftでは返り値を省略して書ける(でも引数はvoidの場合()で書かないとだめっぽい)
・if文の{ }を省略できない

# クラス
```lang:Objective-c
@interface MyClass : NSObject<MyDelegateSampleDelegate>
@end

/* クラスの実装部 */
@implementation MyClass : NSObject
@end
```
```lang:Swift
class MyClass:MyDelegateSampleDelegate{

}
```

**ポイント**
・Swiftは.hと.mがわかれていない
・プロトコルなどはclass宣言の後に書く

**差に驚いたこと**
・書き方が結構違うので最初普通に戸惑う(property宣言とかないし)


#終わりに
基本的なiOSの動きは変わっていないので、記法だけ慣れてしまえばある程度書けそうです！
(実際にアプリもかんたんなサンプルはすぐに作れました)
ただSwiftで出来る事が結構増えた気がするので、そこをしっかり抑えると
よりイケてるコードが書けそう。。

optional型については結構理解がしんどいかもしれませんが、
いろんな解説サイトを巡回したり、実際に書いて出るエラーを読んで潰そうと動かしてみるのが
理解を深めるのに良さそうです！
hubotでscriptを書いてみる

#はじめに
hubotでscriptを書くときのお約束とかの私の私による私のための覚書

#respondとhearの違い
* respondは呼びかけに反応

```
module.exports = (robot) ->
  robot.respond /いぇいいぇい/i, (res) ->
    res.send "いぇいいぇい"
```
って時は

```
Kiriko: @hubot いぇいいぇい
Hubot: いぇいいぇい
Kiriko: いぇいいぇい
```

ッて感じで、呼びかけないと返答がない

* hearは発言の内容に反応

```
module.exports = (robot) ->
  robot.hear /いぇいいぇい/i, (res) ->
	res.send "いぇいいぇい"
```

って時は

```
Kiriko: @hubot いぇいいぇい
Hubot: いぇいいぇい
Kiriko: いぇいいぇい
Hubot: いぇいいぇい
```

ッて感じで、呼びかけても呼びかけてなくても反応が帰ってくる
hearを使うと他の人との会話の中に該当の言葉が入ってたら割り込んでくる感じかな

#replyとsendの違い

```
module.exports = (robot) ->
  robot.respond /いぇいいぇい/i, (res) ->
	res.reply "いぇいいぇい"
```
って時は

```
Kiriko: @hubot いぇいいぇい
Hubot: @Kiriko いぇいいぇい
```

ッて感じで、メンションをつけて返してくれる

* hearは発言の内容に反応

```
module.exports = (robot) ->
  robot.respond /いぇいいぇい/i, (res) ->
	res.send "いぇいいぇい"
```

って時は

```
Kiriko: @hubot いぇいいぇい
Hubot: いぇいいぇい
```

ッて感じで、ただ発言するだけ
respondの時にsendで書いてると悲しくなりますね

今日はここまで随時更新してゆきます
CircleCIからAWS Lambdaファンクションをデプロイしてみた


# 前提条件
[AWS LambdaファンクションをGulpでデプロイ](http://dev.classmethod.jp/cloud/aws/how-to-deploy-a-lambda-function-with-gulp/)でローカルでデプロイできている前提


# IAMの設定

## Lambda実行用のロール
* ロール名（例）
 * sampleLambdaExecureRole
* アタッチするポリシー
 *  AWSLambdaExecute

作成したロールARNをメモっておく

* ロールARN（例）
 * arn:aws:iam::000000000000:role/sampleLambdaExecureRole

## デプロイ用のポリシー

* ポリシー名（例）
 * sampleLambdaDeployPolicy

* ポリシードキュメント（例）
 * iam:PassRoleのResourceはLambda実行用のロールのARNを指定する

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "lambda:CreateFunction",
                "lambda:GetFunction",
                "lambda:UpdateFunctionConfiguration",
                "lambda:UpdateFunctionCode",
                "lambda:UpdateEventSourceMapping",
                "lambda:CreateEventSourceMapping",
                "lambda:ListEventSourceMappings"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::000000000000:role/sampleLambdaExecureRole"
            ]
        }
    ]
}
```

## デプロイ用のユーザー
* ユーザー名（例）
 * sampleLambdaDeployUser
* ユーザーごとにアクセスキーを生成
	* チェックを入れる
* 認証情報をダウンロードする
* ポリシーのアタッチ（先ほどさくせいしたポリシー）
	* sampleLambdaDeployPolicy

# ソースコード
[AWS LambdaファンクションをGulpでデプロイ](http://dev.classmethod.jp/cloud/aws/how-to-deploy-a-lambda-function-with-gulp/)を参考に下記の点を変更する

変更後のソースはこちら
https://github.com/tomiyan/lambda-gulp-sample

circle.ymlを追加

```yaml:circle.yml
deployment:
  production:
    branch: master
    commands:
      - gulp deploy
```

lambda-config.jsのroleをenvから取得するように修正

```javascript:lambda-config.js
module.exports = {
  region: 'ap-northeast-1',
  handler: 'index.handler',
  role: process.env.ROLE,
  functionName: 'api_v1_hoge',
  timeout: 10,
  memorySize: 128,
  runtime: 'nodejs'
  // eventSource: {
  //  EventSourceArn: <event source such as kinesis ARN>,
  //  BatchSize: 200,
  //  StartingPosition: "TRIM_HORIZON"
  //}
}
```

githubにホスティングする

# CircleCI

すでにSign Upしている前提
## プロジェクトの追加
* Add Projects
 * GitHubアカウントを選択
 * 今回作成したProjectを選択
* Project Settings
	* Environment variables
		* Name
			* ROLE
		* Value（例）
			* arn:aws:iam::000000000000:role/sampleLambdaExecureRole
	* AWS keys
		* デプロイ用のユーザーで作成した認証情報Access Key ID/Secret Access Keyを登録


# 参考文献
* [AWS LambdaファンクションをGulpでデプロイ](http://dev.classmethod.jp/cloud/aws/how-to-deploy-a-lambda-function-with-gulp/)
Ubuntu デスクトップで使える Better Touch Tool 的ウィンドウ移動&リサイズ

Ubuntu の Unity デスクトップ環境が対象。

ここで Better Touch Tool (BTT) 的ウィンドウ移動 & リサイズと言っているのは、具体的には以下 2 つ。マウスカーソル下のウィンドウに対し、

1. タイトルバーに限らずどこをポイントしていてもドラッグでウィンドウ移動ができる
- ウィンドウの端に限らずどこをポイントしていてもドラッグでウィンドウのリサイズができる


デフォルトでは

- 1. は `Alt` + 左ボタンドラッグ
- 2. は、`Alt` + 中ボタンドラッグ

でできる。便利。

キーバインディングを変更したい場合は、`dconf-editor` 等を用いて `/org/gnome/desktop/wm/preferences/mouse-button-modifier` の値を書き換えればよい。
詳細はこちら → http://askubuntu.com/questions/521423/how-can-i-disable-altclick-window-dragging
Timerを使ったループで誤差が蓄積しないようにする

System.Timers.Timerの精度
========================
WEBで検索すればすぐ出てきますが、`System.Timers.Timer`の精度は数10msです。
誤差があるのは分かっているので それはいいのですが、
この誤差、0を中心に±両方向に分布していて平均すると0付近になるのかな～と思ったら
往々にして＋方向にズレ(環境によると思いますが)、且つ誤差は蓄積していくようです。
以下は`Interval=1000`にして1秒毎に`DateTime.Now`の時間を表示してみた結果です。
自宅のPCだと1ms程度の誤差ですが、会社のPCでは20ms程度の誤差が蓄積していきました。

```sh:before
2015/11/23 22:14:31.429
2015/11/23 22:14:32.429
2015/11/23 22:14:33.430
2015/11/23 22:14:34.430
2015/11/23 22:14:35.433
2015/11/23 22:14:36.434
2015/11/23 22:14:37.434
2015/11/23 22:14:38.435
2015/11/23 22:14:39.435
2015/11/23 22:14:40.436
2015/11/23 22:14:41.436
2015/11/23 22:14:42.437
2015/11/23 22:14:43.437
2015/11/23 22:14:44.437
2015/11/23 22:14:45.437
2015/11/23 22:14:46.438
2015/11/23 22:14:47.438
2015/11/23 22:14:48.438
2015/11/23 22:14:49.439
2015/11/23 22:14:50.440
```
これだと都合が悪い場合があったので、どうしたもんか…と考えた結果
このようなwrapperを作ってみました。

```csharp:MyTimer.cs
namespace Utils
{
    public class MyTimer
    {
        private System.Timers.Timer timer;
        private Int64 lastTime;

        public Boolean AutoReset;
        public Double Interval;
        public event System.Timers.ElapsedEventHandler Elapsed;

        public MyTimer()
        {
            this.timer = new System.Timers.Timer();
            this.timer.AutoReset = true;
            this.timer.Interval = 1;
            this.timer.Elapsed += (o, e) =>
            {
                if ((DateTime.Now.Ticks / 10000 - this.lastTime) >= this.Interval)
                {
                    System.Threading.ThreadPool.QueueUserWorkItem((state) => this.Elapsed(o, e));
                    this.lastTime += (Int64)this.Interval;
                    if (!this.AutoReset)
                    {
                        this.timer.Stop();
                    }
                }
            };
        }

        public MyTimer(Double interval) : this()
        {
            this.Interval = interval;
        }

        public void Start()
        {
            this.lastTime = DateTime.Now.Ticks / 10000;
            this.timer.Start();
        }

        public void Stop()
        {
            this.timer.Stop();
        }
    }
}
```

本来設定したい`Interval`より充分短い間隔で経過時間を観測し、
期待する時間が経過したら`Elapsed`に設定された処理をするだけですが、
誤差が蓄積せずループを回すことができました。
`Utils.MyTimer`を使った場合の結果

```sh:after
2015/11/23 22:16:23.806
2015/11/23 22:16:24.806
2015/11/23 22:16:25.805
2015/11/23 22:16:26.806
2015/11/23 22:16:27.806
2015/11/23 22:16:28.805
2015/11/23 22:16:29.805
2015/11/23 22:16:30.806
2015/11/23 22:16:31.806
2015/11/23 22:16:32.805
2015/11/23 22:16:33.806
2015/11/23 22:16:34.805
2015/11/23 22:16:35.805
2015/11/23 22:16:36.806
2015/11/23 22:16:37.806
2015/11/23 22:16:38.805
2015/11/23 22:16:39.806
2015/11/23 22:16:40.805
2015/11/23 22:16:41.806
2015/11/23 22:16:42.805
```

もっと精度よくループを回したければ`System.Timers.Timer`で経過時間を監視しているところを別Threadで監視するとか、
経過時間取得部分を`System.Diagnostics.Stopwatch`で取る
(高分解能パフォーマンスカウンタが使用可能な場合は内部的に`QueryPerformanceCounter`使われるらしいので)
などすれば良いかも。

ただ、自分の環境では`System.Diagnostics.Stopwatch`の使用ではそんなに良い結果を得られませんでした。
まぁ`DateTime.Now`の精度がどうなの?って感じで、何を測ってるのか分からないのでアレですね。

今回はこれで自分が求める結果が得られたので良しとします。
S3 に画像をアップロードしたら Lambda で WebP を生成する (node-webp)

AWS Lambda with Node.js で S3 におかれた画像を即座に WebP に変換する関数を作りました。画像や画質の設定にもよりますが、同じクオリティの JPEG 比でだいたい半分くらいの容量になります。

* [lambda-webp-converter](https://github.com/ikait/lambda-webp-converter)

たとえば `s3://a/b/c.jpg` にアップロードされたら、 `s3://a/b/c.webp` が生成されるようなイメージです。

# cwebp を用意する

WebP を生成するにあたって、[cwebp](https://developers.google.com/speed/webp/docs/cwebp) をラップしたライブラリ [node-webp](https://www.npmjs.com/package/cwebp) を使います。node-webp は、cwebp をラップするライブラリで、

* cwebp
* libwebp.so.5

の 2 つが必要です。Lambda はこの 2 つをデフォルトで持っていないので、デプロイ時に zip の中に含めておいて、コードの中でこちらを参照するようにしています。

```javascript:es6
if (!fs.existsSync("/usr/local/bin/cwebp")) {
    const LIB_DIR = path.join(__dirname, "lib");  // ここに cwebp と libwebp.so.5 をおいた
    process.env.PATH += `:${LIB_DIR}`;
    process.env.LD_LIBRARY_PATH += `:${LIB_DIR}`;
}
```


# Lambda でのバイナリの扱い

Lambda は Amazon Linux で稼働するので、Mac でコンパイルしたバイナリは実行できません。なので、EC2 や docker などで予め `cwebp` と `libwebp.so.5` を生成しておく必要がありました。

# 使ってみる

"サンプル画像"でググッて一番上にきた画像を拝借して変換してみます。

![a.jpg](https://qiita-image-store.s3.amazonaws.com/0/14941/3a5eb263-1717-711a-14b6-8679c88166b0.jpeg)
<sub>引用:  http://wwwjp.kodak.com/JP/images/ja/digital/digitalcamera/standard/c330/sample/C330_02.jpg)</sub>

## 2304×1728 の場合
```
Duration: 8041.82 ms    Billed Duration: 8100 ms     Memory Size: 128 MB    Max Memory Used: 48 MB
```

最小の 128 MB インスタンスでだいたい 8 秒くらい。

## 640×480 の場合

```
Duration: 2305.42 ms    Billed Duration: 2400 ms     Memory Size: 128 MB    Max Memory Used: 30 MB
```

おなじく 128MB のインスタンスで、2.5秒くらい。

# 感想
若干時間はかかりましたが、多くの場合、EC2 で変換サーバを立てるよりはきっとお手軽・お手頃でお財布にも優しいはず。たとえば東京リージョンにおける 128MB の Lambda 関数は 100ms あたり $0.000000208 (2015/11/12現在) なので、1ドル120円としたら、ざっくりとした計算で 640x480 の変換は1枚あたり 0.00059904 円です。無料利用分を考えると、100万枚の変換までは 0 円で利用できます。

Lambda には[同アカウント同リージョンで同時に 100 インスタンスまで立てられない](https://aws.amazon.com/jp/lambda/faqs/#scalability)という制限はありますが、この制限を超えたとしても、S3 からのイベントでは 24 時間リトライしてくれるので、変換できる画像であれば確実に変換してくれるはず。

バッチ処理で s3 にアップロードした画像を webp にも変換しておく、ような使い方にもあっているのではないかと思います。

以下のようなサムネイル生成と組み合わせることで、サムネイルを生成 + WebP も用意、というフローもかんたんに実現できます。

* [S3に画像をアップロードしたらLambdaでサムネイルを生成する(node-imagemagick)](http://qiita.com/ryo0301/items/7f9fd8024987526cbc30)
Unity5からCeVIOのささらさんに喋ってもらう

unity5でCevio Creative Studio Sをリモートして
ささらさんに喋ってもらうことが出来たので
やり方紹介

#CeVIO Creative Studio Sとは
初音ミクのような歌やしゃべりが作れるソフトウェアのようなもので
ささらさんやIAさんが有名ではないでしょうか。
特に歌に関しては驚くぐらい人っぽいです。

#今回作ったもの
<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr">寝落ちから起きて寝れなかったから&#10;unityからdocomo雑談API叩いて、&#10;ささらさんと雑談するの作ってた。&#10;マイク小さい… <a href="https://t.co/uAUiISSLAS">pic.twitter.com/uAUiISSLAS</a></p>&mdash; 光輝@ｷｯｸｽﾀｰﾀｰで貯金0 (@koukiwf) <a href="https://twitter.com/koukiwf/status/668526174138560512">2015, 11月 22</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

#おおまかな流れ
1.unityからdocomo雑談apiに文字投げる
2.返ってきた文章をコンソールアプリに投げる
3.コンソールアプリがCevioにリモート掛けて発話させる

今回は2.のコンソールアプリとunityからの呼び方について。

#CeVIOのインストール
http://cevio.jp/downloads/
ここからダウンロードしてインストールして下さい。
一ヶ月体験版使えます。体験版でリモートも試せます。
*ボーナス出たらONEちゃんトークスターター製品版買います。*
**ボーナス出てないけど買いました！！**

#CeVIOの外部連携
Cevioは外部連携機能が提供されています。
[外部連携インターフェース-CeVIO](http://guide2.project-cevio.com/interface)
『③.NETアセンブリとして利用』を今回は使います。

#コンソールアプリの作成
unity5をインストールするとVS2015もインストールされるのでそれで作成します。
ちなみにdllをunityに入れても.netバージョンが違うため、使えません。

『③.NETアセンブリとして利用』ページにサンプルがあるので
C#でコンソールアプリにして下さい。して下さい。
args[0]をとりあえず発話文章に。
最後のホスト終了は削っといたほうが楽です。

#unityからコンソールアプリケーションの呼び出し
[[Unity] UnityからVOICEROIDの呼び出し: ちょむメモ（仮）](http://chomstudio.sblo.jp/article/106248994.html)
こちらのサイトを参考にしました。参考というかexeパス変えるだけなんですが。

#これから
モデル出して口パクは先行研究があるので
<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr">絶賛迷走開発中... MMD4Mecanim <a href="https://t.co/fuyiUhdHEW">https://t.co/fuyiUhdHEW</a> と MMD4Mecanim-LipSync-Plugin <a href="https://t.co/eeJQNWK49K">https://t.co/eeJQNWK49K</a> モデルはお宮式のものを使ってます <a href="https://t.co/SU3awk7Ajc">pic.twitter.com/SU3awk7Ajc</a></p>&mdash; tatsuro matsubara (@blkcatman) <a href="https://twitter.com/blkcatman/status/667670070022156288">2015, 11月 20</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
組み合わせていきたいですね。
出来ればキャラ設定した雑談APIでネット上のNPCにしてみたい。
ライセンス難しいけど。
gitignoreの雛形を用意する

プロジェクトを新規に作成するときに、gitignoreの中身を作るのがちょっと面倒。
そんなときは、[gemignore](https://rubygems.org/gems/gemignore
)を使うと良さそう。github/gitignoreに保存されている様々なgitignoreを取り込むことができます。

# インストール方法

gemでインストールします。gemのインストールはネットでいっぱいあるので調べてみてください。

```
$ gem install gemignore
```

# 使い方
例：swiftプロジェクトの場合

```
$ cd xcodeのプロジェクトルート
$ touch .gitignore
$ gemignore add swift
```

これで.gitignoreがこんな感じになります。

```sh:.gitignore
# Added by gemignore. Snippet 'Swift'
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

## Build generated
build/
DerivedData

## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata

## Other
*.xccheckout
*.moved-aside
*.xcuserstate
*.xcscmblueprint

## Obj-C/Swift specific
*.hmap
*.ipa

# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/

# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts

Carthage/Build

# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md

fastlane/report.xml
fastlane/screenshots
```
line monitor > 情報表示部分 (v0.0) > ７セグメンLED

RPi2のIPアドレスに関して、最後の３桁だけでも分かれば便利だ。

表示方法について考えたところ、7セグメントLEDを使うのがいいかもと思い始めた。
特殊なドライバが必要でないのが大きな理由。

親切な店員に教えてもらい、以下を購入した。2セットで260円.

- 集合抵抗 1kΩ (カソードコモン)
- 高輝度赤色LED

このあたりを勉強して7セグメントLEDを使ってみる。
http://www.kotaden.com/stage3_3_index.html
ネームサーバーを変更する

# はじめに
昨今のLinuxは、サービスの起動・管理にsystemdという名前のソフトウェアが採用されています。これまではupstartという名前のソフトウェアが主流でしたが、現在は大半のLinux系OSがsystemdを採用しているので、systemdの仕様に慣れる必要があります。

upstartにおけるサービスの起動等

```lang:upstart
$ service サービス名 start/restart/stop
または、
$ /etc/init.d/サービス名 start/restart/stop
```

systemdにおけるサービスの起動等

```lang:systemd
$ systemctl start/restart/stop サービス名
```

# ネームサーバーを変更する
`/etc/systemd/resolved.conf`のDNSディレクティブのコメントを外し、参照したいネームサーバを追記することで設定を変更することができます。例えば、BIND, dnsmasq, unboundなどのDNSサービスが起動しているサーバのアドレスが192.168.0.2だとすると下記のように記述します。

```lang:/etc/systemd/resolved.conf
#  This file is part of systemd.
# ...
# See resolved.conf(5) for details

[Resolve]
DNS=192.168.0.2
#FallbackDNS=
#LLMNR=yes
```

systemdにおいて、名前解決を管理しているサービスを再起動します。

```
$ systemctl restart systemd-resolved.service
```

以上で参照するネームサーバの修正は完了です。
名前解決が反映されない場合は、ネームサーバ側のDNSサービスを再起動すればうまくいくようになるかもしれません。

以下の項目は補足です。

# systemdにおけるresolv.conf
systemdにおいて`/etc/resolv.conf`は、`/run/systemd/resolve/resolv.conf`へのシンボリックリンクとなっています。`/etc/resolv.conf`を修正してもその変更は反映されません。

```
 $ ls -l /etc/resolv.conf 
lrwxrwxrwx 1 root root 34 Nov 19 10:31 /etc/resolv.conf 
 -> ../run/systemd/resolve/resolv.conf
```

systemdにおけるresolv.confの実態は、`/run/systemd/resolve/resolv.conf`です。ただし、/etc/resolv.conf`と同じようにこのファイルを直接修正してもその変更は反映されません。

```lang:/run/systemd/resolve/resolv.conf 
# This file is managed by systemd-resolved(8). Do not edit.
#
# Third party programs must not access this file directly, but
# only through the symlink at /etc/resolv.conf. To manage
# resolv.conf(5) in a different way, replace the symlink by a
# static file or a different symlink.

nameserver 192.168.0.1
```

# systemd-resolved.service
systemdでは、Unitという単位で処理を管理し、Unitの定義ファイルは、`/usr/lib/systemd/system`ディレクトリに保存されています。Unitに関する詳細は[こちら](http://enakai00.hatenablog.com/entry/20130914/1379146157)をご参照ください。
`/run/systemd/resolve/resolv.conf`を見ると冒頭部分に「This file is managed by systemd-resolved(8).」と書いてあるので、ネームサーバに関する設定はsystemd-resolvedによって管理されていることがわかります。
[公式ドキュメント](http://www.freedesktop.org/software/systemd/man/systemd-resolved.service.html)によると、参照するDNSサーバ（ネームサーバ）は、下記の３つから決定されると書いてあります。いづれかの方法でDNSサーバの参照先を変更することができます。

- [ ] /etc/systemd/resolved.conf
- [ ] /etc/systemd/network/*.network
- [ ] DHCP

# 最後に
systemdにおけるサービスの管理詳細は、主に[こちら](http://www.freedesktop.org/software/systemd/man/index.html)の公式ドキュメントに記載されています。
vagrant-centos6-php & Netbeans でデバッグできるようになるまで

# vagrant-centos6-php & Netbeans でデバッグできるようになるまで
## なりゆき
趣味で PHP をいじりたく、フレームワークを探していた。　FuelPHP が軽快らしくためしてみることに。　ローカルで作業するので vagrant で動かす。
ネットでしらべたところよさそうなプロジェクトを見つけた。   
[vagrant-centos6-php](https://github.com/kenjis/vagrant-centos6-php/blob/master/README.ja.md)  
これで最初のページを表示し Netbeans でデバッグできるようになるまで幾つか躓くことがあった。

## 最初の関門
**※ここは記憶が曖昧で内容が正しくない可能性あり。　確認しようと一度 box を destroy して作りなおしてみたら最初のページは何もせずに表示されたため再現できなかった**  
Vagrantfile で fuelphp を選択して up し、取説の「プロジェクトへのアクセス方法」にならってアクセスすると "No composer autoloader found. Please run composer to install the FuelPHP framework dependencies first!" というメッセージが出てきた。　これはインストールの際に Composer が GitHub API を用いており、GitHub API は時間あたりのアクセス数を制限しており、制限に引っかかるとこのメッセージが表示される。　ここはググると出てくる他のサイトに書いてあるように GitHub の自分のアカウントの設定ページからトークンを作成してインストールでトークンを求められた時に貼り付ければ OK。

## デバッグの準備
このページにならって設定したが Netbeans でデバッグを実行すると「接続を待っています」という状態でブレークポイントにも引っかからずうまくいかなかった。　xdebug はインストール済みだったので「php.iniの設定」のみ行った。  
[Vagrantで起動したPHP環境をNetBeansからリモートデバッグする方法](http://little-braver.com/585/)

色々試した結果、以下の設定でうまくデバッグ出来るようになった。　デバッグ状態でデバッグしたいページを開くと、そのページにブレークポイントが設定されていればそこで止まる。

    zend_extension="/usr/lib64/php-zts/modules/xdebug.so"
    xdebug.remote_enable=1
    xdebug.remote_connect_back=1
    xdebug.remote_autostart=on
    xdebug.idekey="netbeans-xdebug"

プロジェクトツリーのファイルを右クリックで出るメニューからの、ファイルを指定してのデバッグは fuel/app/classes/controller がパスに挟まるせいか機能しなかった。

あと、色々試している際、apache を再起動する際にいちいち

    Starting httpd: httpd: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain for ServerName

とうるさいので /etc/httpd/conf/httpd.conf に ```ServerName localhost.localdomain:80``` という記述を追加しといた。
line monitor > UI部分(v0.4) > 設定パネルの追加 > combaud / SendMe

line monitor
http://qiita.com/7of9/items/028556c5a819a6a8de96

```txt:環境
実装 Unity 5.1.3-f1 on MacOS X 10.8.5
動作 304SH
```

## プログラム
[v0.4 @ github](https://github.com/yasokada/unity-151117-linemonitor-UI/releases/tag/v0.4)

モニタ画面と設定画面の２パネル構成にした。
設定に関する通信処理を実装した。

設定画面においてはcombaudを設定可能。
また、SendMeボタンを押すことで、モニター先IPとポートをそのスマホのものに設定する。

## 画面

上部のMonitorとSettingボタンでパネルを切換する。
( [この実装](http://qiita.com/7of9/items/dae913ed10c0975b4757)を利用 )

<img width="350" alt="ファイル名" src="https://qiita-image-store.s3.amazonaws.com/0/32870/a9099919-d14b-7694-dfdf-b0a2b90935ca.png">

<img width="350" alt="ファイル名" src="https://qiita-image-store.s3.amazonaws.com/0/32870/46bbdff7-f802-83ec-ab84-d04f6dd2cf4b.png">

RPi2でなく、CentOS上にてdummySerialを有効にして動作確認した。


これで、以下の接続形態のCentOSが304SHでできるようになった。
[block diagram @ mindmup](https://atlas.mindmup.com/2015/11/081fb6b072650133ca0d378ca51caa79/linemonitor_blockdiagram_151121/index.html)

RPi2を使った動作確認ができた。
またTeraTermのCRLF設定を忘れて手間取った。初期設定を変更しないと失敗ばかりする。
Excel方眼紙を支える技術2016

POIを使ったExcel帳票の出力は、システムエンジニアにとっては日常茶飯事、おちゃのこサイサイであります。

## Excel方眼紙を支える技術

takezoen先生による2015年版はこちらになります。
[![image](https://qiita-image-store.s3.amazonaws.com/0/8475/c0f5bc59-ee25-a743-9e9c-ac94cbc2818a.png)]
(http://www.slideshare.net/takezoe/exceljava2015)

ここで紹介されている、S式からExcel方眼紙を出力するライブラリaxebomber-cljは、こちらをご覧ください。

http://qiita.com/kawasima/items/60197799a7990c578263

特筆すべきはaxebomber-cljでは、Excelにありがちな文字切れが起こらないというところです。そもそもExcel方眼紙は、入力文字列が自動改行されない制約を設けて、利用者が意図的な位置で改行をコントロールするために発明されたフォーマットであります。しかし、その特異な見た目が災いし、単に敬遠される存在にとどまっております。axebomber-cljは、文字幅とセル幅を計算し、文字切れしない位置で自動的に改行するようにしています。これにより、Excel方眼紙の文字切れしにくさを活かしつつ、煩わしさを消しているわけです。

```clj
(render sheet {:x 2 :y 12 :data-width 6}                                                                      
        "長い文字列は自動的に改行されます。非常に便利ですね！")
```

文字列が長くても… 以下のとおり、決められたサイズを超えると自動で改行されるわけです。

![image](https://qiita-image-store.s3.amazonaws.com/0/8475/d47a6349-237b-d357-5b16-1b55fe3c62bd.png)

### 自動改行のために

等幅フォントならまだ簡単ですが、見栄えのするExcel方眼紙はやはりプロポーショナルを使ったものです。

```clj
(defn string-width [s font]
  (if (> (.length (str s)) 0)
    (let [layout (TextLayout. (.getIterator (make-attributed-string (str s) font))
                            font-render-context)]
      (.. layout getBounds getWidth))
    0))
```

java.awt.TextLayoutを使って、実際のフォントで文字列幅を計算し、セル幅と比較しながら改行を入れていくことで、自動改行が実現できます。

### 正確な方眼を作る

由緒正しいExcel方眼紙は、セルが正方形であることが条件ですが、セル幅はフォントサイズによって変わってきます。

[POIを使ってみる／横幅の設定 http://irof.hateblo.jp/entry/20100316/p1](http://irof.hateblo.jp/entry/20100316/p1)に横幅の難しさは説明されていますが、試行錯誤の結果、以下のようにフォントサイズによって、オフセットを不規則に変化させると正方形のセルが手に入るようになりました。

```clj

(def font-offset
  { 8 200,
    9 200,
   10 200,
   11 160,
   12 160,
   13 200,
   14 180,
   15 180,
   16 160,
   17 160,
   18 160,
   19 180,
   20 160,
   22 160,
   24 140,
   26 160,
   28 150,
   36 140})

(defn to-grid [sheet]
  (let [font-size (.. sheet
                      getWorkbook
                      (getFontAt (short 0))
                      getFontHeightInPoints)]
    (doseq [col-index (range 256)]
      (.setColumnWidth sheet col-index (+ (get font-offset font-size 180) (* 256 2)))))
  sheet)
```
## excelebration

excelebrationはaxebomber-cljのコマンドラインラッパーです。

https://github.com/kawasima/excelebration (まだドキュメントがありません :construction_worker: )

納品用の表紙を出力したり、テンプレートをもとに方眼紙を出力したりが簡単にできるようになります。

## MarkdownからExcel方眼紙へ

Markdownで設計書を書くという野望を、システムエンジニアの半数は持っているけれども、Excel方眼紙帝国の力に屈服し、ひらすらマス目を埋める"設計"作業をしている、と聞きます。

そういうときはexcelebrationを使いましょう。

![image](https://qiita-image-store.s3.amazonaws.com/0/8475/fd2edf66-3ec7-7559-8e0d-8698835aacbd.png)

こういうMarkdownが…

```shell-session
lein run -- -i test.md -o test.xlsx
```

コマンド一発で、Excel方眼紙に早変わりです。

![image](https://qiita-image-store.s3.amazonaws.com/0/8475/19b0e559-25b5-d8d2-64c9-2e94e4df589c.png)

## まとめ

まだまだS式からのExcel方眼紙出力はすでに実用化済みですが、MarkdownからのExcel方眼紙は、まだまだこれからの技術です。当然ながら[jagrid](http://qiita.com/kawasima/items/2add7c1a70728a7c1e99)を使ったHTML方眼紙への出力も視野に入れております。
Excel方眼紙を支える技術が、2016年どういう進歩を遂げるのか楽しみですね！
Rで九九を出力するワンライナー

# むしゃくしゃしてやった
```r
> as.data.frame(1:9 %*% t(1:9))
  V1 V2 V3 V4 V5 V6 V7 V8 V9
1  1  2  3  4  5  6  7  8  9
2  2  4  6  8 10 12 14 16 18
3  3  6  9 12 15 18 21 24 27
4  4  8 12 16 20 24 28 32 36
5  5 10 15 20 25 30 35 40 45
6  6 12 18 24 30 36 42 48 54
7  7 14 21 28 35 42 49 56 63
8  8 16 24 32 40 48 56 64 72
9  9 18 27 36 45 54 63 72 81
```
後悔はしていない。

というのは冗談ですが、`data.frame()`で同じことをやると、変数名が`x1,x2,...,x9`になります。
そっちの方が九九の表っぽいですが、おそらくそちらの方が遅いので`as.data.frame()`でやっています。
Rに限らず、もっとイイ感じの書き方があれば、ぜひ教えてください。

# いわゆる100マス計算と、その答え合わせに
```r
> (((d<-as.data.frame(sample(9,9) %*% t(1:9))) %>% `rownames<-`(d[,1]) -> d)[,sample(9,9)] -> d)*0
  V5 V2 V9 V4 V3 V6 V7 V1 V8
5  0  0  0  0  0  0  0  0  0
7  0  0  0  0  0  0  0  0  0
2  0  0  0  0  0  0  0  0  0
4  0  0  0  0  0  0  0  0  0
8  0  0  0  0  0  0  0  0  0
9  0  0  0  0  0  0  0  0  0
1  0  0  0  0  0  0  0  0  0
6  0  0  0  0  0  0  0  0  0
3  0  0  0  0  0  0  0  0  0
> d
  V5 V2 V9 V4 V3 V6 V7 V1 V8
5 25 10 45 20 15 30 35  5 40
7 35 14 63 28 21 42 49  7 56
2 10  4 18  8  6 12 14  2 16
4 20  8 36 16 12 24 28  4 32
8 40 16 72 32 24 48 56  8 64
9 45 18 81 36 27 54 63  9 72
1  5  2  9  4  3  6  7  1  8
6 30 12 54 24 18 36 42  6 48
3 15  6 27 12  9 18 21  3 24
```
ワンライナー的には反則かもしれません。。。
0を空白にしたかったのですが、すぐに思いつかず、*0だけであきらめました。
最後の*0を取れば、dがただちに出ます。
これ、足し算だと逆に出しにくいというのがアレな感じですね。
（要素ごとに演算を適用すればすぐ出る気もしますが）
セキュリティ監査で文句を言われないHTTPステータスコードの使い分け

最近はハンドリングしくてもいいや的な、入力改ざんで発生するバリデーションエラーをそのまま500のHTTPステータスで返すと、攻撃者が「なんか攻撃成功しちゃいそう」って思っちゃうとかなんとかで、監査的なところから「500はやめろ」って言われることがあります。

__一理ある__

ということで、安易に500を返さない方法を考えてみます。

HTTPステータスコードにあまり馴染みのない方は、[こちら](http://anond.hatelabo.jp/20151126202619)…ではなく、[こちら](https://ja.wikipedia.org/wiki/HTTP%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89)をまず読んでください。

## HTTPステータスコードの使い分け基礎

### 400

まず、ユーザの入力値、データの状態によってエラーになるケースは 400 Bad Request とします。エラーメッセージを表示して再入力を促すHTMLページを返す、一般的な入力エラー系の遷移は200 OKを返しても、実用上問題はないかと思います。

ユーザの操作が原因で、サーバ処理がエラーになった場合も400で扱うのはおかしいことではないので、

- トークンチェックエラー 
- 楽観ロックエラー

あたりも、400で返します。もう少しこだわる場合は、適当な4xxのステータスコードにしてもよいかと思います。
HTMLページを返す場合は、512バイト以上にしないと、IEの場合ステキな画面が表示されるので注意して下さい。

また、バリデーションで下手なロジック組むと、型変換でExceptionがあがることがありますが、これら全部catchして500にならないように注意して下さい。

### 503

それから環境や負荷状況によって発生するエラーは「503 Service Temporarily Unavailable」にふります。クローラがサイトの負荷を高めることもあるので、同じところから頻繁にアクセスされる場合は、503を返してクローラに時間をおいてアクセスするように促します(行儀の良いクローラにしか効果はありませんが…)。

### 401 or 403

さらに、認証/認可に関するエラーはそれぞれ、401と403で返します。認証と認可はハッキリと区別し、認証が通ったリクエストのみ、認可チェックを行い、NGの場合403を返すようにして下さい。さもなくば、秘密のURLが存在していることを攻撃者に知らせることになってるぞっ、ということで恰好の指摘を受けるネタになります。

### 404

もう少し細かくするなら、SQLなどであるはず(あったはず)なのにデータが見つからなかったとき、404にします。
「あるはずなのに」が重要です。たとえば、検索導線のドリルダウン中に該当データがない場合…

![image](https://qiita-image-store.s3.amazonaws.com/0/8475/c6a655b5-e1af-604f-320a-fc145913f22f.png)

これをの0件のリンク先に(ちなみに上記はSUUMOの例ですが、0件の場合はこのようにカテゴリの横に(0)と明記して、リンクを落とすのが定石です)、アクセスしたときに404を返すのは、今たまたまデータがないだけなので、好ましくありません。

一方で、詳細ページで物件が削除された場合などは、404を返すようにします。

## 3xx系にもこだわる

以上のことをやっておけば、指摘されることは無くなると思いますが、3xx台も使い分けておくとよいです。

URLを変更した場合に、検索エンジンなど外部サイトからの流入がデッドリンクになっては困るので、Webサーバのリライト機能などを、使って旧URLから新URLにリダイレクトさせることがあります。この用途では「301 Permanent redirect」を使います。

この実装は、WebサーバのURLリライト機能を使うケースが多く、リライトでリダイレクトする設定例に、よく「R=301」が出てくるのはそのためです。

```apache
RewriteRule ^/2015/(.*)$ /2016/$1 [R=301,L]
```

認証のかかっているURLへのリクエストは、未認証の場合ログインページに飛ばし、ログイン成功したら戻ってくるのが、よくあるUIですが、このように前提条件を満たしてないときに、一時的に別のURLで処理をさせるようなケースで「302 Found」を使います。
また、ログイン成功して戻る場合や一連の更新画面遷移の最後で、リロード対策として[PRGパターン](http://teeda.seasar.org/ja/extension/concept/prg.html)を実装する場合には、「303 See other」を使います。

302,303の使い分け、どっちでもいい気がしますが、IE9はPOSTのリクエストに対して302を返すと、リダイレクト先のURLにもPOSTで遷移するRFC strictな実装がされているので、PRGパターンでの期待と違う動きになります。

302/303の使い分けに迷ったら現段階ではざっくり、GETリクエストからのリダイレクトは302、POST/PUT/DELETEのリクエストからのリダイレクトは303としておけばよいと思います。

## HTTPステータスコードへの飽くなきこだわり

REST APIを設計・実装しようとなると、もっとHTTPステータスコードにこだわりたくなります。そんなとき私は、このLiberatorのデシジョングラフを参考にしています。

https://clojure-liberator.github.io/liberator/assets/img/decision-graph.svg

これを辿って行くと、例えばどういうときに409 Conflictで、どういうときに410 Goneを使う感じか指針めいたものが分かってきます。

ちなみに、Liberatorはこのデシジョングラフの全てのノードで、任意の処理をフックでき、それを宣言的に書くことができるライブラリです。開発時には、すべてのリクエストについて、どのデシジョンノードを通ってHTTPステータスコードにたどり着いたかを、↑のデシジョングラフに色付けして表示してくれます。

![image](https://qiita-image-store.s3.amazonaws.com/0/8475/62715327-5ce2-4ae8-4f7b-eaf6c117dccb.png)


HTTPステータスコードマニアは、このためだけにでもClojureを使う価値があるのではないでしょうか。

## まとめ

- Internal Server Errorは、本当のトラブルのときだけ出るようにしよう。
- HTTPステータスコードマニアはLiberator(Clojure)を使おう
メールのトランザクション設計

3日目で息切れしてきたので、今日は軽めな内容です。

## データベース更新とメール送信の一貫性

商品購入の完了ページなど、よくデータベースを更新して、メールを送信してデータベースをコミットするという仕様があります。
データベース登録出来てないのに、完了メールを送るわけにはいかないので、これらを1トランザクションにできなきゃいけません。が、SMTPプロトコルにコミット/ロールバックの概念はありません。

さて、どう設計しましょうか、というお話です。

## 方式

### A.DBトランザクション後にメールを送る

同一トランザクションはあきらめ、データベースを先にコミットし、その後でメールを送る、という設計です。
メール送信でエラーになったら、データベースには書き込めているので、メールだけ再送するように仕組みを作ったりします。

以下のようなイメージです。

```java
public class OrderController {
    @Inject
    private OrderService orderService;

    // Controllerメソッドはトランザクション境界にしない
    public Result complete(Order order) {
        orderService.insertOrder(order);

        // DBトランザクションがうまくいった時だけメールを送る
        Email email = new SimpleEmail();
        email.setHostName("mail.server");
        email.setSmtpPort(465);
        email.setFrom("admin@example.com");
        email.setSubject("TestMail");
        email.setMsg("This is a test mail ... :-)");
        email.addTo("foo@bar.com");

        try {
            email.send();
        } catch(Exception e) {
            RECOVERY_LOG.warn(email);
        }
        return Resutls.redirect("/showOrderComplete");
    }
}

public class OrderService {
    @Inject
    private EntityManagerProvider entityManagerProvider;

    // サービスメソッドをトランザクション境界にする
    @Transaction
    public void insertOrder(Order order) {
        EntityManager em = entityManagerProvider.get();
        em.persist(order);
    }
}


```
### B. 送信リクエストテーブルに書き出し、別プロセスで送る

一度メール送信要求をテーブルに書きだして、そこで同一トランザクションとし、別プロセスがその送信要求を取り出して、実際にメール送信するという設計です。

![image](https://qiita-image-store.s3.amazonaws.com/0/8475/6addb55d-676b-1af7-de6c-86c83d26f654.png)

これもよく使われる方式ですが、前述の方式より複雑で障害ポイントが増えるので、運用面では気をつける点が増えます。

そして、今度はバッチ側でメールは送れたけど、データベースの更新(送信要求の削除)でエラーになった場合、送信ステータスがUNKNOWNになるという問題もあります(可能性としてはだいぶ低いとは思いますが[レアケース厨](http://anond.hatelabo.jp/20141029181254)もいるので、そのときの対応方針は考えとかなきゃいけません)。

### C. [現実解] A + ローカルキューに送る

さてここでSMTPのプロトコルについて考えてみます。もともとサーバをリレーして目的の宛先まで届く仕組みです。直接外部送信用のSMTPサーバに送ろうとするから、失敗の可能性が高まるわけです。ローカルに送ってスプーリングすればエラーの確率は、ほぼ考慮しなくても良くなります(プロセスの起動忘れか、ディスクフルのケースくらい、のレベルの違うトラブルだという点において)。さらに流量制御も比較的容易にできるようになります。

![image](https://qiita-image-store.s3.amazonaws.com/0/8475/ce4d1891-a1e7-07cc-87f8-6b6f7fdd01c0.png)

同じことがやはりキューイングの仕組みをもつアーキテクチャ全般に言えます。MQを使ってデータ送るときも、ローカルキューを作ってそこからリレーさせるのが定石のようです。

## 余談

### メールアドレスのバリデーション

ローカルSMTPでもエラーとなる可能性として、送信先のメールアドレスが不正であるケースがあります。これは送信以前に除外しておくべきです。

というところで、メールアドレスのバリデーションを考えるわけです。

[巷のバリデータ](https://github.com/hibernate/hibernate-validator/blob/master/engine%2Fsrc%2Fmain%2Fjava%2Forg%2Fhibernate%2Fvalidator%2Finternal%2Fconstraintvalidators%2Fhv%2FEmailValidator.java)はRFCに沿ったチェックをするんだというものが多いようですが、この話をするとき、いつも出てくるのはDOCOMOのRFC違反のアドレスの話です。
RFC違反のアドレスが届くかどうかは、相手のMTA依存なので、そのアドレスが正しいかどうかは実際に送ってみないと分からないということになります。ユーザが正しいメールアドレスだと言っているのに、厳しいバリデーション仕様を作りこんでも、運用時の問い合わせ・クレームを増やすだけになるので、戦略としては、とりあえず送ってみて、ダメだったら連続失敗回数をカウントアップし、何回か連続して送信失敗したら、不達アドレスとして以降送信しないようにする対応が現実的かと思います。

したがって、このとりあえず送ってみることのできる範囲を、バリデーションの仕様とした方がよいでしょう。

// TODO 後で書く

## まとめ

メールは直接外部送信用SMTPサーバに送らず、ローカルにスプーリングしよう。メール以外の非同期キューイングアーキテクチャも同じくです。
指定した日時によって自動で表示を切り替えたり変化させるPHPネタ

PHPを使って自動でサイトを更新するためのまとめ。
キャンペーン告知や応募受付に。

※さらにスマートな書き方をコメント欄にていただいたので追記しました。

# 指定日時まで表示し、過ぎたら非表示にする

```php
<?php
if (strtotime(date('Y-m-d H:i')) < strtotime('2015-10-10 8:00'))
{
echo '2015-10-10 7:59まで表示する内容';
}
?>
```
##追記
```php
<?php
if (date('Y-m-d H:i') < '2015-10-10 08:00'): ?>
　2015-10-10 7:59まで表示する内容
　(複数行可)
<?php endif; ?>
```
```php
<?php
$closeTime = new DateTime('2015-10-10 8:00');
if (new DateTime < $closeTime): ?>
　2015-10-10 7:59まで表示する内容
　(複数行可)
<?php endif; ?>
```

# 指定日時を過ぎたら表示する

```php
<?php
if (strtotime(date('Y-m-d H:i')) >= strtotime('2015-10-10 8:00'))
{
echo '2015-10-10 8:00～表示する内容';
}
?>
```
##追記
```php
<?php
if (date('Y-m-d H:i') >= '2015-10-10 08:00'): ?>
　2015-10-10 8:00～表示する内容
　(複数行可)
<?php endif; ?>
```
```php
<?php
$startTime = new DateTime('2015-10-10 8:00');
if (new DateTime >= $startTime): ?>
　2015-10-10 8:00～表示する内容
　(複数行可)
<?php endif; ?>
```
# 表示される期間を指定する
```php
<?php
$foo = strtotime(date('Y-m-d H:i'));
if ($foo >= strtotime('2015-10-10 8:00') && $foo < strtotime('2015-10-10 20:00'))
{
echo '2015-10-10 8:00～19:59まで表示する内容';
}
?>
```
##追記
```php
<?php
$now = date('Y-m-d H:i');
if ($now >= '2015-10-10 08:00' && $now < '2015-10-10 08:00'): ?>
　2015-10-10 8:00～19:59まで表示する内容
　(複数行可)
<?php endif; ?>
```
```php
<?php
$now = new DateTime();
$startTime = new DateTime('2015-10-10 8:00');
$closeTime = new DateTime('2015-10-10 20:00');
if ($now >= $startTime && $now < $closeTime): ?>
　2015-10-10 8:00～19:59まで表示する内容
　(複数行可)
<?php endif; ?>
```
# 表示/非表示ではなく、内容を変化させたい場合

```php
<?php
date_default_timezone_set('Asia/Tokyo');
if (strtotime(date('Y-m-d H:i')) < strtotime('2015-10-10 8:00'))
{
echo '受付中';
} else {
echo '締め切り';
}
?>
```
##追記
```php
<?php
if (date('Y-m-d H:i') < '2015-10-10 08:00'): ?>
　受付中
<?php else: ?>
　締め切り
<?php endif; ?>
```
# 内容が複数行の場合
echoの部分を書き換える

```php
{
echo <<< EOF
2015-10-10
7:59まで
表示する内容
EOF;
}
```
参考
http://liapoc.com/strtotime.html
http://sole-color-blog.com/blog/php/36/
Djangoが出力する生のSQL文が見たい

Django 1.8.4

```
./manage.py sqlmigrate [app_label] [migration_name]
```

migration_nameはアプリ名のmigrationsフォルダの中にあるファイルの番号
0001_initial.py なら 0001

```
./manage.py sqlmigrate [app_label] 0001
webpackのentryにワイルドカードを使うには

# はじめに
webpackのentryでワイルドカードを使いたいけど、標準機能でワイルドカードは使えません。こういう場合、どうすればいいのでしょうか。

# globを使いましょう
公式サイトでも言われているように、globを使いましょう。コードのイメージはこんな感じです。

```
var glob = require("glob");
// ...
entry: glob.sync("./test/**/*Spec.js")
```

公式サイト
https://github.com/webpack/webpack/issues/370#issuecomment-49835937

# 少しだけ応用的な話
勘のいい人は気付いたかもしれませんが、実はwebpack.config.jsではnpmモジュールを読み込むことができます。もちろん自作のjavascriptを読み込むこともできます。これがさりげに便利なところでサーバサイドがnode.jsの場合に、サーバ側で使っているファイル抽出ロジックをwebpackでそのまま使うことができます。

手前味噌で申し訳ありませんが、自作ゲームのGブレイバーではテストコード抽出ロジックをサーバサイドとテストコードで同じモジュールを参照するようにしています。

テストコード抽出ロジック
https://github.com/kaidouji85/gbraver/blob/f3fae41f6c8a5530325f598e9aaf5d68f75f11da/testGlob/index.js

サーバサイドの参照
https://github.com/kaidouji85/gbraver/blob/f3fae41f6c8a5530325f598e9aaf5d68f75f11da/app.js#L23

webpack.configでの参照
https://github.com/kaidouji85/gbraver/blob/f3fae41f6c8a5530325f598e9aaf5d68f75f11da/grunt/webpack/webpack.test.config.js#L1

大元のgithubはこちら
https://github.com/kaidouji85/gbraver
cordovaでアンドロイド開発環境を用意するまで

# はじめに
今更ですがcordovaを触ってみようと思い、開発環境を作ってみました。cordova自体の導入はすごく楽だったのですが、android周りが結構大変だったので、そのメモを残します。

# 公式サイトなど
ぶっちゃけ、公式サイトを見ながらやれば大体はできます。こういうのは情報がすぐに古くなるので、下手に日本語の解説サイトを見るよりも英語の原文を見た方がいいと思います。

cordovaのインストール
https://cordova.apache.org/docs/en/latest/guide/cli/index.html

android関係のインストール
https://cordova.apache.org/docs/en/latest/guide/platforms/android/index.html

# android関係で詰まったところ
java、Android Studioはそこまで苦労しませんでしたが、androidのシュミレータを動かすのに滅茶苦茶苦労しました。私の開発環境は2年前のmac book airですが、こいつのパワーだとandroidシュニレータがまともに動きません。これを回避するためには、intelアーキテクチャ専用のVMイメージを導入します。詳細はこの記事を見るといいと思います。

http://qiita.com/gabu/items/8bc1a11f1382409f1d2a

これで大丈夫かと思いきや、そうは問屋が卸しません。androidシュミレータを使うためには、ANDROID_AVD_HOMEという環境変数を設定する必要があります。これを設定しないと、androidエミュレータを立ち上げた瞬間に、以下のエラーが出ます。

```
PANIC: HOME is defined but could not find cordova.ini file in
```

ここの詳細はこのStack Overflowに載っています。ちなみにOSXの場合はANDROID_AVD_HOMEに${HOME}/.android/avdを設定すれば大丈夫だと思います。

http://stackoverflow.com/questions/27537578/could-not-find-ini-file-in-android-avd-home-nor-in-home-android-avd

# 最後に
cordovaはnpmで簡単に入れられますが、android関係は本当に苦労しました。android sdkのインストールも結構時間がかかったし。
GitHub の issue の中で指定したラベルが付いているものをリストアップして Markdown に整形するアプリ

自作ツールの紹介です。

## 作ったもの

GitHub で管理している任意のリポジトリにある issue の中で指定したラベルが付いているものだけをリストアップして Markdown に整形するデスクトップアプリを作りました。

[Raccoon といいます。](https://github.com/mironal/raccoon)

<img width="912" alt="raccoon.png" src="https://qiita-image-store.s3.amazonaws.com/0/17704/e7920993-eaa0-1d5a-de20-6005e6646f68.png">

フォームに入力した内容は次回起動時に復元されるので微妙に便利です。

## モチベーション

[弊社](http://covelline.com/)は GitHub の issue で課題管理をしているのですが、時々特定のラベルがついた issue だけをリストアップしたくなります。

例えば "バグ" というラベルがついたものだけをリストアップしてユーザーに公開したい場合とかです。 ウェブに公開するので Markdown とかで生成されるとなお良しです。

こういったことをするために簡単に GitHub の issue で特定のラベルがついたものをリストアップしてウェブに公開できるツールが欲しくなったので作ったというわけです。

## 設計思想

- コマンドラインツールに慣れてない人でも使えるようにデスクトップアプリを作る
- 自動化にも使えたら便利だからコマンドラインツールも作る
- デスクトップアプリを簡単に作りたかったので Electron を使う
- HTML を生成するのはめんどいから Markdown を生成

大事にしたいのは誰でも使えるように作ることです。

既知の不具合ページなどはユーザーサポート部門の人が更新作業を行ったりしますが、多くの場合そういった部門の人はプログラマの様にコマンドラインツールに慣れていません。

しかしデスクトップアプリだけだと自動化に向きません。

なのでコマンドラインツール + デスクトップアプリという構成で作りたいと思います。 

ただし、同じ機能を持ったものを2つ作るのは面倒なので、単純な機能を持ったコマンドラインツールを作って、そのフロントエンドとしてデスクトップアプリがいるという構成にします。

デスクトップアプリがコマンドラインツールを実行して結果を表示するみたいな考え方です。

## 使った技術

### Electron

最近話題のやつ。 マジ便利。

http://electron.atom.io/

package.json に以下のように書くと electron がインストールされてない環境でも `npm start` するだけで起動できて便利です。

```json:package.json
{
  "scripts": {
    "start": "electron main.js"
  },
  "devDependencies": {
    "electron-prebuilt": "^0.35.0"
  }
}
```

全体像はソースコード見てください。

### highlight.js

https://highlightjs.org/

シンタックスハイライトする奴。 markdown のシンタックスハイライトに使っています。

npm で入れて electron の環境で使う場合は レンダラープロセスの方で `const hljs = require("highlight.js");` ってやらないとうまく動作しません。

npm で入れた場合に `<script src="note_modules/path/to/highlight.js"></script>` 的なことを html の方に書いても色々ロードする処理が index.js の方に書いてあるのでうまく動作しません。

ｱﾎなので3時間ぐらい悩みました。

全体像はソースコード見てください。

## やりたいこと

より簡単に使用するために GitHub の API Token を GitHub の設定画面に行かなくても作れるようにするための便利ツールを作ればこのツール群は完成です。

作ったら更新します。
Math.floorを使わないで小数点以下を切り捨てる

## 0〜9のランダムな整数を出力

（１）Math.floorを使う方法

```js

var res = Math.floor(Math.random() * 10 ); //0〜9

```

（２）ビット演算子を２つ書く方法

```js

var res = ~~(Math.random() * 10 ); //0〜9

```

●ソースコードみててチルダ２つあるのなんぞ？と調べて「なるほど」と思いメモ。

//----＜追記＞-----//

（３）コメントにて教えていただいた方法（hikaru_oao様ありがとうございました！）

```js

var res = (Math.random() * 10 )|0; //0〜9

```

※注意点：
（２）の~~を使う方法は条件によってはMath.floorと結果の値が変わるとの情報をいただきました（jkr_2255様ありがとうございました！）
Apacheアクセスログの解析ツール（AWStats）を使用する

WEBページの閲覧状況確認のため、Apacheアクセスログ解析ツール（AWStats）を使用してみた。

Ubuntu 14.04
------------

パッケージをインストールする。

```sh
$ sudo aptitude install awstats
```

awstats設定を変更する。
※仮想ホスト設定を使用しているため、解析対象のログファイル指定を変える必要があった。

```sh
$ sudo vi /etc/awstats/awstats.conf
```
```diff
--- a/awstats/awstats.conf
+++ b/awstats/awstats.conf
@@ -48,7 +48,7 @@
 # If there are several log files from load balancing servers :
 # Example: "/pathtotools/logresolvemerge.pl *.log |"
 #
-LogFile="/var/log/apache2/access.log"
+LogFile="/var/log/apache2/other_vhosts_access.log"


 # Enter the log file type you want to analyze.
@@ -120,7 +120,7 @@ LogType=W
 # Example for IIS:
 # LogFormat = 2
 #
-LogFormat=4
+LogFormat = "%virtualname:%other %host %other %logname %time1 %methodurl %code %bytesd %refererquot %uaquot"


 # If your log field's separator is not a space, you can change this parameter.
@@ -151,7 +151,7 @@ LogSeparator=" "
 # Example: "ftp.domain.com"
 # Example: "domain.com"
 #
-SiteDomain=""
+SiteDomain="home.local"


 # Enter here all other possible domain names, addresses or virtual host
@@ -210,7 +210,7 @@ DirData="/var/lib/awstats"
 # Example: "/awstats"
 # Default: "/cgi-bin"   (means awstats.pl is in "/yourwwwroot/cgi-bin")
 #
-DirCgi="/cgi-bin"
+DirCgi="/awstats"


 # Relative or absolute web URL of your awstats icon directory.
```

ログ解析実行スケジュールの設定ファイルを修正する。
※デフォルトのままではスクリプトがログファイルにアクセスできないため、ログファイルのパーミッションかcron実行アカウントのどちらかを修正する必要あり。

```sh
$ sudo vi /etc/cron.d/awstats
```
```diff
--- a/cron.d/awstats
+++ b/cron.d/awstats
@@ -1,6 +1,6 @@
 MAILTO=root

-*/10 * * * * www-data [ -x /usr/share/awstats/tools/update.sh ] && /usr/share/awstats/tools/update.sh
+*/10 * * * * root [ -x /usr/share/awstats/tools/update.sh ] && /usr/share/awstats/tools/update.sh

 # Generate static reports:
-10 03 * * * www-data [ -x /usr/share/awstats/tools/buildstatic.sh ] && /usr/share/awstats/tools/buildstatic.sh
+10 03 * * * root [ -x /usr/share/awstats/tools/buildstatic.sh ] && /usr/share/awstats/tools/buildstatic.sh
```

apache設定フィアルを作成する。
※デフォルトでは存在しないので作成する必要あり。

```sh
$ cat <<EOS | sudo tee /etc/apache2/sites-available/awstats.conf
Alias /awstats-icon/ /usr/share/awstats/icon/
Alias /awstats/ /usr/lib/cgi-bin/
<Location /awstats>
    Options FollowSymLinks MultiViews ExecCGI
    Require ip 192.168.0
</Location>
<FilesMatch "\.pl$">
    AddHandler cgi-script .pl
</FilesMatch>
EOS
```
```sh
$ sudo a2enmod cgi
$ sudo a2ensite awstats
$ sudo service apache2 restart
```

アクセス確認

http://192.168.0.200/awstats/awstats.pl


CentOS 7
--------

パッケージをインストールする。

```sh
$ sudo yum install awstats
```

apache設定フィアルを変更する。
※アクセス許可変更

```sh
$ sudo vi /etc/httpd/conf.d/awstats.conf
```
```diff
--- awstats.conf.org    2015-11-23 17:33:57.513830080 +0900
+++ awstats.conf        2015-11-23 17:34:07.343830053 +0900
@@ -26,7 +26,7 @@
     AllowOverride None
     <IfModule mod_authz_core.c>
         # Apache 2.4
-        Require local
+        Require ip 192.168.0
     </IfModule>
     <IfModule !mod_authz_core.c>
         # Apache 2.2
```

httpdサービスを再起動する。

```sh
$ sudo systemctl restart httpd.service
```
launchdのWatchPathsによるファイル監視

WatchPathsまとめ

ぐぐっても古かったり不正確だったりするので．

WatchPathsは，launchdで使えるパラメータの一つです．
公式のリファレンスはこちらですが，見ても以下のような素気ない一文があるだけでよくわからないのが正直なところ．
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man5/launchd.plist.5.html

>  WatchPaths <array of strings>
     This optional key causes the job to be started if any one of the listed paths are modified.

というわけで，どれぐらい使えるのか確認します．

# 前提
```shell-session
uraura@rosemary$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.11.1
BuildVersion:   15B42
```
El Capitanです．

# 準備
```xml:local.watchpaths-test.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
	<dict>
		<key>Label</key>
		<string>local.watchpaths-test</string>
		<key>Program</key>
		<string>/Users/uraura/work/ld/fired.sh</string>
		<key>WatchPaths</key>
		<array>
			<string>~/work/ld/watching</string>
		</array>
	</dict>
</plist>
```

```bash:fired.sh
#!/bin/sh

LOGFILE=/tmp/fired.log

{
	echo "$(date) fired!"
} >> "$LOGFILE" 2>&1
```

# 結果

やること|コマンド|結果
---|---|---|---
ディレクトリ生成|`mkdir watching`|**fired**[^1]
パーミッション変更|`chmod 777 watching`|**fired**|
所有者変更|`sudo chown nobody:nobody watching`|**fired**|
ディレクトリの内容表示|`ls watching`|**-**|
ファイル作成|`touch watching/foo`|**fired**
ファイルのパーミッション変更|`chmod 777 watching/foo`|**fired**
ファイルの所有者変更|`sudo chown nobody:nobody watching/foo`|**fired**
ファイルに書き込み|`date > watching/foo`|**fired**
ファイルの内容表示|`cat watching/foo`|**-**
ファイルの削除|`rm watching/foo`|**fired**
サブディレクトリ作成|`mkdir -p watching/sub1/sub2/sub3/sub4`|**fired**
サブディレクトリ内にファイル生成|`date > watching/sub1/sub2/sub3/sub4/bar`|**fired**
サブディレクトリ内でパーミッション変更|`chmod 777 watching/sub1/sub2/sub3/sub4/bar`|**fired**
サブディレクトリ内のファイル削除|`rm watching/sub1/sub2/sub3/sub4/bar`|**fired**
サブディレクトリを一気に削除|`rm -rf watching/sub1/sub2`|**fired**
対象ディレクトリを削除|`rm -rf watching`|**fired**

以上より，`WatchPaths`に指定したディレクトリ以下はサブディレクトリを含め変更はすべて監視対象になるようです．
`ls`や`cat`で読みとるだけの操作では何も起こりませんでした．

サブディレクトリは監視対象にならない，というのをそこここで目にするのですが，昔の話?? :sake: 

---

[^1]: `/var/log/system.log`にこんなログが出て，だいたい10秒後に2回目が発火しました．
 > Nov 23 17:28:30 rosemary com.apple.xpc.launchd[1] (local.watchpaths-test): Service only ran for 0 seconds. Pushing respawn out by 10 seconds.