OmniAICreator/Qiita-1.07M huggingface dataset:
UglifyJS で ES2015 を minify する

UglifyJS は JavaScript のコードを minify したり難読化するためのツールです。
その UglifyJS を使って ES2015 のコードを minify する方法を書き留めます。

## 2017年10月 追記

月日は流れ、現在 ES2015+ 対応のブランチは別ライブラリとして npm に登録されているようです。その名も [uglify-es](https://github.com/mishoo/UglifyJS2/tree/harmony) !!

npm コマンドでインストール出来ます。

```console
$ npm install uglify-es -g
```

インストールされるコマンド名は相変わらず `uglifyjs` のようですね。

```console
$ uglifyjs [input files] [options]
```

<br>

以下、今となっては古い内容ですが↓↓

## サンプルコード

適当に Hello,world するコードを、

```js:input.js
'use strict';

document.addEventListener('DOMContentLoaded', (e) => {
  let name = 'world';

  document.querySelector('.foobar').textContent = `Hello,${name}!`;
}, false);
```

letキーワード・アロー関数・テンプレート文字列を使ってみています。
これを minify しましょう。

## 普通にやるとエラーを吐いてコケる

まずは [公式リポジトリ](https://github.com/mishoo/UglifyJS2#readme) に書かれているとおり普通にインストールして普通に実行してみます。

```bash
$ npm install uglify-js -g
$ uglifyjs --compress --mangle -- input.js
```

すると、

![20160907_10.png](https://qiita-image-store.s3.amazonaws.com/0/84816/5b65d055-91a2-4386-9494-49e5f16b17a0.png)

![20160907_03.png](https://qiita-image-store.s3.amazonaws.com/0/84816/61e393e1-8a60-5669-5cf6-74dd2e603fad.png)

アロー関数のところで Parse Error を吐いて止まります。
その他、letキーワード・テンプレート文字列・ジェネレーター関数なども許してくれないようです。ツラいですね。

## Issue が上がっていた

まぁ当然要望が上がりますよね。Issue がありました。

[Harmony support · Issue #448 · mishoo/UglifyJS2](https://github.com/mishoo/UglifyJS2/issues/448)

流れをザッと追っていくと、

- ES2015 対応は harmony ブランチで進めている
- そのうち master にマージされる予定

とのこと。

## harmony ブランチを試す

まず、さっきインストールしてしまったものをアンインストールします。

```bash
$ npm remove uglify-js -g
```

![20160907_09.png](https://qiita-image-store.s3.amazonaws.com/0/84816/8a3a75cf-cc08-4a59-81e7-3fb6ce33821f.png)

はい、

<br>

あらためて GitHub からインストールして。試してみましょう。
npm は Git リポジトリの URL を直接指定することでリポジトリからもインストール出来ます。
`#` の後に続けてブランチを指定すれば master 以外のブランチからもインストール可能です。

```bash
$ npm install -g https://github.com/mishoo/UglifyJS2.git#harmony
$ uglifyjs --compress --mangle -- input.js
```

![20160907_06.png](https://qiita-image-store.s3.amazonaws.com/0/84816/3ad3f88a-e145-bfd8-a5cf-0730ea4066bb.png)

![20160907_08.png](https://qiita-image-store.s3.amazonaws.com/0/84816/2ce9dc98-8399-8884-aef8-587a517c6046.png)

出来ました :v: :wink: 

## 注意点

npm のバージョンが古いと https 経由でのインストールに失敗することがあります。
インストール中に失敗する場合は `npm update -g npm` で npm を最新にしてみてください。
ApacheもしくはTomcatでBodyのサイズ制限

Bodyのサイズ制限をしようとして、
ApacheのLimitRequestBody、TomcatのmaxPostSizeでハマったのでメモしておく。
結局アプリ内で処理することにした。

日本語のマニュアル　https://httpd.apache.org/docs/2.2/ja/mod/core.html#limitrequestbody
の日本語版に特に記述がないので、そのまま使ってみたら、うまく動作しない

```
ある場所へのファイルアップロードを許可する場合に、 アップロードできるファイルのサイズを 100K に制限したければ、 以下のように指定します:

LimitRequestBody 102400
```

と思ったら
英語版のマニュアル　https://httpd.apache.org/docs/2.2/en/mod/core.html#limitrequestbody
にはPROXYしている場合は、使えない旨が書いてある。。。

**Note: not applicable to proxy requests.**

```
If, for example, you are permitting file upload to a particular location and wish to limit the size of the uploaded file to 100K, you might use the following directive:

LimitRequestBody 102400
Note: not applicable to proxy requests.
```

だからTomcatでmaxPostSizeを使おうと思ったけど
こっちはマルチパート以外は引っかからないらしい。
【自分用】ChefDKで環境(workstation+node)構築時に利用するコマンド備忘録

ChefDKを利用して開発環境構築(Workstation+単一Node)の勉強をしている。
構築時の流れについて、忘れないうちにメモしておく。

# 仮想マシン作成〜Chefリポジトリ作成＆準備
```sh
# 初期の場合
# chef gem install knife-solo
# chef gem install berkshelf
# knife configure
# CentOS6.7のboxファイルを取得
$ vagrant box add centos64 vagrant box add centos64 http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.4-x86_64-v20131103.box

# centos67で仮想マシンを作成、起動確認
$ vagrant init centos64
$ vagrant up

# ssh設定を追加。ホスト名はmylinuxとする
$ vagrant ssh-config --host mylinux >> ~/.ssh/config  

# mylinuxで、SSH接続ができることを確認
$ ssh mylinux

# 上位ディレクトリに移動し、chefリポジトリを作成
$ cd ../
$ knife solo init chef-repo

# chefリポジトリに移動し、仮想マシンでchefが利用できるようにする
$ cd chef-repo
$ knife solo prepare mylinux

```

# Berksfileへの追記

```sh:chef-repo/Berksfile
source "https://api.berkshelf.com"

cookbook "yum"
cookbook "yum-epel"
```

# berksコマンドの実行

```sh
$ cd chef-repo
$ berks vendor ./cookbooks
```


# Cookbook作成

```sh
# mybookというCookbookを、site-cookbooks配下に作成
$ knife cookbook create mybook -o site-cookbooks/ 
```

## recipeの追記
```ruby:chef-repo/site-cookbooks/mybook/recipes/default.rb
%w{
mysql-server
httpd
python-devel
git
}.each do |p|
    package p do 
        action :install
    end
end

service "httpd" do 
    action [:start, :enable]
end
```

## nodeへのレシピ情報の追記

```json:chef-repo/nodes/mylinux.json
{
  "run_list": [
    "recipe[yum]",
    "recipe[yum-epel]",
    "recipe[mybook]"
  ]
}
```

```sh
# node(mylinux)への反映
$ knife solo cook mylinux

# 仮想マシンに反映されていることを確認
$ ssh mylinux2

# 仮想マシン上でgitを実行してみる
$ git
```
El Capitanでrbenvでruby-1.8.7-p375をインストールする

```
brew install apple-gcc42 openssl libyaml libffi
xcode-select --install
export CC=/usr/local/bin/gcc-4.2
export CFLAGS='-g -O2'
export RUBY_CONFIGURE_OPTS=--with-openssl-dir=`brew --prefix openssl`
export CONFIGURE_OPTS=--with-openssl-dir=`brew --prefix openssl`
rbenv install 1.8.7-p375
```

とりあえず、現状ではopensslはこれでなんとかなった。
certbotの実行後にApacheが起動できなくなった件

Apache on CentOS/RHEL 6

```
[root@XXX ~]# uname -a
Linux XXX 2.6.32-573.12.1.el6.x86_64 #1 SMP Tue Dec 15 21:19:08 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

[root@XXX ~]# cat /etc/redhat-release
CentOS release 6.8 (Final)

[root@XXX ~]# httpd -v
Server version: Apache/2.2.15 (Unix)
Server built:   Jul 18 2016 15:24:00

[root@XXX ~]# ./certbot-auto --version
letsencrypt 0.8.1
```
```:/var/log/httpd/error_log
(2)No such file or directory: httpd: could not open error log file /var/log/apache2/redirect.error.log.
Unable to open logs
```

```
[root@XXX httpd]# ag apache2
conf.d/le-redirect-mydomain.com.conf
9:ErrorLog /var/log/apache2/redirect.error.log
```

```:/etc/httpd/conf.d/le-redirect-mydomain.com.conf
- ErrorLog /var/log/apache2/redirect.error.log
+ ErrorLog /var/log/httpd/redirect.error.log
```

なんとなくソース読んでみたけどCentOS判定されたら`/var/log/httpd`がログディレクトリに設定されるようになっていたので、OS判定がミスってるのかなとか。
そもそも CentOS 6.8 (Final) だと python 2.7 が標準対応してないのでIssue投げる案件ではないと思いこっちに書いた。
scala.util.Tryをパターンにわけてうまく実装するぞ

主にWebアプリケーションを書くときに、エラーやValidation結果を返すのに、いろいろと悩むことがありますよね。

Option?
Either?
Try?
\/?

で最近は、けっこーTry一択で実装してて、なんとなしにパターン的なものが掴めてきた気がするので、自分用も兼ねてまとめてみた。

# Try型は低レイヤーのメソッドで生成しよう

最も小さいメソッドでTryを生成し、そのメソッドを呼び出すメソッド内では、for式を使うと良い。

```scala
lazy val assertNotEmpty: String => Try[Unit] = (value: String) => Try {
  assert(value.nonEmpty, "value is empty")
}

lazy val findBy: String => Try[String] = (id: String) => Try {
  someTable.findBy(id)
}

def printSomething(id: String): Try[Unit] =
  for {
    u <- assertNotEmpty(id)
    some <- findBy(id)
  } yield
    println(some)
```

みたいな。

`Try.apply` で処理を受けてやるのは、小さい粒度?のメソッドでやってやって、そいつを呼ぶメソッドでは、for式で。

こうすると、スッキリとしたコードが書けて良いなって思ってる。

これを守らなかったら、

```scala
lazy val assertNotEmpty: String => Unit = (value: String) =>
  assert(value.nonEmpty, "value is empty")

lazy val findBy: String => String = (id: String) =>
  someTable.findBy(id)

def printSomething(id: String): Try[Unit] = Try {
  assertNotEmpty(id)
  val result = findBy(id)
  println(result)
}
```

こんな感じになって、なんか、valとか入るし、printSomethingの実装のしかたがあんまり決まってこないし、なんかビミョー。

って気がする。

小さい単位でTry型を返すようにしてやると、そいつを呼び出すところの処理がある程度、決まってくるから、なんか書いてて気持ちいい。

仕様が変わったり、処理を追加したりにも柔軟に対応できる。

たとえば、updateしてから、printしてって仕様に変わったとしても、 

```scala
lazy val update = (id: String) =>  (something: String) => Try {
  someTable.update(id)(something)
}
```

って関数を追加してやって、for式に一行呼び出しを書くんだろうなってすぐに分かる。

```scala
def printSomething(id: String): Try[Unit] =
  for {
    u <- assertNotEmpty(id)
    some <- findBy(id)
    updatedSome <- update(id)(some + "thing") // <= ココに追加したった。
  } yield
    println(updatedSome)
```

処理の流れも見易くて、Gitとかで差分見ても、一目瞭然。

やっぱこの単位でTryにしていくのがベストな気がします。

# Try[Seq[Try[String]]]をほぐす

低レイヤーのメソッドでTryにしていくと、 `Try[Seq[Try[String]]]` みたいなことになりがち。

```scala
lazy val assertNotEmpty: String => Try[Unit] = (value: String) => Try {
  assert(value.nonEmpty, "value is empty")
}

lazy val findAll: () => Try[Seq[String]] = () => Try {
  someTable.findAll
}

lazy val findBy: String => Try[String] = (id: String) => Try {
  someTable.findBy(id)
}

def printSomething(): Try[Seq[Try[String]]] =
  for {
    ids <- findAll()
  } yield for {
    id <- ids
  } yield for {
    u <- assertNotEmpty(id)
    some <- findBy(id)
  } yield
    some
```

上記のよーな感じ。これをほぐす。

```scala
def printSomething(): Try[Seq[String]] =
  for {
    ids <- findAll()
    somes <- Try {
      for {
        id <- ids
      } yield (for {
        u <- assertNotEmpty(id)
        some <- findBy(id)
      } yield some).get
    }
  } yield somes
```

みたいな。

これで良い感じ。

# Option.getは悪だけどTry.getは良い

Option.getをすると、NullPointerになるから、getとか絶対使うなよ!!って言うけど、だからって、Try.getもだぞ!!ってことにならないと考えてます。

```scala
Try {
  // something
} match {
  case Success(s) => s
  case Failure(e) => throw e
}
```

って、

```scala
Try {
  // something
}.get
```

と同じなんだよね。

結構、前者のコードを見る。(まあ、Scala初級者なだけですが…)

けど、そんなん冗長なことせんと、そこは素直にgetでいこーぜって思う。

# まとめ

ざっと、眠たい目をこすりながら、思い出したのは、以上。

他に思い出したら追記かなんかします。

以上です。
9/6　今日の学習内容～アクションで使える機能～

###今日の学習内容
***
今日は昨日学習したアクションの命名規約に引き続き、アクションについて学習を進めていきました。

アクションで使える機能を、[cloud9](https://c9.io/)で実際に使いながら練習していきたいと思います(-ω-)/

####練習の下準備
***
練習用のコントローラを復習を兼ねて作っていきましょう(*‘∀‘)


ターミナルに``rails g controller lesson``と打ち込んでください。

![cloud9_22.png](https://qiita-image-store.s3.amazonaws.com/0/137880/c03196df-5238-e685-e843-179f4f1e5800.png)

``lesson_controller``が``controllerｓ``ファイルの中にできました。

つぎに、ルーティングをしておきましょう。

``config``フォルダ下の``routes.rb``ファイルを開いて、ルーティングの設定を書いていきます。

![cloud9_23.png](https://qiita-image-store.s3.amazonaws.com/0/137880/8e217490-33dc-80cb-3869-06a4a6df1656.png)

####練習①　パラメーターの取得
***
まず、パラメータのって何？というところからですね。
私にはさっぱりですので、先人の知識を借りてきました(笑)

>通常アプリケーションを利用する場合、単にリクエストだけを送信することは少なく、例えば新しいデータを登録する場合には登録する情報をブラウザ上で入力し、パラメータとしてリクエストと一緒に送信されてきます。

>[RubyLife パラメータの取得](http://www.rubylife.jp/rails/controller/index6.html)より引用

つまり、パラメータというのは**URLから送られてきた値やフォームで入力した値**ということですかね？(。´･ω･)

インターネットショッピングなどで登録する、名前や住所などの情報などもパラメータにあたるのでしょうか(-ω-)/

アクションに渡されるパラメータは２種類あるようですね。
１つは``https://localhost:3000/lesson/step1/yamada``の``yamada``部分のように、パスに埋め込まれたパラメータで、もう１つはURLのクエリー（クエリ）部分に、``?名前=値``のような形を使って渡されるパラメータだそうです。

どちらの方法でも、``params[:パラメータ名]``で取り出すことが可能です。

さっそく実際に使ってみたいと思います(-ω-)/

下の画像を参考に、コードを``controllers``フォルダ下の``lesson_controller.rb``に書き加えてみてください。

![cloud9_24.png](https://qiita-image-store.s3.amazonaws.com/0/137880/247d46a4-5fee-0c4f-2efc-77ecac1ae720.png)

つぎに、``rails s -b $IP -p $PORT``をターミナルで実行しサーバを起動後、出てきたURLを開いてください(-ω-)/

その際、さきに``cd``コマンドをターミナルで実行して、アプリケーションのディレクトリ（私の場合は``asagao``）に移動しておいてください。

``lesson``コントローラの``practice１``アクションに``yamamoto``というパラメータがリクエストと一緒に送られるようにパスをURL欄に書き込んでください。

![cloud9_25.png](https://qiita-image-store.s3.amazonaws.com/0/137880/4700ca41-56b9-3879-1784-6d627994507c.png)


↑そうすると、こんにちは、yamamotoさんと表示されます(*‘∀‘)


``/practice1?name=yamamoto``と書いても同じですね。↓

![cloud9_26.png](https://qiita-image-store.s3.amazonaws.com/0/137880/d29853a3-8996-0ca0-8fd3-3533cbb6179b.png)


今日は時間があまりとれなかったので、ここまでしか進めませんでした(;´д｀)
次回から、この続きを学習していきたいと思います。

もし、この記事を読んで一緒に学習して下さっている方がいらっしゃるのでしたら、今日作ったファイルは、まだ消されないよう、お願い申し上げますm(__)m

###あとがき
***
今日はコントローラのパラメータ取得について学習を進められました。
これまで使っていた名前や住所を書き込むフォームも、こんな形で送っていたものがあったのかもしれないと思うと、少しウキウキしてくるものですね(笑)
私だけかもしれないですけど(´-ω-`)

ここまで読んでいただきありがとうございましたm(__)m

###参考にさせていただいたサイトなど
***
- [改訂３版基礎Ruby on Rails](https://www.amazon.co.jp/dp/4844338153)
- [cloud9](https://c9.io/)
- [RubyLife パラメータの取得](http://www.rubylife.jp/rails/controller/index6.html)
サバティカらないゲーム開発ブログ 1日目

ちょっとアプローチを変えて、今まで面白いと思ったゲームをリストアップしてみる。
自分が面白いと思うゲームを作る方が間違いなくモチベは上がる、はず、なのだ。

* バベルの塔…ファミコンですげーやった。L字ブロックを積んでいく独特のアクションパズルのゲーム性は今でも色褪せていない。音楽も良かった。
* エッガーランド…ディスクシステムで全シリーズやりこんだ。練りこまれたギミックで作り込まれた大量のステージがぼくのプログラマーとしての論理的思考能力を培ってくれたと言っても過言ではない。メデューサに刺された時の効果音はマジで心臓に悪かった。

もちろん世に言う名作というものも一通りプレイして、面白かったけど、印象に残ってるのはこの2本だなー。つまりあれですよ、パズルゲームが好きなんですよ。

最近骨太なパズルゲームってあまりないし、パズルゲームにしようかな。

ただAdsの導入を考えるとある程度のアクション性、ランダム性があったほうがよさそう。
↓のスライドでいうところのコンティニュー型、もしくはアイテムプレゼント型にしたいのだ。

日本・海外の事例からみる動画広告を使ったゲームアプリのマネタイズ超入門 http://www.slideshare.net/yasuyukikamata/ss-48827754

もう少し考える。
/.snapshotsディレクトリのpermission

openSUSEだと750、Debianだと755なので、一般ユーザーが.snapshotsディレクトリの内容を見れちゃう。
同じパーミッションだし害はないかなーと思ったが、例えば間違えて権限を付けたファイルがあったとして、過去のsnapshotから参照しちゃえるよな、それはまずいかも。


追記：新規にインストールしてみたら、通常のパーミッションになってた。あれれ？
プログラムとLive2Dモーションのお話

８月末にLive2Dのモデル・モーション制作に参加
プログラムの方にタッチできない状態での制作
***
#モーション部分の切り替え仕様が　わかりづらい
***
今回は指示を受ける側でしたが
指示を出す側に回った時や次の時に
**どのように仕様を伝えるとよいのか？**
**どのような情報を要求すればよいのか？**
考えてみました
***
#Unity+Live2Dにある機能
***
・前提としてプログラムで扱える機能と
　モデルの状態切替についてCHECK！
・対象はSDKのSampleApp1を基準
・規約に触れる可能性があるので
　ソースコードには触れません
・網羅性は保証されません
　自分が知っていることだけ書いてあり
　その他の方法があるかもしれません
***
・代わりにSampleApp1が基礎になってる
　GadgetXLive2Dで概要を掴めるサンプルを用意
https://www.dropbox.com/s/9sdll8gq4ib6e6q/motiontest.zip?dl=0
***
##パラメーターの直打ち
![paramset.PNG](https://qiita-image-store.s3.amazonaws.com/0/117475/adbe13ba-aa62-a4cc-9f7e-ca244d3a88bb.png)

***
APIで直接パラメーターを変更する方法

・プログラム側で値を用意する必要がある
・自由度は大きい
　-複数の表情を混ぜあわせたり
　-顔と体で別々にモーション制御可能
・Mecanimもこの系統
・マバタキや呼吸なども厳密にみるとこの系統
***
###メリット
・自由度
###デメリット
・モデル制作側がタッチしづらい
***
##モーション
![mtn.PNG](https://qiita-image-store.s3.amazonaws.com/0/117475/06c68402-33e4-2c81-a4c2-edcd4c648107.png)
***
mtnやmtnbを読み込んで使用する方法
優先度付き・グループ名で呼び出す
　　　　　　　　　　　（SampleApp1では）
***

モーションはViewerでModel.jsonにまとめる
![motion.PNG](https://qiita-image-store.s3.amazonaws.com/0/117475/65ee2aa9-85d9-b6db-841a-0b1432bae0d1.png)
***
##2つの切り替え方法
***
###1.残り値で切り替える
***
再生されたあとの終了値が残る現象を利用
・複雑な入モーションが可能
・一度に使えるモーションは一つ（未改造時）
・アイドリングはモーションかパラメーター操作
![motion1.PNG](https://qiita-image-store.s3.amazonaws.com/0/117475/554521f6-a37e-6af0-4b19-93a196e4eac3.png)
***
###メリット
・複雑な入モーション
・Live2D側で設計可能
###デメリット
・残す値戻す値の整合性維持が難しい
***
###2.待機モーション自体を変更
***
アイドリングの呼び出しを入れ替えていく方式
切替時は優先度２か３
アイドル時は１でかけ続ける
![motion2.PNG](https://qiita-image-store.s3.amazonaws.com/0/117475/b0bf6d67-6161-b616-d098-7e45d0d6cd20.png)
***
###メリット
・残り値は気にしなくてよい
・こちらもLive2D側で設計可能
・待機状態の変化も設計可能
###デメリット
・ファイル数はかなり増える
***
##Exp.json表情ファイル
***
![exp.PNG](https://qiita-image-store.s3.amazonaws.com/0/117475/b541d4e4-3f11-4a6b-bfc1-fb76baeeb08d.png)
Viewerで追加できるファイル
パラメーター状況を記録し、切り替えられる
モーションと併用可
***
###メリット
・モーションと併用可
・切り替えはとても単純に
###デメリット
・複雑な入が不可
***
#ここまでのまとめ
***
![票１.png](https://qiita-image-store.s3.amazonaws.com/0/117475/d752daf0-fcb7-5288-752d-0abe1ce2b2de.png)
***
#今回当たった　　　ケースの仕様
***
・全てのパラメーターの頭にデフォルト値を打つ
・標準がアイドリングモーションとして使用
・呼吸と目パチは標準だけ
・残りは全てスタート向けモーション
***
###以上のことから考えられるプログラム仕様
***
##MTNファイルを処理してから読み込む方式
・それ故全パラメーターに値が必要
・話を詰めた感じたぶんこれであると思われる
・もしかしたら値AddでMecanimかも？
***
##実はアイドリングはパラメーター直打ち方式
・標準以外を基準で考えるとコレ？
・標準モーションは標準に戻すため使用
・標準だけがしょぼくなるかも？
***
##全てのモーションがアイドリング
・頭に値を入ってることを考えるとコレ
・入モーションとして作成したので
　落ち着きなくなる
***
##すぐに表情が戻るがそれが仕様
・こちらの誤解
・一度見た動作確認アプリの動作はコレ
・なんかもったいない感
***
#どんな情報を共有すべきか？
***
##モーションの流され方
・使用タイミング
・モーション間の連結について
・アイドリングの方法
***
##パラメーターの権限
・さわっちゃイケナイ値
・設計する値
・入力しても無視される値
・指定のある値
・値が被ったときの優先順位や計算方法
***
##最後に
組み込みモデルを作るとき、やはり最後のプログラムでの動きというのはとても気になる
ファイルが切り替え可能なサンプルプログラムを配布したらどうだというのもあるけどこれはSDKの規約的にNG
それ故プログラム作成側とモデル作成側の情報交換は大事
英語のいろは歌にどの程度の重複があるのか確認する

英語にも「いろは歌」があるらしいことを知りました。

以下が英語の「いろは歌」だそうです。

```
The quick brown fox jumps over the lazy dog.
```

`The` 被ってるじゃん。

# というわけで

どの程度重複しているのか確認してみました。

```
[root@centos7 iroha]# echo 'The quick brown fox jumps over the lazy dog.' | grep -o '[[:graph:]]' | sort
.
T
a
b
c
d
e
e
e
f
g
h
h
i
j
k
l
m
n
o
o
o
o
p
q
r
r
s
t
u
u
v
w
x
y
z
[root@centos7 iroha]#
```

ざっと見た感じそこそこ重複があるようです。
重複の割合を計算してみます。シェル芸勉強会で覚えた `bc -l` を使います。

```
[root@centos7 iroha]# echo 'The quick brown fox jumps over the lazy dog.' | grep -o '[[:graph:]]' | sort | wc -l
36
[root@centos7 iroha]# echo 'The quick brown fox jumps over the lazy dog.' | grep -o '[[:graph:]]' | sort -u | wc -l
28
[root@centos7 iroha]# echo '(38-28)/38*100' | bc -l
26.31578947368421052600
[root@centos7 iroha]#
```

なんか長かったので分けました。シェル芸とは何だったのか。
26% 程度の重複があります。

普通のいろは歌でもやってみます。

```
[root@centos7 iroha]# echo 'いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす' | grep -o '.' | sort | wc -l
47
[root@centos7 iroha]# echo 'いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす' | grep -o '.' | sort -u | wc -l
47
[root@centos7 iroha]# echo '(47-47)/47*100' | bc -l
0
[root@centos7 iroha]#
```

重複なしです。

# 結論

英語のいろは歌は結構被ってる。

# 参考
[パングラム - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%B3%E3%82%B0%E3%83%A9%E3%83%A0)
ジェネリクスの入れ子パラメータ

```java
import java.util.*;

public class NestedGenericsTest {
    public static void main(String args[]) {
        Map<String, List<String>> m1 = new HashMap<String, List<String>>(); // OK
        //Map<String, List<String>> m2 = new HashMap<String, List<>>();   // compile error
        Map<String, List<String>> m3 = new HashMap<>(); // OK
        Map<String, List<String>> m4 = new HashMap();   // unchecked warnings
    }
}
```

入れ子中のダイヤモンド演算子の利用はコンパイルエラーとなる。
Unityからスクリプトだけで利用可能な効果音管理クラス

#Unityで簡単にSEをならしたい

もともとは、こちらの「○×つくろー」さんの記事です。


その３ スクリプト内だけでSEを鳴らす
http://marupeke296.com/UNI_SND_No3_SoundPlayer.html
こちらを参考にして作成しました。


##Git

Gitはこちらです

 GitHub 
hmcGit/SoundControl
https://github.com/hmcGit/SoundControl
SoundControl - Unity SE Control Script(C#)
 
##使用方法
###再生する

```
SoundControl.Instance.playSE(SE登録キー)
```

気軽にplaySEでどこからでも呼べるのでお手軽で気に入っています。

ただし、事前に効果音を登録しておく必要があります。

private SoundControl()　（コンストラクタ）にて
SEを予め登録しておく必要があります。 登録には、呼び出しに指定するキーとファイル名を指定します
・「SE登録名（キー）」
・「SEのファイル名（Resourcesフォルダからのパスを記述」

```
private SoundControl()
{
    audioClips.Add("SE_OK", new AudioClipInfo("sound/ok", "SE_OK", 10, 2.0f));
}
audioClips.Add()を使用するSEの分だけ登録しておく必要があります。
```

インスペクター側を操作することなくスクリプトでどこからでも呼び出すことが出来ます。
||= とは？

## 個人的なメモ

人のコードを拝見してるとたまに出てくる ||= は一体なんだろうかと。

## irbで調べてみる。

変数に`nil`を与える。

```rb
irb(main):001:0> hoge = nil
=> nil
```

本題のメソッドを使って見る。
１回目に||= "hello,ruby"を入れると代入される。
２度目に||=を入れても"値が代入されない。"

```rb
irb(main):002:0> hoge ||= "hello, ruby"
=> "hello, ruby"
irb(main):003:0> hoge ||= "hello, hoge"
=> "hello, ruby"
```

## もう一回試す。

```rb
irb(main):005:0> hoge = nil
=> nil
irb(main):006:0> hoge ||= "hello, hoge"
=> "hello, hoge"
irb(main):007:0> hoge ||= "hello, ruby"
=> "hello, hoge"
irb(main):008:0> 
```

## わかったこと。

||= は変数に値がnilであれば、右辺の値（またはメソッド）を代入することができる
便利なやつ！

そして、irb先生便利。
math > sin(kx)cos(kx)の積分 / desmosで比較 / Wolfram Mathematicaでは元の式となった

CG分野で使われるSpherical Harmonics。自分の数値シミュレーション計算に用いたいと思い調べると、量子化学の講義にたどり着く。

そして関連ビデオを見ていると出てきた数式。

そのビデオの中の積分の結果が自分の導出と異なる。

ビデオの式では以下となっている。

```math
\int{sin(kx)cos(kx)}dx = -\frac{1}{2k}cos^2(kx)
```

この積分は2通りの方法を試した。

### t=sin(kx)を使う編

以下の式を<font color=red>(式1)</font>とする。

```math
\int{sin(kx)cos(kx)}dx
```
上記の式が与えられた時に思うのは「片方消せばいい」ということ。

cos()を消すには1/cos()をかければいい。

1/cos()を作るには「sin()の微分(=cos())の逆数があればいい」となる。

ということで以下のようにtを定義する。

```math
t = sin(kx)
```

xで微分して

```math
\frac{dt}{dx} = cos(kx)k
```

上記をdx=の式に変形する。

```math
dx = \frac{dt}{cos(kx)k}
```

このdxの式を式1に代入すると

```math
\int{sin(kx)cos(kx)\frac{dt}{cos(kx)k}}
```
となり

```math
=\int{sin(kx)\frac{dt}{k}}
```

t=sin(kx)と置いたので

```math
=\int{t\frac{dt}{k}}
```
でこれはtの積分なのでt^2/2となり

```math
=\frac{1}{k}\frac{t^2}{2}
=\frac{1}{2k}sin^2(kx)
```

として式が導出された。
が、ビデオの式とは違う。

### 加法定理を使う編

以下は再度、<font color=red>(式1)</font>。

```math
\int{sin(kx)cos(kx)}dx
```

この式を見て思い出すのは加法定理

```math
sin(2x) = 2sin(x)cos(x)
```

式変形して

```math
sin(x)cos(x) = \frac{sin(2x)}{2}
```

```math
sin(kx)cos(kx) = \frac{sin(2kx)}{2}
```

この式を式1に代入して

```math
\int{sin(kx)cos(kx)}dx
```

```math
= \int{\frac{sin(2kx)}{2}}dx 
```

sin()の積分は-cos()、2kxの微分は2kなので

```math
= -\frac{cos(2kx)}{2*2k}
= -\frac{cos(2kx)}{4k}
```

として導出された。
がビデオの式とは違う。

### desmosで比較

自分が導出した2つの式とビデオの式をdemosで可視化した。
https://www.desmos.com/calculator/huzg9fydem

波の位相は合っている。
縦方向が異なるが、これは積分定数が異なる、ということだろうか。

### 元の式

Wolfram Mathematicaで元の式が導出された。

http://integrals.wolfram.com/index.jsp?expr=sin%28kx%29cos%28kx%29&random=false

ビデオの人は自分で導出はしてないのかもしれない。

式が複雑になってくる場合、こういうツールを使うのは普通かと思う。

### 2つ目の式

Wolfram Mathematicaでsin(kx)cos(kx)の式に+1すると+1の積分以外はこの記事の2つ目の式となった。

http://integrals.wolfram.com/index.jsp?expr=sin%28kx%29cos%28kx%29%2B1&random=false
viで編集するために必要な最低限覚えておくべき10のコマンド

viで編集するために最低限覚えておくべきコマンドをまとめました。
この10のコマンドさえあればとりあえず編集できます。
→(いずれ)スマートに編集するために必要なあと10のコマンド


# 操作基礎

 `vi ファイル名`
 で起動

* 起動時はコマンドモードで下記のコマンドが使える状態。
* 入力コマンドを押すとINSERTモードに切り替わり、ファイルに加筆したり修正したりできる状態になる。
* ふたたびコマンドモードに戻るためにはキーボードの「Esc」を押せば戻る。


# 移動コマンド

コマンド|説明
|:----------------:|:-----------------:|
h|←|左に移動
j|↓|下に移動
k|↑|上に移動
l|→|右に移動

# 検索コマンド

|コマンド|説明|
|:----------------:|:-----------------:|
/<文字列>|文字列 を検索する(「n」で次の検索結果にジャンプ)

# 入力コマンド

コマンド|説明
|:----------------:|:-----------------:|
i|カーソルの左から入力開始

# 行追加
コマンド|説明
|:----------------:|:-----------------:|
o|現在の行の下に１行挿入、INSERTモードで入力開始

# 削除コマンド
コマンド|説明
|:----------------:|:-----------------:|
x|カーソル上の1文字削除

# 終了コマンド
コマンド|説明
|:----------------:|:-----------------:|
:wq|保存して終了
:q!|保存せずに終了
Windows10 に pycuda をインストール

折角、GTX1070を購入したのでpythonでCUDAにトライしてみようと思って環境を準備したら、意外とはまったので。
ほぼ自分のインストールメモで文字しかないですが参考になれば。

- 環境
 - Windows10 Home 64bit Anniversary Update
 - Python 3.5.2(Anaconda 4.1.1 (64-bit))
 - Geforce GTX1070

- インストール
 - [Anaconda 4.1.1 For Windows]
(https://www.continuum.io/downloads#windows)

 - [Visual Studio Community 2013 with Update 5]
(https://www.visualstudio.com/ja-jp/downloads/download-visual-studio-vs.aspx)
     - インストール後、環境変数PATHの一番目に「C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin」を追加
  - [CUDA Toolkit 8.0 Release Candidate](https://developer.nvidia.com/cuda-release-candidate-download)
  - [When the CUDA Toolkit will support GTX1070 Graphics Card???](https://devtalk.nvidia.com/default/topic/949823/when-the-cuda-toolkit-will-support-gtx1070-graphics-card-/)
      - 上記に従いグラフィックドライバの最新版を再インストール

pycuda は pip でインストール。
> pip install pycuda

テストコードを実行するとUnicodeDecodeErrorが出るので[ここ](http://qiita.com/masato/items/713fa8876e50a65d575c) を参考にcompiler.pyの264行目辺りに以下のコードを追加

```py3:Anaconda3\lib\site-packages\pycuda\compiler.py
...
        self._check_arch(arch)

        if options is not None:
            options.extend(["-Xcompiler","/wd 4819"])
        else:
            options = ["-Xcompiler","/wd 4819"]

        cubin = compile(source, nvcc, options, keep, no_extern_c,
                arch, code, cache_dir, include_dirs)
...
```

[テストコード](https://documen.tician.de/pycuda/tutorial.html)で動作確認。

```py3:test_pycuda.py

import pycuda.gpuarray as gpuarray
import pycuda.driver as cuda
import pycuda.autoinit
import numpy

a_gpu = gpuarray.to_gpu(numpy.random.randn(4,4).astype(numpy.float32))
a_doubled = (2*a_gpu).get()
print (a_doubled)
print (a_gpu)
```

実行結果は下記の通り。
時間計測も何もしていないが動いてはいるようだ。
>
[[ 0.06258085  3.00050306 -2.16977096 -1.87397981]
 [-2.13656282  4.49329472  0.04928281  3.36462641]
 [-0.23879284 -2.65320969 -0.87821233  0.39281949]
 [ 0.31394795 -0.32421556  0.16610235  2.44501066]]
[[ 0.03129042  1.50025153 -1.08488548 -0.9369899 ]
 [-1.06828141  2.24664736  0.0246414   1.6823132 ]
 [-0.11939642 -1.32660484 -0.43910617  0.19640975]
 [ 0.15697397 -0.16210778  0.08305117  1.22250533]]

ちなみにはまった理由は完全に自分のミスで

- GTX1070に対応していない(?)CUDA Toolkit 7.5をインストールしてしまった
- 最初python2.7系と3.5系の両方がインストールされていて混乱した。（結局、2.7系は一旦アンインストール)
mixで作成しているアプリの再読み込みをする

`iex -S mix` でコンパイルしたElixirアプリのコードを編集した後に自動的に再読み込みさせたかったんですが、調べたところ無理でした。

ということでメモ代わりにどこかで拾ったコピペスクリプトを貼っておく

```ex
defmodule R do
  def reload do
    Mix.Task.reenable "compile.elixir"
    Application.stop(Mix.Project.config[:app])
    Mix.Task.run "compile.elixir"
    Application.start(Mix.Project.config[:app], :permanent)
  end
end
```

やってることは単純でAppilicationをコンパイルして再読み込みさせてるだけ

実行

`R.reload`
WindowsとCentOS間でフォルダを共有する方法


# WindowsとCentOS間でフォルダを共有する方法  (所要時間 5～15分)

 WindowsとCentOS間でフォルダを共有する方法を紹介します。
 スクショはいずれ。。。

## Windows側での作業 ##

 1. Windowsでフォルダを選択し、右クリックで「プロパティ」を選択します。

 1. 「共有」タブの「詳細な共有」を選択します。

 1. 「このフォルダーを共有する」にチェックを入れます。

 1. 「アクセス許可」をクリックします。

 1. 「Everyone」のアクセス許可に「フルコントロール」「変更」を追加します。

 1. コマンドプロンプトを起動します。
		（「スタート」で「cmd」と検索し起動、もしくは「スタート」->「すべてのプログラム」->「アクセサリ」->「コマンドプロンプト」で起動）

 7. `ipconfig` と入力しWindowsのIPアドレスを確認します。


---

## CentOS側での作業

 1. デスクトップの「場所」タブから「サーバへ接続」を選択します。

 1. 下記のように入力します。

|設定名|記入内容|
|:-----------------|------------------:|:------------------:|
|サービスの種類|「Windows共有」|
|サーバ名|7で調べたWindowsのIPアドレス」|
|共有する場所|「共有するフォルダ名」|
|フォルダ|「とりあえず空欄でOK」|
|ユーザ名|「とりあえず空欄でOK」|
|ドメイン名|「とりあえず空欄でOK」|

※ブックマークを追加するはチェックしなくてOKです。

　
3. `「"フォルダ名@WindowsのIPアドレス"を共有するにはパスワードが必要です」`
   という画面が出るので下記を入力し「接続する」をクリックします。

項目名|記入内容
|:-----------------|:------------------:|
ユーザ名|「Windowsのログインで使用するユーザ名」
ドメイン名|「MYGROUP」でOK
パスワード|「Windowsのログインで使用するパスワード」

 ※ドメインを設定している場合は「マイコンピュータ」で右クリックしてドメインを確認する。


4. フォルダが表示されますので、右クリックで「ドキュメントの生成」->「空のファイル」をクリックします。
	* 問題なくファイルが生成できればこれで作業完了です。
	* もしファイルが作成できなかった場合は3と5の設定をもう一度確認してみてください！
Emacs で python コーディング用に タグジャンプ を使う設定の備忘録

python コーディングのための、emacs タグジャンプの設定を忘れないように記録しておこうと思います。

# 環境
・ Ubuntu 16.04
・ Emacs 24.5.1

# やったこと

・ ターミナルで下記を実行して、インストール

```
$ sudo apt install exuberant-ctags
```

・ ターミナルで下記を実行して、TAG ファイルを作成。

```
$ ctags -Re
```

・ emacs のソースコード上で、定義されている箇所にタグジャンプするため、emacs 中で下記を実施。

```
M-.(ドット) 
```

・ 所望のものと違った場合は、次の候補にタグジャンプするため、emacs 中で下記を実施。

```
Ctrl-u M-.(ドット) 
```
JavaScriptでURLの解析をしたかった

フロントエンド JavaScript で「URL 文字列からパス部分を抽出したい」という有りがちな処理をやりたかった時に、気持良く解決できなかったという作業ログです。

誰の役に立つのかわからないですが、とりあえず書いてみました。


## window.location オブジェクト
- 解析対象の URL は当ページの URL ではない
- 文字列として URL を解析出来る方法が必要なので NG


## URL オブジェクト
- 担当サービスの対応ブラウザである IE10, IE11 に無い
  - 正確には存在するけど `function` ではない別物


## URL オブジェクトを polyfill
- よろしい、ならば polyfill だ
- https://github.com/Polymer/URL を使ってみた
  - `''` を `'/'` にするかしないかが Chrome と異なっていた
- https://github.com/inexorabletash/polyfill/blob/master/url.js を使ってみた
  - 相対パスを展開するかしないかが Chrome と異なっていた 
- そもそも URL オブジェクトの仕様はまだ未確定
  - Ref) https://url.spec.whatwg.org/
- 仕様が安定していないものを polyfill するのは止めた方が良さそう


## DOM を介して解析
- `var a = document.createElement('a'); a.href = 'http://example.com';` から解析するハックがある
- ブラウザ内でもいわゆるモデルっぽい場所で使われるので、そこで DOM に依存したくない
- すみません、何か気分的に無理
  - あえて言うなら、速度感が単体関数とかけ離れそう（未調査ですが）


## npm から探す
- https://www.npmjs.com/package/url-parse
  - API は `Node.js` の `url` モジュール準拠で良さそう
  - しかし、browser 用のビルドが無い（単品で欲しかった）
  - オレオレで fork して browserify を掛けるのは、ちょっとなぁ
- https://www.npmjs.com/package/url
  - 大体↑の url-parse と同じような状況
- https://medialize.github.io/URI.js/
  - API は独自、不要に柔軟な印象を受ける
  - ビルドが[ココ](https://medialize.github.io/URI.js/)からオプションを指定してやる方式、できれば唯一のソースが良かった
  - jQuery とか入ってるし・・・。
- 他に :star: や DL 数が多そうなものがわかりませんでした
  - 良さそうなのは大抵 browserify でコンパイルしてくれって書いてある


## 結末
今回は正規表現さんで対応しました。
POSTで送信されたデータを確認する方法


Web開発をおこなっているとPOSTされたデータを確認したい場合があります。
今回はPHPのビルトインサーバーに対してPOSTしたデータを2種類の方法で確認してみます。

なお、環境はOS X El Capitanとなります。

## ビルトインサーバーを起動しておく

```
$ mkdir ~/webroot
$ cd ~/webroot
$ vim index.html
```

```index.html
Hello World.
```

```
$ cd
$ php -S localhost:8080 -t ~/webroot
```

PHPのビルトインサーバーについては詳しくは公式マニュアルを
http://php.net/manual/ja/features.commandline.webserver.php



## tcpdump

tcpdumpはTCP/IPなどのパケットをダンプして表示させることができるツールです。

### 実行例
`$ sudo tcpdump -A -p -s 0 -i lo0 -n 'dst port 8080 and greater 100'`

### オプション解説

#### -A
パケットの内容をASCIIで表示する。

#### -p
非プロミスキャスモードで動作させる。自ホスト宛のデータのみキャプチャする。

#### -s size
パケットから取得するサイズを指定する。0を指定した場合には無制限に取得する。

#### -i interface
インターフェースを指定する。今回はビルトインサーバーから取得するのでlo0を指定する。

#### -n
ホスト名やポート番号を変換せずにそのまま表示。

#### 'dst port 8080 and greater 100'
ダンプするパケットのフィルター

`dst port 8080`
パケットの宛先ポート番号を指定

`greater length`
パケットがlengthで指定した長さ以上の場合に真

### tcpdumpを試す

#### curlでデータをPOSTする
`$ curl -sS --include -X POST 'http://localhost:8080' -d 'a=1'`


```
HTTP/1.1 200 OK
Host: localhost:8080
Connection: close
Content-Type: text/html; charset=UTF-8
Content-Length: 13

Hello World.
```

#### tcpdumpでパケットをキャプチャする

`$ sudo tcpdump -A -p -s0 -i lo0 -n 'dst port 8080 and greater 100'`


```
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo0, link-type NULL (BSD loopback), capture size 262144 bytes
07:11:54.078079 IP6 ::1.52963 > ::1.8080: Flags [P.], seq 1880446489:1880446639, ack 499426002, win 12743, options [nop,nop,TS val 785863894 ecr 785863894], length 150: HTTP: POST / HTTP/1.1
`.{....@....................................p.V.......1........
..T...T.POST / HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.43.0
Accept: */*
Content-Length: 3
Content-Type: application/x-www-form-urlencoded

a=1
```

`a=1`とPOSTしたデータが確認することができます。



## ngrep
grepの様に使える、パケットをキャプチャできるツール。
http://ngrep.sourceforge.net/

### インストール

`$ brew install ngrep`

### 実行例

`$ sudo ngrep -d lo0 -W byline port 8080`

### オプション解説

#### -d
LISTENするインターフェースの指定

#### -W
表示方法、bylineを指定するとlinefeedsで改行する。

### port
パケットの送信元ポートまたは宛先ポートを指定する。

### ngrepを試す

#### curlでデータをPOSTする
`$ curl -sS --include -X POST 'http://localhost:8080' -d 'a=1' -d 'b=2' -d 'c=3'`

#### ngrepでパケットをキャプチャする

`$ sudo ngrep -d lo0 -W byline port 8080`



```
interface: lo0 (127.0.0.0/255.0.0.0)
filter: (ip or ip6) and ( port 8080 )
#####
T ::1:50538 -> ::1:8080 [AP]
POST / HTTP/1.1.
Host: localhost:8080.
User-Agent: curl/7.43.0.
Accept: */*.
Content-Length: 11.
Content-Type: application/x-www-form-urlencoded.
.
a=1&b=2&c=3
```

`a=1&b=2&c=3`とPOSTしたデータが確認することができます。

## 最後に
より便利なオプションや使い方があれば教えて頂けたら幸いです。

ここまで読んでいただき、ありがとうございました。
LinuxでMonoを使ってC#をコンパイル・実行する

目標：

- NuGetを使ってRestSharpをインストールする
- RestSharpを使ってHTTP POSTする


## Monoをインストール

自分はArch Linuxなので

```
pacman -S mono
```

でインストール。他のディストロの場合は`yum`か何かで探してみてください。


## NuGetをインストールする

```
wget --no-check-certificate https://nuget.org/nuget.exe
```

```
mozroots --import --machine --sync
certmgr -ssl -m https://go.microsoft.com
certmgr -ssl -m https://nugetgallery.blob.core.windows.net
certmgr -ssl -m https://nuget.org
```

途中何か聞かれるので`yes`と入力。

こちらを参考にさせていただいた。
http://symfoware.blog68.fc2.com/blog-entry-1750.html

※mozrootsとcertmgrはmonoパッケージに含まれるコマンド


## NuGetでRestSharpをGET

```
mono nuget.exe install RestSharp
```

カレントディレクトリの下に`RestSharp.105.2.3`がダウンロードされた。


## DLLへのパスを通す

```
export MONO_PATH=./RestSharp.105.2.3/lib/net452
```


## コードを書く

```Test.cs
using System;
using RestSharp;

class Test
{
    public static void Main()
    {
        var client = new RestClient("http://httpbin.org");

        var request = new RestRequest("/post", Method.POST);
        request.AddParameter("hoge", "123"); // adds to POST or URL querystring based on Method
        request.AddParameter("sage", "456"); // adds to POST or URL querystring based on Method

        // execute the request
        IRestResponse response = client.Execute(request);
        var content = response.Content; // raw content as string

        Console.WriteLine(content);
    }
}
```

RestSharpの使い方についてはこちら：
http://restsharp.org/


## ビルドして実行

```
$ mcs -reference:./RestSharp.105.2.3/lib/net46/RestSharp.dll Test.cs

### ./Test.exe でも実行できる
$ mono Test.exe

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "hoge": "123", 
    "sage": "456"
  }, 
  "headers": {
    "Accept": "application/json, application/xml, text/json, text/x-json, text/javascript, text/xml", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "17", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "RestSharp/105.2.3.0"
  }, 
  "json": null, 
  "url": "http://httpbin.org/post"
}
```

※`Test.exe`と`RestSharp.dll`を同じディレクトリに置いておけば`MONO_PATH`はセットしなくてもいい模様
配布時の推奨ディレクトリ構造がここに書いてある：
http://www.mono-project.com/docs/getting-started/application-deployment/


## REPLを使う

```shell-session
$ csharp
Mono C# Shell, type "help;" for help

Enter statements below.
csharp> DateTime.Now 
2016/09/17 12:30:35                   
csharp> 
```

補完も効くので便利。
ELB + Apache で本番サーバを運用するときによくやる設定

Apache 2.4 について書いてるので、2.2 だとちょっと違うかもしれない

# Apache
## Apache のバージョンを表示させない
``` httpd.conf
ServerSignature Off
ServerTokens Prod
```

- サーバーエラー時に Apache のバージョン表示消す
- HTTP ヘッダから Apache のバージョン消す

## アクセスログの設定
``` httpd.conf
LogFormat "host:%{X-Forwarded-For}i\tident:%l\tuser:%u\ttime:%{%d/%b/%Y:%H:%M:%S %z}t\tmethod:%m\tpath:%U%q\tprotocol:%H\tstatus:%>s\tsize:%b\treferer:%{Referer}i\tagent:%{User-Agent}i\tresponse_time:%D" ltsv
SetEnvIf User-Agent "ELB-HealthChecker" nolog
SetEnvIf User-Agent "internal dummy connection" nolog
CustomLog "logs/access_log" ltsv env=!nolog
```

- ログフォーマットを LTSV にする
    - 参考： [ApacheログをLTSV形式にする際の２つの落とし穴と対処法＋Apache＆FluentdのLTSV設定サンプル - Y-Ken Studio](http://y-ken.hatenablog.com/entry/apache-tips-ltsv-access-log)
- IP アドレスを ELB の IP アドレスではなく X-Forwarded-For を見るようにする
- ELB のヘルスチェックをログに書き出さない
- ELB の internal dummy connection をログに書き出さない
- mackerel で外形監視をしている場合は以下の行も追加する
    - `SetEnvIf User-Agent "mackerel-http-checker" nolog`

## ELB のときの http → https リダイレクト設定
``` httpd.conf
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Port} !^443$
RewriteCond %{HTTP_USER_AGENT} !^ELB-HealthChecker
RewriteCond %{HTTP:X-FORWARDED-FOR} !^$
RewriteRule ^(.*)?$ https://%{HTTP_HOST}$1 [R=301,L]
```

- ELB のヘルスチェックはリダイレクトしない
- ELB 以外 (VPC 内部) からのアクセスはリダイレクトしない

SSL に関する設定はアプリケーション側にあまり意識してほしくないので `.htaccess` に書くよりも `httpd.conf` に書いたほうが良いと思う

# ELB
## アイドルタイムアウトを 20 秒に設定する
Apache 2.4 を使っているとアクセスログに 408 エラーが大量に出るので、ELB の設定でアイドルタイムアウトを 60 秒から 20 秒に変更する

参考： [ELB-httpd間で408エラー多発 - 駆け出しアクアテラリストのIT奮闘記](http://iryond.hatenablog.com/entry/2015/10/25/161326)

# オマケ： PHP
## `X-POWERED-BY` ヘッダで PHP のバージョンを送るのをやめる
``` php.ini
expose_php = Off
```
ActiveRecord で接続している PostgreSQL のバージョンを確認する

Rails console で以下のようにすると良い。

```
[1] pry(main)> ActiveRecord::Base.connection.instance_eval { postgresql_version }
=> 90504
```

この値の解釈については `pg` の gem の中身を参照。
https://github.com/ged/ruby-pg/blob/1f274f68c16f1af1c642db1b9d3d28aef169dc84/ext/pg_connection.c#L775-L785

```c
/*
 * call-seq:
 *   conn.server_version -> Integer
 *
 * The number is formed by converting the major, minor, and revision
 * numbers into two-decimal-digit numbers and appending them together.
 * For example, version 7.4.2 will be returned as 70402, and version
 * 8.1 will be returned as 80100 (leading zeroes are not shown). Zero
 * is returned if the connection is bad.
 *
 */
```

とのことなのでこれは 9.5.4 ということになるようです。
偶数長の窓関数の出力の違い

# はじめに

信号処理で広く使われる窓関数の、`python` による生成方法は複数ある。
その生成方法によって微妙に振る舞いが異なったので備忘録として記録しておく。
(ここではハミング窓に限定。たぶんどの窓でも似たことが生じる)

# 比較対象
比べる候補は以下の３種類。窓幅は $N$ とする。

* `numpy.hamming(N)`
* `scipy.signal.hamming(N)`
* `scipy.signal.get_window('hamming', N)`

# 比較結果
$N$ が奇数のときは全て同じ。

```py
>>> import scipy.signal, numpy
>>> N = 5
>>> numpy.hamming(N)
array([ 0.08,  0.54,  1.  ,  0.54,  0.08])
>>> scipy.signal.hamming(N)
array([ 0.08,  0.54,  1.  ,  0.54,  0.08])
>>> scipy.signal.get_window('hamming', N)
array([ 0.08,  0.54,  1.  ,  0.54,  0.08])
```

しかし、$N$ が偶数になると様子が変わる。 (`get_window`)

```py
>>> import numpy, scipy.signal
>>> N = 4
>>> numpy.hamming(N)
array([ 0.08,  0.77,  0.77,  0.08])
>>> scipy.signal.hamming(N)
array([ 0.08,  0.77,  0.77,  0.08])
>>> scipy.signal.get_window('hamming', N)
array([ 0.08,  0.54,  1.  ,  0.54])
```

ところが、`get_window` の 3 つ目の引数に `False`をいれると結果が揃う。

```py
>>> scipy.signal.get_window('hamming', N, False)
array([ 0.08,  0.77,  0.77,  0.08])
```

# なぜか
`scipy.signal.hamming` と `numpy.hamming` は、デフォルトでは
左右対称になるように窓関数の値を生成する。
一方、`get_window` では、FFT で使いやすいように"periodic"(?) な値が生成されて、
3つ目の引数を `False` にすると、フィルタで使いやすい対称的な値が生成される。

そのため、デフォルトの振る舞いが関数によって異なっている。

# 参考文献
http://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.hamming.html
http://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.get_window.html
どこのJavaScriptを読み込んでいるか知りたい

配信広告などを読み込んでいると、どんなJavaScriptを読み込んでいるかサービス提供者でも分かりません。しかし少しでも分かる手がかりが欲しいところです。探したところこんなものを見つけました。

[パフォーマンスまわりのAPIについて \- Qiita](http://qiita.com/makotot/items/70bd392a62afd43d3189#resource-timing-api)

`performance.getEntriesByType('resource')` を使えばダウンロードしたURLについての情報くらいは取ることが出来ます。残念なことにiframeのURLはこれで取れるのですが、iframeの中でリクエストしたURLは取れません。配信広告の場合、iframeの中でiframeが呼ばれてその中でさらに…（iframe地獄）、というようにして様々な配信広告に繋ぎにいきますが、これについては取得することはできません。

[Can I use\.\.\. Support tables for HTML5, CSS3, etc](http://caniuse.com/#feat=resource-timing)

Can I useを見るとSafariは対応してないのでSafariについては取れませんし、APIも存在していない可能性を考慮して書く必要があります。なので

```js
(function(){
  window.setTimeout(function(){
    if (typeof performance !== 'undefined' && typeof performance.getEntriesByType !== 'undefined') {
      var p = performance.getEntriesByType('resource');
      var i = 0;
      for (i = 0; i < p.length; i++) {
        console.log(p[i].name);
      }
    }
  }, 2000);
})();
```

このようなコードを書けば、とりあえずざっくりとどこにリクエストを送っているかは取得できます。

本来はパフォーマンス用途ですが、こういう使い方もできますよーということで。
CakePHP2の__d()はsprintfフォーマット使えますよ


他の人が書いたコードをみてたら、下記の様なコードを発見。

```php
echo __d('foo', sprintf('Please input %s', $label));
```

でもわざわざsprintfかまさなくても ↓ こんな感じで書けますよ〜

```php
echo __d('foo', 'Please input %s', $label);
```

## 余談
__d()関数追ったら [vsprintf()](http://php.net/manual/ja/function.vsprintf.php)なんて関数あるの初めて知った(^^;
nginxのerror.logをtd-agentを使用してtreasure data送る


##環境
* OS：Amazon Linux AMI release 2016.03
* td-agent：td-agent 0.12.26
* nginx：nginx version: nginx/1.10.1

##概要
/var/log/nginx/error.logをtd-agentを使用してtreasure dataに送りたい。その際、error.logのformat指定方法で四苦八苦したのでメモする。


##nginxのerror.logのサンプル

```/var/log/nginx/error.log
[ 2016-09-06 18:01:55.4569 31618/7ff7ec8ce840 age/Wat/WatchdogMain.cpp:1291 ]: Starting Passenger watchdog...
[ 2016-09-06 18:01:55.4698 31624/7f6b03425840 age/Cor/CoreMain.cpp:982 ]: Starting Passenger core...
[ 2016-09-06 18:01:55.4699 31624/7f6b03425840 age/Cor/CoreMain.cpp:235 ]: Passenger core running in multi-application mode.
```

##設定した内容

```/etc/td-agent/td-agent.conf
抜粋)
## tail nginx log
<source>
  type tail
  path /var/log/nginx/access_log
  format ltsv
  time_format %d/%b/%Y:%H:%M:%S %z
  tag <タグ名>
  pos_file /var/log/td-agent/nginx_access.pos
</source>

<source>
  type tail
  path /var/log/nginx/error.log
  pos_file /var/log/td-agent/nginx_error.pos
  tag <タグ名>
  format /^\[ (?<time>[^\.]+)\.[^ ]+ (?<pid>\d+)\/(?<tid>\w+) (?<path>[^ ]+) \]: (?<message>.*)$/
  time_format %Y-%m-%d %H:%M:%S
</source>
```


##便利だったこと
以下サイトで正規表現を試せるので便利だった。
http://fluentular.herokuapp.com/

##やり残したこと

```
18:01:55.4569
```

ミリ秒をうまく指定することができなかったので、良い方法があれば教えてください。
Rails 5のAPIモードでToDoアプリ用のREST APIを作ってみる

Ruby on Rails 5.0からAPIモードが追加されたので試しにToDoアプリ用のAPIを作ってみようと思います。
環境は以下のとおりです。

| Ruby/Ruby on Rails | バージョン |
|:-:|:-:|
| Ruby | 2.3.1 |
| Ruby on Rails | 5.0.0 |

# アプリをAPIモードで作成する

1. ディレクトリを作成する

    ```
    $ mkdir todo-api
    $ cd todo-api
    ```

1. Gemfileを作成する

    ```
    $ bundle init
    ```

1. Gemfileの`# gem "rails"`のコメントアウトを外す
1. Railsをインストールする

    ```
    $ bundle install --path vendor/bundle
    ```

1. Railsアプリを作成する

    ```
    $ bundle exec rails new . --api
    ```
    途中でGemfileの上書きを確認されるので上書きを許可する

# APIを作成する

1. ScaffoldでTaskの雛形を生成する

    ```
    $ bin/rails g scaffold Task title:string description:text
    ```

以上です。

# 動かしてみる

1. DBを作成する

    ```
    $ bin/rails db:create db:migrate db:fixtures:load
    ```

1. Railsを起動する

    ```
    $ bin/rails s
    ```

1. APIを叩く

    ```
    $ curl http://localhost:3000/tasks
    [{"id":298486374,"title":"MyString","description":"MyText","created_at":"2016-09-06T10:12:04.626Z","updated_at":"2016-09-06T10:12:04.626Z"},{"id":980190962,"title":"MyString","description":"MyText","created_at":"2016-09-06T10:12:04.626Z","updated_at":"2016-09-06T10:12:04.626Z"}]
    $ curl http://localhost:3000/tasks/298486374
    {"id":298486374,"title":"MyString","description":"MyText","created_at":"2016-09-06T10:12:04.626Z","updated_at":"2016-09-06T10:12:04.626Z"}
    ```

JSON文字列が返ってくることを確認できましたね。
追加、更新、削除も同様に確認できます。
RailsでのAPI開発が楽になりそうですね。
Googleの共有カレンダーをAppleのカレンダーアプリで表示する方法

## はじめに
Googleの共有カレンダーはデフォルトではAppleのカレンダーアプリでは表示されない。
厳密に言うとGoogleアカウント登録を行っていれば「ウィンドウ」メニューから選択することができるが、プライベートカレンダーと一緒に表示することができない。（Googleアカウントの登録は上部の「カレンダー」>「アカウント」から行うことができる）

これらを解消し、Googleアカウントに紐付くプライベートカレンダーと共有カレンダーをカレンダーアプリの左部のメニューに表示する事を実現する方法を以降に示す。

## 方法

方法はいたって簡単で、

1. 「 https://calendar.google.com/calendar/syncselect 」にアクセス
2. 表示させたいカレンダーのチェックボックスを選択

これだけ。

Googleはまだましな方だけど、設定画面へのアクセスが素直にできないのは残念。。。

## 参考までに
この設定画面のアドレスは、とあるQAサイトで見つけたのだが、正規のルートだとどうやってアクセスするのか気になった。正しいかどうかは別として、これは辛い。。。

1. http://www.google.co.jp/sync/
2. 「カレンダー」>「デスクトッププログラムと同期」から「Googleカレンダーヘルプセンター」画面を表示
3. 「読み込み、書き出し、同期」>「Appleカレンダーとの同期」>「同期するカレンダーを変更する」>「他のカレンダーの同期」
4. 手順の1.に示されるリンクからアクセス

手っ取り早いのは

「google calendar syncselect」

で検索することだけど、実はこっちが正解なのか。。。
IAMRoleでS3期限付きURLの生成をしてはいけない


S3期限付きURLが指定したexpireより前に期限切れしてしまう、
という事象を追って調査した際のメモ。
こちらは同様の事象かと思われる。
- https://forums.aws.amazon.com/thread.jspa?messageID=713763

## なにが起きたか
- EC2でIAM Roleの権限を使用して、S3期限付きURLの発行を行なっていた。
  - [Javaでの実装例] (https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/ShareObjectPreSignedURLJavaSDK.html)
- その際に、有効期限（expire）を一月後に設定し発行。
- しばらくURLは有効だったが、数時間後に"ExpiredToken"となってしまう。


## どうすればよいか
IAM Userのアクセスキーペアを使用する。

## 何故？
IAM Roleで使用で発行されるキーは有効期限がある。
その為、キーの有効期限以上のexpireを設定する事は出来ない。

## まとめ
ということで、一時的な権限の使用以外ではIAMUserの権限を使用する必要がある。
IAM RoleとIAM Userの違いについて知ると確かに、ということだった。
https://aws.amazon.com/jp/iam/faqs/

*IAM RoleとIAM User*
** **
Q: IAM ロールと IAM ユーザーの違いは何ですか?
IAM ユーザーには永続的な長期の認証情報があります。また、IAM ユーザーを使用して AWS サービスと直接やり取りすることができます。IAM ロールには認証情報がなく、AWS サービスに対して直接リクエストを送信することはできません。IAM ロールは、IAM ユーザー、アプリケーション、AWS のサービス (EC2 など) などの認可されたエンティティに割り当てるために用意されたものです。

Q: IAM ユーザー、IAM グループ、または IAM ロールはどのように使い分ける必要がありますか?
IAM ユーザーには永続的な長期の認証情報があります。また、IAM ユーザーを使用して AWS のサービスと直接やり取りすることができます。IAM グループは、主に、許可が同じ1組の IAM ユーザーを管理するための管理用の機能です。IAM ロールとは、AWS サービスリクエストの送信許可を持つ AWS Identity and Access Management (IAM)エンティティです。IAM ロールから AWS のサービスに対してリクエストを直接送信することはできません。IAM ロールは、IAM ユーザー、アプリケーション、AWS のサービス (EC2 など) などの認可されたエンティティに割り当てるために用意されたものです。IAM ロールは AWS アカウント間でアクセス権限を委任するために使用します。
** **

コードにキーを埋め込まなくていいからと全てIAM Roleでやろうとして発覚。
長期的な権限を発行する際にはIAMRoleで発行するのは控えたほうがよいですね。
通常はIAMRoleを使用するべきですが、用途によってはIAMUserを使わないと行けない場面があるということを改めて認識致しました。

## おまけ - IAMRoleのキーの有効期限について -
EC2内で下記メタデータ取得のcurlで確認可能

```
curl 169.254.169.254/latest/meta-data/iam/security-credentials/[role name]/
```
結果

```
{
  "Code" : "Success",
  "LastUpdated" : "2016-09-06T08:08:23Z",
  "Type" : "AWS-HMAC",
  "AccessKeyId" : "*******",
  "SecretAccessKey" : "******",
  "Token" : "*******",
  "Expiration" : "2016-09-06T14:12:37Z" ← 有効期限
}
```
英語の文章を aspell でスペルチェック

- この記事を読むと、コマンドラインから英語文章のスペルチェックが出来るようになります。
- スペルチェックで無視したい単語を、チームで共有することができるようになります。

# 動機

英語の単語、病的なまでにスペルミスするので、スペルチェッカーに頼りたい。
md で英文書いてて、コマンドラインからスペルチェックしたい。

#  aspell

[`aspell`](http://aspell.net/) というものがあるらしい。

`$ aspell -l en -c <file>`

でスペルチェックできます。ありがとう。
`-l en` で英語を指定している。
怪しいスペルをインクリメンタルにサジェストしてくれて、
無視するか、aspell が出してる候補に置き換えるか、自分で書きかえるか。とか選択肢ができる。

例えば、`CUI` という単語には以下のようにサジェストしてくれる。

<img width="640" alt="スクリーンショット 2016-09-06 18.58.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/36144/a8ee2763-cc5c-1912-f693-08454668c7da.png">


## 専門用語問題

IT系の専門用語はスペルチェックに引っかかりやすい。
そういうのは、毎回引っかかってしまうので、ちょっと効率が悪い。

そこで、`Add`　をつかう。これもスペルミスがサジェストされた時に出て来る選択肢の中にある。　`a` とタイプすると使える。
`Add` すると、その単語は`個人辞書(personal dictionary)`に登録される。
一度、個人辞書に登録されると、次回から同じ単語が出て来ても無視されるようになる。

個人辞書は `.aspell.<言語の種類>.pws`　という名前のファイル。
英語だと `.aspell.en.pws`

## 個人辞書の共有

チームで英文のドキュメントを管理しているので、個人辞書を共有したい。
個人辞書はデフォルトではホームディレクトリに生成される。
ドキュメントは GitHub で管理してるので、リポジトリのトップに個人辞書を置く。

`-p` オプションで個人辞書のパスを指定する運用にする。

```
$ aspell -p `git rev-parse --show-toplevel`/.aspell.en.pws -l en -c <file>
```

`git rev-parse --show-toplevel`　で リポジトリのトップディレクトリの絶対パスが返ってくる。

だいぶコマンドが長くなったので、短くしたいと思っている。 

## Git で管理してるのでバックアップファイル不要

デフォルトでは、スペルを書きかえると、ドキュメントのバックアップが作成される。やさしい。
でも、ドキュメントは既に git の管理下にあるので、バックアップは不要なのです。

そこで `--dont-backup` オプションをつけて、生成されないようにする。

```
$ aspell --dont-backup -p `git rev-parse --show-toplevel`/.aspell.en.pws -l en -c <file>
```

## URL

URL はデフォルで無視されるので、ありがたい。
できれば、markdown モードも欲しい。

これでもいいかもしれない。
https://www.npmjs.com/package/markdown-spellcheck

## Install

Mac はこんな感じ

`brew install aspell`
【go】webアプリでサーバーを止めずにconfigファイルをリロードする

# やりたいこと

webサーバー起動時にconfigファイルを読み込んでstructに入れていたが、
これだとconfigファイルに変更があった場合プロセスを再起動する必要がある。
そうではなく、変更があった場合はプロセスを止めずに自動でリロードするようにしたい。

# 方法

[fsnotify](https://github.com/fsnotify/fsnotify)というライブラリを使う。
ファイルの変更などを検知してくれるので、変更がった場合に再度読み込むようにする。

# ソース

```:config.toml
name = "fuku"
age = 20
```

```go:main.go
package main

import (
    "github.com/BurntSushi/toml"
    "github.com/fsnotify/fsnotify"
    "github.com/gin-gonic/gin"
)

type Config struct {
    Name string
    Age  int
}

const File = "./config.toml"

var config Config

func main() {
    watchConfig(&config)
    r := gin.Default()
    r.GET("/config", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "name": config.Name,
            "age":  config.Age,
        })
    })
    r.Run()
}

func watchConfig(conf *Config) {
    reload(conf)
    go monitor(conf)
}

func reload(conf *Config) {
    _, err := toml.DecodeFile(File, &conf)
    if err != nil {
        panic(err)
    }
}

func monitor(conf *Config) {
    var err error
    watcher, _ := fsnotify.NewWatcher()
    defer watcher.Close()
    for {
        err = watcher.Add(File)
        if err != nil {
            panic(err)
        }
        select {
        case <-watcher.Events:
            reload(conf)
            if err != nil {
                panic(err)
            }
        }
    }
}
```

# 確認

サーバーをたちあげてリクエストしてみる

```
$ go run main.go
$ curl http://localhost:8080/config
{"age":20,"name":"fuku"}
``` 

config.tomlを修正して再度リクエスト

```:config.toml
name = "tarou"
age = 17
```

```
$ curl http://localhost:8080/config
{"age":17,"name":"tarou"}
``` 

webサーバーを再起動しなくとも内容が変更されている確認できた。

# まとめ

実際の運用でもプログラムの内容は変えずconfigだけを変更というケースは多いはず
そんな場合でもプロセスを止めずに変更を反映できるのは便利なので実施してましょう
Windows 7でlocalhost宛のパケットをキャプチャする

# Windows 7でlocalhost宛のパケットをキャプチャする

WindowsではWiresharkで自端末間のパケットをキャプチャしようとしてもできません。
やり方はたくさんありそうですが、RawCapを使うのが簡単そうです。

## RawCapを使う

[RawCap](http://www.netresec.com/?page=RawCap)をダウンロードします。インストール不要でそのまま実行できます。
コマンドプロンプトを管理者モードで実行し、RawCap.exeを実行して対象のインターフェースと保存先のファイル名を指定するだけです。

```
C:\Users\ADMIN\app\RawCap>RawCap.exe
Interfaces:
 0.     9.68.246.238    ワイヤレス ネットワーク接続     Wireless80211
 1.     169.254.139.141 ローカル エリア接続     Ethernet
 2.     192.168.33.1    VirtualBox Host-Only Network    Ethernet
 3.     127.0.0.1       Loopback Pseudo-Interface 1     Loopback
Select interface to sniff [default '0']: 3
Output path or filename [default 'dumpfile.pcap']: test.pcap
Sniffing IP : 127.0.0.1
File        : test.pcap
Packets     : 778
```

Ctrl+cでパケットキャプチャを終了します。保存したファイルはWiresharkで開いて見ることができます。

### IPv6の無効可

しかし、この方法では目的のパケットをキャプチャできませんでした。それはRawCapがIPv6に対応していないためでした。通常のアダプタは設定からIPv6を無効化することができますが、ループバックアダプターの設定は変更できないため、[IPv6全体を無効にする](https://support.microsoft.com/ja-jp/kb/929852)ことで、目的のパケットがキャプチャできました。無効化すると弊害もありそうなので、[IPv4を優先にする](http://www.vwnet.jp/Windows/w7/IPv4/IPv4PriorityUP.html)だけでもいいと思います。

## その他の方法

[WiresharkのWiki](https://wiki.wireshark.org/CaptureSetup/Loopback)によると、他にも以下の方法がありそうです。

* WinPcapの代わりにNpcapを使う
* Microsoft Loopback Adapterを使う
* ゲートウェイを通るようにルートを追加する
* [PowerShellからlocalhost宛のキャプチャができるように設定する](http://ig2600.blogspot.jp/2011/03/powershell-script-to-enable-windows-to.html)

## 参考にしたリンク

[Loopback capture setup](https://wiki.wireshark.org/CaptureSetup/Loopback)
[RawCap を用いてWireshark で自マシン間の通信を解析する方法](http://troushoo.blog.fc2.com/blog-entry-134.html)
macOS Sierra beta 上傳送審 App Store 的詭雷

自從作業系統升到 `macOS Sierra beta` 之後，上傳 binary 的時候一直碰到這個報錯：

> "No .app bundles found in the package"

看起來很詭異的問題，因為在上傳期間，他的確有顯示過他在打包 .app 檔案。

Error code 大概會是這樣：

```
ERROR ITMS-90167
```

或是其他的編號。

根據 - [這個討論串](http://stackoverflow.com/a/37931353) - 的討論，
基本上目前是無解，
看來是要等正式版出來，才會真正的穩定。

認真講解法的話

- 用 Xcode 7.* 開發，用 Xcode 8 beta build
- 但是這個 workaround 似乎只能對 TestFlight 有用，無法用在 App Store 提交

恩 ... 所以基本上還是無解。

該篇有提到有出現過的問題有：

- beta OS 的 tool chain 有問題
- 你用了非正式版本的 Xcode, SDK 等等、或是你用了 beta OS 來 build

還是等正式版出來唄 :laughing: 
到時候應該就不會有這個問題了。
Terraformを 0.6 から 0.7 にバージョンアップしたら dot indexing が使えなくなっていた

> 参考

- issue: [Terraform plan panic #7103](https://github.com/hashicorp/terraform/issues/7103)
- document [INPUT VARIABLES](https://www.terraform.io/intro/getting-started/variables.html)



variables.tf

```
variable "vpc" {
    default = {
        cidr_block = "10.30.0.0/16"
    }
}
```

### before

```
resource "aws_vpc" "main" {
    cidr_block           = "${var.vpc.cidr_block}"
}
```

### after

```
resource "aws_vpc" "main" {
    cidr_block           = "${lookup(var.vpc, "cidr_block")}"
}
```

こんな感じで書き直してた。みんな知ってた？
Sublime Text 3 + Clang-Complete インクルードパスの指定でプロジェクトルートからの相対パスを使う

Sublime Text 3 で C/C++ 開発するときにコード補完してくれるプラグインとして [Clang-Complete](https://github.com/lvzixun/Clang-Complete) があります。

このプラグインは`<name>.sublime-project`ファイルの`cc_include_options`を適切に設定することで、ヘッダファイルのインクルードパスも指定できます。しかし、Clang-Complete の README には次のように絶対パスで指定する例しか書いてありません。

```
"settings":
{
    "cc_include_options":
    [
        "-I/headfile_path1",
        "-I/headfile_path2",
        "-I/headfile_path3"
        // ...
    ]
     // ...
}
```
絶対パスで指定しなければ相対パスにはなるのですが、各ソースファイルからの相対パスになってしまいます。

これをプロジェクトのルートからの相対パスで設定するには、`${project_path}`変数を使います。

```
"settings":
{
    "cc_include_options":
    [
        "-I${project_path}/headfile_path1",
        "-I${project_path}/headfile_path2",
        "-I${project_path}/headfile_path3"
        // ...
    ]
     // ...
}
```
Sublime Text 3 の設定に詳しい人なら当たり前かもしれませんが、備忘録として。