OmniAICreator/Qiita-1.07M huggingface dataset:
UnityでGameObjectの作成とコンポーネントの生成

ここでは、Unityで作成したアプリにc#のコンポーネントを追加する方法を紹介する（新規シーンの作成方法は省略）。

## **0. Unityの開発画面の説明** ##
Unityを起動し、任意のシーンを開くと、次のような開発画面が表示される。
![3820969610-wiki_unity_1.png](https://qiita-image-store.s3.amazonaws.com/0/132683/330b0293-0071-dfbb-35c5-df9555ee1695.png)
（画面中央のSceneビューに写っているハル(http://sites.cybernoids.jp/cubism2/samples) は気にしないでほしい。）開発画面の仕様は以下の通り。

* Sceneビュー：GameObjectを選択し配置する際に使用する。
* Gameビュー：最終的に出力しようとしているゲーム画面。画面中央の「▶」(再生)ボタンとクリックすると、自動的にGameビューが表示される。
* Hierarchyウインドウ：GameObjectを作成し登録する。
* Inspectorウインドウ：選択したGameObjectに登録しているコンポーネント（ソースコードや、音声ファイル、各種イベントなど）が表示される。
* Projectウインドウ：現在開いているシーンのフォルダ構成を表示する。
* Consoleウインドウ：画面中央部の「▶」(再生)ボタンを押下した際に、ログの内容を確認できる。
* Editor Testsウインドウ：作成したユニットテストの実行結果が表示される。

## **1. GameObjectの作成** ##
Unityの開発画面のHierarchyウインドウにて右クリック→「Create Empty」から、新規GameObjectを作成する。作成したGameObjectに任意の名前を付ける。

## **2. Componentの追加** ##
先ほど作成したGameObjectを左クリックで選択すると、GameObjectに対応したInspectorウインドウが表示される。以下では、C#のテンプレートの作成方法を紹介する。
Inspectorウインドウの「Add Component」ボタンをクリックし、「New Script」を選択、任意のNameとLanguage（本記事ではC Sharpを選択）を入力し、「Create and Add」ボタンをクリックする。
![2620674009-wiki_unity_2.png](https://qiita-image-store.s3.amazonaws.com/0/132683/3df68fe8-5fd7-3545-8afd-789596fa7568.png)

![1159073369-wiki_unity_3.png](https://qiita-image-store.s3.amazonaws.com/0/132683/b11a9de1-f186-34c2-eee1-04e11a98f39e.png)
すると、C#のテンプレートが作成される。  
**補足：**プロジェクトに格納されている既存のソースコードや音声ファイルなどをコンポーネントとして追加することもできる。  
Inspectorウインドウの「Add Component」ボタンをクリックした後、追加したいファイルを追加したい場合は「Scripts」をクリックし該当のC#を選択する。音声ファイルを追加したい場合は「Audio」→「Audio Source」をクリックし、空の「Audio Source」コンポーネントの「Audio Clip」に該当のファイルをD&Dする。

## **3. C#の記述方法** ##
先ほど生成したC#をVisual Studioで開く（UnityのProjectウインドウから該当のC#ファイルをダブルクリックすることで開くこともできる）。
すると、下記のようなテンプレートが生成されていることを確認できる。

```csharp
public class NewBehaviourScript : MonoBehaviour {
	void Start () {
	}
	
	void Update () {	
	}
}
```

**MonoBehaviour**とは、このクラスがMonoBehaviourからの派生であることを示している。Unityで扱うオブジェクトは全て、MonoBehaviourから自動的に派生するようにUnityエディタが作り出す。MonoBehaviourは、Unityで作られるゲーム中で出てくる物体などの動作のきっかけ(イベント)で動かす処理のかたまり（メソッド）等をつなぐ役割をしている。
（参考：http://docs.unity3d.com/jp/current/ScriptReference/MonoBehaviour.html）

**Start ()**メソッドには、Unityで作成したアプリが起動されたときに実行する初期化処理を記述する。つまり、Start ()は一度しか実行されない。

**Update ()**メソッドには、Unityアプリ実行中の毎フレームで実行したい処理を記述する。アプリを終了しない限り、Update ()は何度も実行される。

**補足：**MonoBehaviourからの派生クラスとして記載された各C#のStart ()やUpdate ()は、Unityアプリが実行時に、ひとまとまりのStart ()やひとまとまりのUpdate ()のように実行される。つまり、他のコンポーネントを意識せず、各コンポーネントにてそこで実装したい処理を記述することができる。
MESHでJavaScriptを扱う

ここでは、MESH (http://meshprj.com/jp/) の任意のセンサータグから、JavaScriptで処理を実装した自作のタグを起動する方法を紹介する。

# **MESH SDKの登録** #
MESH SDK (https://meshprj.com/signin/) のサイトにアクセスし、アカウントを作成する。

# **カスタムタグの作成** #
MESH SDKにログインし、「Create New Tag」から新しいカスタムタグを作成する。
新しく作成したカスタムの「Edit」から、タグの名前や詳細などの情報を記述できる。

![mesh_wiki_1.png](https://qiita-image-store.s3.amazonaws.com/0/132683/7c439781-2835-ea1d-579b-3a060e339dbe.png)

### **タグの機能の追加** ###
「Edit」画面から、タグの機能を実装できる。
先ほど名前を付けたFunction（デフォルトではNew Function）の左側の「▶」をクリックし、機能を実装していく。
以下に、図を用いて実装の詳細を説明する。

![mesh_wiki_2.png](https://qiita-image-store.s3.amazonaws.com/0/132683/74f52f5b-379b-e33e-bb3f-62b6543a524d.png)

詳細は、 https://meshprj.com/sdk/doc/ を参照のこと。

### **JavaScriptの記述** ###
今回は、iPadの「MESH」アプリに表示される「Log」画面に「こんにちは！」が表示されるだけのコードを実装する。
「Edit」の「Fuction」の「Execute」にて、以下のコードを追加する。

```js
log(" こんにちは！ ");

return {
    resultType : "continue"
};
```

![mesh_wiki_3.png](https://qiita-image-store.s3.amazonaws.com/0/132683/c6ba0158-6a95-829b-3a45-d14b8ff072c5.png)

（returnのresultType : "continue"とは、タグが実行された後に次のタグに自動的に遷移するための値設定であり、
MESH SDK固有のものである。
その他の値として、"stop"や"pause"がある。詳細は、 https://meshprj.com/sdk/doc/ を参照のこと。）

# **タグの動作確認** #
以下に、作成したタグをiPadの「MESH」アプリに取り込む方法を紹介する。
任意のレシピを開き、画面右上の設定から、「SDK」をタップし、先ほどカスタムタグを作成したMESH SDKのアカウントにてログインする。
レシピの右ペイン下方に表示されている「Custom」の「＋」をタップすると、先ほど作成したタグが表示されるので、タップしてダウンロードを行う。
ダウンロードできたタグのインプットと任意のセンサーのアウトプットを繋ぐ。
「Custom」の「Log」をタップし、ログ画面を表示させている状態でセンサーを反応させると、「こんにちは！」の文字列が表示される。
一度でも偽になるとその後代入不可能になるプロパティ

Rubyでは`||=`が出来るので、当然`&&=`も出来るよね
と言うことで実験してみました。

```ruby
class Hoge
  def initialize
    @a = 0
  end

  def a=(i)
    @a &&= i
  end

  def a
    @a
  end
end
```

で、

```ruby
num = Hoge.new

num.a = 1
p num.a
#=> 1

num.a = 2
p num.a
#=> 2

num.a = nil
p num.a
#=> nil

num.a = 3
p num.a
#=> nil
```

これだけだとちょっと用途が思いつきませんが、代入メソッドの中にバリデーションのロジックなんかを仕込むと使い道があるかも。
アポロ11号の管制プログラム

47年前に初めて月面着陸した[アポロ11号](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%9D%E3%83%AD11%E5%8F%B7)の[管制プログラム](https://github.com/chrislgarry/Apollo-11)の話題を見つけた

1. 月で動いていたコードが眺められる
2. [MIT 博物館にあったハードコピー](http://www.ibiblio.org/apollo/ScansForConversion/Luminary099/)から復元されたもの
3. アポロで使われたプログラムを[再現してる人たちがいる](http://www.ibiblio.org/apollo/)
4. [yaYUL](http://www.ibiblio.org/apollo/yaYUL.html) でアセンブルできるらしい
    1. 元々は YUL と言うアセンブラを使っていたが、もう誰も持ってないらしい

面白いファイル名が混じってるよ...

1. [BURN_BABY_BURN--MASTER_IGNITION_ROUTINE.s](https://github.com/chrislgarry/Apollo-11/blob/master/BURN_BABY_BURN--MASTER_IGNITION_ROUTINE.s)
    1. [本当に使われてる名前だった](http://www.ibiblio.org/apollo/ScansForConversion/Luminary099/0731.jpg)
2. [PINBALL_GAME_BUTTONS_AND_LIGHTS.s](https://github.com/chrislgarry/Apollo-11/blob/master/PINBALL_GAME_BUTTONS_AND_LIGHTS.s)
Zybo > Link > ZYBO_Master.xdc / ug903-vivado-using-constraints.pdf

ZYBO用のXDCファイル
https://github.com/Digilent/ZYBO/blob/master/Resources/XDC/ZYBO_Master.xdc

~~こちらからはzip形式が取得できる。~~
~~https://reference.digilentinc.com/zybo:zybo~~
(追記 2016/07/09 ページ構成が変わって取れなくなった。githubから取れということだろうか。)

XDCの記載内容の理解については
[ug903-vivado-using-constraints.pdf](http://www.xilinx.com/support/documentation/sw_manuals/xilinx2012_2/ug903-vivado-using-constraints.pdf)
Zybo > PL Interface Comparison Summary > AXI_HP / AXI_ACP / AXI_GP

@ ug585-Zynq-7000-TRM.pdf
p642
22.4.2 PL Interface Comparison Summary

AXIにはAXI_HP, AXI_ACP, AXI_GPの3つがあるようだ。

Table 22-8に比較されている。そのうちのBenefitsは以下

- PL AXI_HP DMA
  - Highest Throughput
  - Multiple Interfaces
  - Command/Data FIFOs
- PL AXI_ACP DMA
  - Highest Throughput
  - Lowest Latency
  - Optional Cache
  - Coherency
- PL AXI_GP DMA
  - Medium Throughput

Benefits以外の項目としてDrawbacks, Suggested Users, Estimated Thoughputなどが記載されている。

上記を使い分けるのはまだまだ先の話になりそう。
Nefryでデジタル出力を試す！

Nefryでデジタル出力をためしてみましょう！

D2ピンをSWボタンを押した時にHIGHになるプログラムです。


```c++:Nefry.ino
#include <Nefry.h>

void setup() {
  pinMode(D2, OUTPUT); //D2のピンのデータを出力モードにします。
}
void loop() {
 if(Nefry.push_SW()==HIGH){
  //NefryのSWボタンが押されたとき
  Nefry.println("PushSW!");
  Nefry.setLed(255,0,0);
  digitalWrite(D2,HIGH);
 }else{
  //NefryのSWボタンを押していないとき
  digitalWrite(D2,LOW);
  Nefry.setLed(0,0,255);
 }
 Nefry.ndelay(250);
}
ややこしいCSS3プロパティのメモ

# 個人的に書くときよく迷うCSS名

* transition
* transform
* translate

アニメーションさせるのどれだっけ？
〜(100%, 0)とか付けて位置制御するのどれだっけ？

ああああああああ
この3つがごちゃごちゃするので私的に整理しておく

## transition

http://ejje.weblio.jp/content/transition

> 移り変わり、移行、変遷、変化、過渡期、変遷期、変わり目

変化を生むもの、つまりこれがアニメーションさせるやつ。[trans-i-tion]

```css
transition:background-color 1s linear 0 , width 1s linear 0 , height 1s linear 0;
```

## transform

http://ejje.weblio.jp/content/transform

> (…に)一変させる、変形させる、(すっかり)変える、変換する、変圧する、(…を)変換する、変形する

変形させるもの、つまりそのまま変形させるやつ[trans-form]

```css
transform:rotate(-7deg);
```

## translate

http://ejje.weblio.jp/content/translate

> (…へ)訳す、翻訳する、(…と)解釈する、説明する、(…を)移す、直す、(…に)転任させる

翻訳する、つまり入力値を座標へ翻訳させるやつ[trans-late]

```css
transform:translate(100px, 0);
```


---

雑記

* `transform:translate〜`　は特にややこしい…

* transの語彙については、元化学側だった人種としては
https://ja.wikipedia.org/wiki/トランス_(化学)
が思い当たるけど違うかも。
Linuxコマンドを連続して使うには


どうも、江川(egawa)くんです。

Linuxでシェルスクリプトなどを書いていると以下のような条件に遭遇することがあるので、
備忘録的に残していきたいと、おっもいま〜す。

- 複数のコマンド実行を一行で記述したい
- あるコマンドが問題なく実行された場合のみ、次のコマンドを実行したい
- あるコマンドが失敗したら、次のコマンドを実行したい
<br />

## 更新情報
- 2016/7/8 新規作成
- 2016/7/8 レイアウトなど見やすく修正
- 2016/8/18 テキストを一部修正
<br />

## 種類
ここで出てくるのは以下のみです。
- `;` （セミコロン）
- `&`（アンパサント）
- `&&`（アンパサントアンパサント）
- `|`（パイプ）
- `||`（パイプパイプ）
<br />

## 使用例

### コマンド1が終了したらコマンド2を実行する（実行結果に関わらず）
コマンド1が異常終了しても、コマンド2は実行されます
使い方

```
コマンド1 ; コマンド2　
```
使用例1.　5分後に`date`コマンドを実行する(普段使わないので、いい例が思いつきませんww)

```
# sleep 5m ; date
```
<br />
### コマンド1を実行しつつコマンド2も実行する
バックグラウンドでコマンド1を実行しつつ、コマンド2も実行できます
使い方

```
コマンド1 & コマンド2
```

使用例1.　`/home/egawa/egawa.sh`を実行しログを出力しつつ、`vi`で`egawa.txt`を編集する

```
# sh /home/egawa/egawa.sh >> /var/log/egawa.log & vi /home/egawa/egawa.txt
``` 
<br />
### コマンド1が正常終了したらコマンド2を実行する
コマンド1が正常終了したときのみ、コマンド2が実行されます
使い方

```
コマンド1 && コマンド2
```

使用例1.　`/home/egawa`にディレクトリ移動ができたら、`egawa.txt`を作成する

```
# cd /home/egawa/ && touch egawa.txt
```  
使用例2.　ダウンロードしてきた`tar.gz`を解凍後、ディレクトリへ移動

```
# tar zxf xxx-2.x.tar.gz && cd xxx-2.x
```
使用例3. 何かのパッケージをソースからインストールする

```
# ./configure && make && make install
```

<br />
### コマンド1の結果をコマンド2に渡して実行
コマンド1の結果をコマンド2へ渡して結果を出力します
使い方

```
コマンド1 | コマンド2
```
使用例1.　`ps aux`で実行中のプロセスを出力し（ターミナルには出力されない）、その中からキーワード`httpd`にマッチする行を出力する

```
# ps aux | grep httpd
```  
<br />
### コマンド1が異常終了したらコマンド2が実行される
コマンド1が異常終了したときのみ、コマンド2が実行されます
使い方

```
コマンド1 || コマンド2
```

使用例1.　`/home/egawa/abc`にディレクトリ移動ができなかったら、`/home/egawa/abc`ディレクトリを作成する
（使用例だと、ディレクトリがなかった場合エラーが出力されるが、その結果としてディレクトリが作成される）

```
# cd /home/egawa/abc || mkdir /home/egawa/abc
```
<br />
license > Link > Visual Studio 2015 > MSDNのボリュームライセンス価格比較

Visual Studio 2015 Professional + MSDNに関して、以下に詳細な情報が記載されている。
http://tmori3y2.hatenablog.com/entry/2016/02/28/235459

個人契約の観点で調べられているようだ。
企業で購入する場合は違う点も出てくるかもしれないが、参考になる。

Open Value, Open Licenseなどの選択についてはまだ未消化。

[ライセンスまるごと早わかりガイド @ Microsoft](
https://www.microsoft.com/ja-jp/Licensing/licensing-programs/LicenseQuickStartGuide)から入手できるPDFファイルによるとOpen Value, Open Licenseともに「3ライセンスから購入可能」とのこと。
Redisの利用メモリが最大メモリ超えた時の挙動

## 背景
最近ElasticCacheのRedisを利用して、メモリ使用量が常に高い状態になって、メモリ増加した.
その後、メモリ利用量もアイテム数もずっと増え続きしてた

##　調査
メモリ増加前にメモリ利用量がピックになって、アイテム数がずっと同じ数値でした。

おかしいので、仮説としてRedis利用メモリがMAXメモリ超えた時点で、アイテムがredisから削除されたではないか

[REDIS を LRU キャッシュとして使う](http://redis-documentasion-japanese.readthedocs.io/ja/latest/topics/lru-cache.html)
こちらを見ると、volatile-lruの場合はexpireが設定されてるアイテムなら、期限切れるかどうかと関係なく利用頻度が少ないアイテムから削除

ローカルで検証してみる

### 前準備
1. こちらを参考にredisインストール[MacにRedisをインストールして使ってみる](http://qiita.com/TakashiOshikawa/items/83d3b59b4835eb9ba63e)

```
$ brew install redis 
```

### メモリサイズを2MBにして、maxmemory-policyをvolatile-lruにする
#### 期限付きがないアイテムを追加して、最大メモリ超えると、エラーになる

1. 設定変更 /usr/local/etc/redis.conf
  * maxmemory 2MB
  * maxmemory-policy volatile-lru
1. 再起動
    ```
    brew services restart redis
    ```
1. 有効期限設定しないで10000個アイテムセット
 
```ruby
(1..10000).each do |i|
   Redis.current.set(SecureRandom.uuid, '1111111111111111111111111111111111')
end
   ```
エラーで落ちる
```
Redis::CommandError: OOM command not allowed when used memory > 'maxmemory'.
```

redis-cliで追加されるアイテム数確認
```
dbsize
```
1570個追加できた

#### 期限付きのアイテムを追加して、最大メモリ超えると、後で回収される
 * 1000個の有効期限付きで追加

```rb
time = 3.months.seconds
(1..1000).each do |i|
   id = SecureRandom.uuid
   Redis.current.set(id, '1111111111111111111111111111111111')
   Redis.current.expire(id, time)
end
```
dbsizeで確認、0個、メモリ使いすぎて、削除された？

 * 100個を追加
  * 正常に追加できた

 * 300個を追加
  * 正常に追加できた
  * 1分ぐらい待つと、207個になってる
  * 5分ぐらい待つと、14個
  * 回収アルゴリズムがよくわからん

 * 500個を追加
  * 正常に追加できたが、1分後に0個になった、回収された

## 結論
 * volatile-lruの場合はexpireが設定されてるアイテムなら、期限切れるかどうかと関係なく利用頻度が少ないアイテムから削除、削除アルゴリズムがよくわかってない
 * 全部expireが設定されてるアイテムだったら、メモリが少なくなって、redisが落ちることがないが、正確な有効期限までじゃなくても、削除される
Nefryでデジタル入力を試す！

今回はD2ピンで入力を試してみます。

D2ピンはNefryのGrove端子に繋がっており、Groveで試すことも可能です！


```c++:Nefry.ino
#include <Nefry.h>

void setup() {
  pinMode(D2, INPUT); //D2のピンのデータを入力モードにします。
}
void loop() {
  int pinState;
  pinState = digitalRead(D2);
  if (pinState == HIGH) {
    Nefry.setLed(255, 0, 0); //LEDが赤色に光ります
    Nefry.println("HIGH");
  } else if (pinState == LOW) {
    Nefry.setLed(0, 0, 255); //LEDが青色に光ります
    Nefry.println("LOW");
  }
  Nefry.ndelay(250);
}
```
Onsen Theme Rollerで作成したThemeをMonacaで作成したアプリに取り込む方法。

#下記をみて、Themeを作成していましたが、Monacaで適用する方法が、かかれていなかったので、まとめておきました。
1. [Onsen UIをカスタマイズするOnsen Theme Rollerの紹介](http://blog.asial.co.jp/1355)をみて、Themeを作成。作成したThemeをダウンロード
2. ダウンロードした、onsen-css-components.cssをonsen-css-components-cus.cssにリネーム。
3. lib/onsenui/css配下にリネームしたファイルをアップロード。（componentsの方にonsenuiのフォルダがある場合もあるが、そちらは無視）


![スクリーンショット 2016-07-08 11.28.19.png](https://qiita-image-store.s3.amazonaws.com/0/132925/61b54562-f833-c6e6-9860-6b4551964fd5.png)

4.index.htmlを書き換える。

```html:index.html
    <link rel="stylesheet" href="components/loader.css">
    <link rel="stylesheet" href="lib/onsenui/css/onsenui.css">
    <link rel="stylesheet" href="lib/onsenui/css/onsen-css-components.css">　→書き換え
    <link rel="stylesheet" href="css/style.css">
```

書き換え後

```html:index.html
    <link rel="stylesheet" href="components/loader.css">
    <link rel="stylesheet" href="lib/onsenui/css/onsenui.css">
    <link rel="stylesheet" href="lib/onsenui/css/onsen-css-components-cus.css">
    <link rel="stylesheet" href="css/style.css">
```
jquery.getScriptはどうやってスクリプトファイルを実行しているのか

## jQuery.getScript()とは？
指定のスクリプトファイルを非同期で読み込んで，さらにそのスクリプトを実行するコマンド．
`$.getScript('//.../foo.js', callback)`


## 疑問
スクリプトの読み込みは$.ajax()を使っているとして，スクリプトをどのように実行しているのか？DOMツリーに `<script src="...">` 要素を追加すればブラウザがスクリプトを実行してくれるが，$.getScript実行後のDOMを確認しても追加されているように見えない．


## 答え
`<script>`をDOMに追加して**即座に削除**している．

```javascript:jquery/2.2.4/jquery.js
L335: script = document.createElement( "script" );
L336: script.text = code;
L337: document.head.appendChild( script ).parentNode.removeChild( script );
```
MacBookを使うシステム管理者なら手元に１つは置いておきたいCentOS7デスクトップ用のVagrantfile

MacBookを使うシステム管理者として時々困ることは、WindowsとLinux(Redhat系)しかサポートしていないGUIアプリケーションを使わなければならなくなった時です。そんな機会は稀ですが、そういうニーズが本当にたまにあります。そんな時のためのVagrantfileがこちら。

## Vagrantfile

```ruby
# -*- mode: ruby -*-
# vi: set ft=ruby :

$script = <<SCRIPT

yum -y groupinstall "GNOME Desktop"
systemctl set-default graphical.target
systemctl start graphical.target

SCRIPT

Vagrant.configure(2) do |config|
  config.vm.box = "bento/centos-7.2"

  config.vm.provider "virtualbox" do |v|
    v.memory = "2048"
    v.gui = true
    v.customize ["modifyvm", :id, '--audio', 'coreaudio', '--audiocontroller', 'ac97']
    v.customize ["modifyvm", :id, '--vram', '256']
  end

  config.vm.provision "shell", inline: $script

end
```

ユーザとパスワードはどちらもvagrantです。デスクトップ環境のインストールが済んだ後はライセンスに同意する手順を踏まなければなりませんが、GUIなので`next`、`next`で簡単に済みます。

## カーネルアップデート後のVirtualBox Guest Additionsについて

初回の`yum update`にはカーネルのアップデートがつきものですが、カーネルのバージョンが変わるとVirtualBox Guest Additionsが使えなくなってしまいます。そうなるとデスクトップのウィンドウサイズの調節が出来なくなってしまうので、そんな時は[vagrant-vbguest](https://github.com/dotless-de/vagrant-vbguest)を使うか、もしくは`vagrant ssh`でVMにログインして下記のスクリプトを実行すると大丈夫です。

```
#!/bin/bash

set -e

yum -y install gcc kernel-devel
wget http://download.virtualbox.org/virtualbox/5.1.0_RC1/VBoxGuestAdditions_5.1.0_RC1.iso
sudo mount VBoxGuestAdditions_5.1.0_RC1.iso /mnt -o loop
sudo /mnt/VBoxLinuxAdditions.run
sudo umount /mnt
rm VBoxGuestAdditions_5.1.0_RC1.iso
sudo yum clean all
sudo reboot
```

## イメージを保存する

イメージのアップデートが完了したらそのイメージをローカルに保存することをお勧めします。そうしておけば`vagrant destroy`後にまたイチからイメージを作り直す必要がなくなります。

```
## Step 1. ひとまずsshキーをデフォルトに戻します。こうしておくと新規に
## vagrant upした時にVagrantが新しい鍵でリセットしてくれます。
$ vagrant ssh
$ wget https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub -N -O .ssh/authorized_keys
$ exit

## Step 2. ローカルのvagrant boxとして保存します。
$ VBoxManage list vms
$ vagrant package --base <イメージのフルネーム> --output /tmp/centos-7-desktop.box
$ vagrant destroy
$ vagrant box add centos-7-desktop /tmp/centos-7-desktop.box
$ rm /tmp/centos-7-desktop.box
```

> **NOTE:** Step 1でsshキーをデフォルトに戻しておかないと、新しいboxで作ったVMに`vagrant ssh`できなくなります。

## ローカルに保存した後のVagrantfile

アップデート後のイメージを`vagrant box`として保存した後は下記のVagrantfileで気軽にCentOS 7のデスクトップイメージを立ち上げることができます。

```
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|
  config.vm.box = "centos-7-desktop"

  config.vm.provider "virtualbox" do |v|
    v.memory = "2048"
    v.gui = true
    v.customize ["modifyvm", :id, '--audio', 'coreaudio', '--audiocontroller', 'ac97']
    v.customize ["modifyvm", :id, '--vram', '256']
  end

end
```

こういうイメージが手元にあると、ときどき便利です。
仕様書をMarkdownで書く時に、Atomエディタを使ってみた

# 理由
[「集中できる開発スタイルを目指して」](http://qiita.com/daijinload/items/a37364970f6d6f699bbc)で、書いたのですが、仕様書をmarkdownでコミットするようになって、リアルタイムで表示を確認したいと思ったため、使い始めました。

# 良い所
何も入れずに、デフォルトでマークダウンがプレビュー出来ます。
カスタマイズしなくて良いのは、本当に良いですね＾＾
レスポンスも遅いと言われている割に、個人的には余裕で許容範囲だと思います。

# 悪いところ
フォントの設定をしても、プレビューに反映されません。そちらは別途設定する必要がありました。

[AtomでカッコよくMarkdown PreviewするためのCSS](http://tanksuzuki.com/post/atom-markdown-style/)

# 小ネタ
Ctrl + Shift + Mで、今開いているファイルのマークダウンプレビュー出来ます。

# まとめ
Markdownのためだけに、Atomを使うのはありだと思います。
エディタ戦争とかありますが、全部１個で担うのではなく、要所要所で
最適なものを使っていけば良いのでは無いかと思います。

ちなみに、エディタですが、
* サクラエディタ（ファイルの文字コード確認＆とりあえず中身見るとき）
* SublimeText3（ソースコード開くときなど）
* Atom Editor（Markdown編集）
* Vim（サーバでの修正や、git操作中にちょっと修正したい時）
* Netbeans（PHPとNode.js開発で使ってます）

を使ってます。それぞれ役割が違いますが、使っていて良い感じです＾＾
使いすぎやないかい！！とか、ツッコミたくなりますかね？＾＾
MySQLでパッとcsv形式ダンプ(データの差分取りたい)

データベースにあるテーブルを一括でダンプ
差分取るのにCSV形式にしたいお。

```
mysqldump -u [ユーザー名] --tab=/tmp/dump --fields-terminated-by=, --fields-optionally-enclosed-by=\" --lines-terminated-by="\r\n" -t [データベース名]
```

パスワードは省略。
`--tab`で保存先を設定
`--fields-terminated-by`で区切り文字を設定
`--fields-optionally-enclosed-by`はLOAD DATA INFILE？(よくわかってない)
`--lines-terminated-by`はLOAD DATA INFILE？(よくわかってない)

これをやるとデータベースにあるテーブルに対して、`.sql`ファイルと`.txt`ファイルができるので、それで。

繋げたい場合は

```
more [txtファイル] … > [保存したいファイル名]
```

ファイル名が不要な場合は`more`じゃなく`cat`でもOK。
ファイル名多くて死にそうだったから`ls`コマンド(`ls *.txt`)してそれをTeraPadあたりに貼って整形して使った。

p(｀・ω・´)q＜あとはテキストファイルだからWinMergeあたり使えば差分が取れる
Emacs Lispの正規表現において[]の中で[]を使用したい時にちょっと困った

正規表現における[]では，[]の中に記述した文字の中から一つでも該当するものがあればマッチします．
例えば`[abc]`であれば，aかbかcのいずれかにマッチします．
ここで，`[`または`]`をマッチしたい時に少し困りました．

# ダメなパターン
1. `[\[\]]`
`[`をエスケープしてしまえばいいのでは？と思ったのですがダメでした．
  
2. `[[]]`
エスケープしなければいいのでは？と思ったのですがだめでした．

# 正解
**`[][]`**

は？って感じ．
Emacs Lispでは`[]`内で]をマッチさせたいときには，`[`の直後に置くようです．
従って，]だけが必要であれば，`[]]`が正しいパターンとなります．
よって今回の例では，`[][]`が正解です．うーん...
erutasoをmacにインストールして使えるようにする

# erutaso
[これ](https://github.com/sgymtic/sl)です。
![スクリーンショット 2016-07-08 10.16.36.png](https://qiita-image-store.s3.amazonaws.com/0/40264/0f409a80-e6cd-034d-8c17-c1c5f6a1b98c.png)


## やること
1. githubからクローンしてくる
2. コンパイル(ビルド)する
3. 適切なディレクトリにコピーする
4. 実行する

## 具体的な手順
適当なディレクトリで

```sh
git clone https://github.com/sgymtic/sl.git #githubからクローン
cd sl #クローンしたディレクトリに移動
make #コンパイル等の処理
cp erutaso /usr/local/bin #実行可能な生成物をパスの通ったディレクトリに配置
cd ../ #クローンしたディレクトリを抜ける
rm -r sl #不要ファイルのお掃除
erutaso #実行
```

## 要らなくなったら
```sh
rm /usr/local/bin/erutaso
```
で配置した`erutaso`を削除

## 参考
http://qiita.com/opengl-8080/items/08fdfd0f6dc65b5a53ad
bootstrapモーダルダイアログ上にinput-groupを配置すると、jQuery UI datepickerがz-indexの計算を間違える

jQuery UI便利ですか？便利ですね！！
bootstrap便利ですか？便利ですね！！
（導入）

# 前提

## bootstrapのinput-group

bootstrapにinput-groupという機能があります。
http://getbootstrap.com/components/#input-groups
フォーム部品の前後に、アイコンや文字をきれいに付ける機能です。

## bootstrapのmodal

bootstrapにmodalという機能があります。
http://getbootstrap.com/javascript/#modals
ページ上にきれいなウィンドウを表示する機能です。

## jquery uiのdatepicker

jQuery UIにdatepickerという機能があります。
http://jqueryui.com/datepicker/
テキストボックスにカレンダーを付ける機能です。


# 問題

modal上に配置したフォーム部品にinput-groupを付けると、datepickerがz-indexの計算を間違えてしまい、datepikerがmodalの後ろに隠れてしまいます。

![datepicker1.PNG](https://qiita-image-store.s3.amazonaws.com/0/59475/eb22ce80-fb4b-1799-4fbb-583144ab0727.png)

ソースはこんなんです。

```html:zindex-issue.html
<div id="mydialog" class="modal fade" role="dialog">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
      </div>
      <div class="modal-body">
        <form>
          <div class="form-group">
            <label>This is a datepicker with input-group on modal</label>
            <div class="input-group">
              <span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
              <input type="text" class="datepicker form-control">
           </div>
          </div>
        </form>
      </div>
    </div>
  </div>
</div>
```



ほんとはこのようになるはずなのです。

![datepicker2.PNG](https://qiita-image-store.s3.amazonaws.com/0/59475/f15d7dce-2a6c-9d82-91e9-cd5b3e1d1bb9.png)

こちらで問題を再現できます。
https://jsfiddle.net/5da9pjw1/16/



# 解決策！？

モーダル上の.input-group .form-controlのz-indexをmodalより大きい数字にしてあげれば大丈夫？

```css:fix-bootstrap-zindex-issue.css
.modal .input-group .form-control { z-index:1060; }
```

解決策追加後はこちら。
https://jsfiddle.net/5da9pjw1/17/
Sublime Text3でタイプライタースクロール

# タイプライタースクロール(2016.07.08の話)
少し長文を入力する際は、Scrivenerを使って快適に作業しているのだけど、そこまで長くない文を作成する時に、タイプライタースクロールできるものを探してた。

UlysessでもできるようだけどそうなるとScrivenerとスコープが被るのでCotEditorかSublime Textで調査。

Sublime Textならアドオンが在るのでテスト。

試用してみたのはこれ

* [Typewriter Ver0.4](https://packagecontrol.io/packages/Typewriter)

## インストール
Package Control : Install Package から "Typewriter"を選択して入れるか、[ここ](https://github.com/alehandrof/Typewriter/releases/)から最新版をダウンロードしてローカルで解凍し、Sublime Textのメニューにから「Browse Packages]を探して表示し、そのフォルダに回答したフォルダごとコピーする

## 利用方法
ALT + CTL + Pでコントロール画面を開いて「Typewriter」の入力で切り替え候補が表示される。候補は以下の3種類

* TypeWriter All Mode (Toggle)
* TypeWriter Scroll Mode (Toggle)
* TypeWriter Typing Mode (Toggle)

各モードのオンオフは同じモードを選択することで切り替わる模様。

いわゆるタイプライタースクロール（画面の中央付近でスクロールが停止して入力できる状態）にするには「Scroll Mode」を選択しておけばよい。

スクロールがちょっとガクガクすることがあるが、中央にカーソルが固定で入力できるのは快適。当面試してみることにする。
react-router + 静的ファイル(css, js) の組み合わせの罠

## 状況
react-routerにて[URL Params](https://github.com/reactjs/react-router-tutorial/tree/master/lessons/06-params)を使って動的にページ制御しようとしたところ、該当のURIをサーバーにリクエストした結果をロードしても、**reactで描画すべきコンテンツが空になってしまった**。

## 問題点と原因
初期表示用のHTMLファイル(index.html)に記述した**静的ファイル（css, js)の参照URLが存在しない場所を指していて**、SPAとしての機能が働かなかった。これが直接的な問題。

その原因は、次のようにreact-routerのルーティング設定をし、かつ静的ファイルを相対パスで指定したことで、返されたHTMLファイル内の静的ファイル参照先をブラウザが解決する際に矛盾を発生させていたからだった。

> react-routerは悪くない。アプリケーションの設定方法に誤りがあった。

```html:bundle.jsの記述抜粋
  <Route path="/" component={AppLayout} >
    <IndexRoute component={Top} />
    <Route path="blog" component={Blog}>
      <Route path=":id" component={BlogPost} /> <!-- www.domain.jp/blog/123 となることを想定　 -->
    </Route>
    <Route path="aboutus" component={AboutUs} />
    ...
  </Route>

```

```html:index.htmlの記述抜粋
<!-- いずれも参照先は相対パス指定 -->
<link href="css/animate.css" rel="stylesheet">
<script src="build/bundle.js"></script>
```

例えば`www.domain.jp/blog/123`に対してリクエストを送ると、ブラウザは上記の静的ファイルを取ろうとして、`www.domain.jp/blog/css/animate.css`を参照してしまう。`bundle.js`も然り。それらのファイルは存在しないのでロードできず、`react`は動かない。

<img width="656" alt="error.png" src="https://qiita-image-store.s3.amazonaws.com/0/37895/2e63af02-1697-6969-164a-ad20a7734007.png">


## 詳細な問題分析
`react-router`は[`History API`](http://diveintohtml5.info/detect.html#history)を使っている、という点に着目すると、実装時に注意しなくてはならない点が見えてきた。

そもそも、`History API`の`pushState`関数により、より自然な形でSPAのロケーションを操作できるようになった経緯がある。しかし、同時にサーバのサポートが必要になった。もしそのURIがアドレスバーをクリックするなどしてサーバに送信されたら、適切な制御を行ってレスポンスを返す必要があるからだ（react-router公式にも書いてある[^1]）。そのサポートとは次のような制御を指す。

[^1]: https://github.com/reactjs/react-router/blob/master/docs/guides/Histories.md#configuring-your-server

1. 個々のページのリクエストに対して、サーバはその時の状態を解釈して適切なコンテンツを描画し、応答する（いわゆるサーバサイドレンダリング）。
2. すべてのリクエストに対して、同一の初期表示用ページを戻し、その後の実際の描画処理はクライアントに任せる
3. 上記をミックスする

もし、Nodejs + express を使ってアプリケーション開発していて、次のような記述をしているなら、そのアプリのサーバのサポートは上記の2に当たる。

```js:server.js
// serve our static stuff like index.css
app.use(express.static(path.join(__dirname, 'public')));

// send all requests to index.html so browserHistory in React Router works.
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

```

このアプローチだと（かつ、相対パスで静的ファイルを指定していると）、ベースパス直下が第一階層だけのURI構成を検討している間は問題がないが、それより深くしようとすると、深刻な問題が発生する。開発者は常にベースパスからの相対パスとして静的ファイルの場所を指定しているのに、ブラウザはロケーションに指定されたパスからの相対パスに対してファイルをリクエストするからだ。

> （前項再掲）例えば`www.domain.jp/blog/123`に対してリクエストを送ると、ブラウザは上記の静的ファイルを取ろうとして、`www.domain.jp/blog/css/animate.css`を参照してしまう。`bundle.js`も然り。それらのファイルは存在しないのでロードできず、`react`は動かない。

## 解決方針
問題点をまとめると、

* 現在のサーバ実装は2の形を取っている。この時、初期表示用のHTMLファイル内に外部ファイルが相対パスで指定されていると問題が起こる。
* 遷移先のURIが`www.domain/path`の場合、cssやjsの参照先も`www.dmain.jp/path/css/...`といった形で誤った場所を示してしまう。本当は、
`www.dmain.jp/css/...`としたい。

ということになる。
そこで解決策としては

**パスの頭に`/`を追加して、絶対パス化する**。
これにより、URIの深さによらずに静的ファイルを確実に参照できるようになる。 

```html:index.htmlの記述抜粋（新）
<link href="/css/animate.css" rel="stylesheet">
<script src="/build/bundle.js"></script>
```

## ハマリ時間
4時間。。

## 参照したページ
https://blog.tyrsius.com/pushstate-relative-paths/
Windows Formアプリケーションでの非同期処理

# Timerって便利だけれども

Windows FormアプリケーションではTimerコンポーネントがあるので一定間隔の処理を行うのは便利ですね。
ただし、このTimerはGUIスレッドで動作するので、重い処理を実行するとGUIのイベントループも止まってしまうために、ウィンドウが動かせなかったりします。

以下だと、10秒間固まってしまうわけです。

```csharp
    private void timerHoo_Tick(object sender, EventArgs e)
    {
        Thread.Sleep(10000);
    }
```

# 間違った解決

それを嫌ってタスクに処理を任せたくなるわけですが、それにも問題があります。

```csharp
    private void timerHoo_Tick(object sender, EventArgs e)
    {
        Debug.WriteLine("start");
        Task.Run(() =>
        {
            Debug.WriteLine("thread start");
            Thread.Sleep(10000);
            Debug.WriteLine("thread end");
        });
        Debug.WriteLine("end");
    }
```

これを実行するとタスク生成だけしてTick関数がさっさと抜けていき、Timer間隔が短いと次々とタスクが生成されてしまいます。

```
start
end
thread start
start
end
thread start
start
end
thread start
start
end
thread start
thread end        // <-いつの？？？
```

# async/await で解決

そこで登場するのが C#5.0 から使える async/await ですね。

```csharp
    private async void timerHoo_Tick(object sender, EventArgs e)
    {
        Debug.WriteLine("start");
        await Task.Run(() =>
        {
            Debug.WriteLine("thread start");
            Thread.Sleep(10000);
            Debug.WriteLine("thread end");
        });
        Debug.WriteLine("end");
    }
```

平和です。

```
start
thread start
thread end
end
start
thread start
thread end
end
start
thread start
thread end
end
```

お詳しい解説は[こちら](
https://ufcpp.wordpress.com/2012/11/12/asyncawait%E3%81%A8%E5%90%8C%E6%99%82%E5%AE%9F%E8%A1%8C%E5%88%B6%E5%BE%A1/)。
license > Visual Studio 2015 > Androidアプリ開発

[編集中]

Visual Studio Communityの制限を超える場合の開発体制において、Visual StudioでAndroidアプリ開発を行う場合の費用の調査。

[Xamarin の開発環境を整理しよう](http://ytabuchi.hatenablog.com/entry/2016/04/02/163106)

> Visual Studio と Xamarin Studio は同じライセンスが適用されます。大原則としては、個人開発者は Community ライセンス で無料、企業開発者は Visual Studio with MSDN を購入しましょう。

Visual Studio Professional with MSDNが70,000円くらいで、そのサブスクリプションでAndroid開発もできるということだろうか?
https://www.npress.jp/msdn_chart

他のIDEではOSごとにライセンス料が発生したりするので、それと上記が混乱している。

[MSDNのボリュームライセンス価格比較](http://tmori3y2.hatenablog.com/entry/2016/02/28/235459)
価格比較に関して詳しい。
バッチ作成の基礎

（参考）[開発に役立つBATファイルの書き方・パターン集](http://language-and-engineering.hatenablog.jp/entry/20130502/PatternsOfMSDOSorBAT)

## 雛形
### **基本形**
```bat
@echo off

rem
rem このバッチの説明
rem

rem 設定事項
set hoge="変数の値"

rem このバッチが存在するフォルダをカレントに
pushd %0\..
cls

〜処理〜

pause
exit 0
```
- コマンドの先頭に@をつければ，バッチ実行時に，そのコマンド自体は表示されなくなる。
- echo offとすれば，実行しているコマンド自体の表示を全面的にOFFにできる。
- pushdは，ディレクトリの移動。cdコマンドだと，異なるドライブに移動できない。
- %0 は，このバッチファイルのファイルパス。

### **反復系**
```bat
@echo off

:start
cls

rem ----- メイン処理 -----
〜〜
rem ----- キー入力で分岐 -----

echo.
set userkey=
set /p userkey=終了する (Enter) / メイン処理を再度実行 (o + Enter) / サブ処理を実行 (p + Enter) ?
if not '%userkey%'=='' set userkey=%userkey:~0,1%
if '%userkey%'=='o' goto start
if '%userkey%'=='p' goto exec
goto quit

rem ----- サブ処理 -----

:exec

〜〜

rem ----- 終了 -----

:quit

exit
```
- コロンで始まる行は，ラベル。gotoで，ラベルにジャンプすることができる。
- set /p は，ユーザ入力値を環境変数に格納する。

## 構造化
### **ルーチンの分割**
```bat
@echo off

rem メイン処理：サブルーチンのテスト
call :routine_hello hoge
call :routine_hello fuga
call :routine_hello boo


pause
rem メイン処理はここで終了
exit



rem 引数を受け取って，Hello と表示するルーチン。
:routine_hello

echo Hello, %1!

exit /b
```
- ラベルをgotoではなくcallで呼び出せば，サブルーチンになる。
- サブルーチンには，そのサブルーチン独自の引数を渡すことが可能。
- サブルーチン内では%1などで参照。
- サブルーチンからメインルーチンに戻る際には，exit /b する。/b オプションを付けないと，バッチ全体が終了してしまう。
- ルーチンからの戻り値について,数値しか返却できず，大したことはできない。
- バッチ内のルーチンから，呼び出し元に値を返却するには，errorlevelを使う。

### 実行ファイルや実行プロセスの分割
- .batファイル自体を分割。
- 呼び出し方法には２つある：  
call バッチファイル名  
start バッチファイル名
- callでラベルを指定すればサブルーチンを呼び出せたのと同じように，別バッチを呼び出せる。
- startで呼び出した場合は，プロセスも分かれる。

## 小ネタ
### **日付処理**
```bat
set date_tmp=%date:/=%
set time_tmp=%time: =0%
set yyyy=%date_tmp:~0,4%
set yy=%date_tmp:~2,2%
set mm=%date_tmp:~4,2%
set dd=%date_tmp:~6,2%
set hh=%time_tmp:~0,2%
set mi=%time_tmp:~3,2%
set ss=%time_tmp:~6,2%
set sss=%time_tmp:~9,2%

rem yyyymmddhhmisssss
set datetime=%yyyy%%mm%%dd%%hh%%mi%%ss%%sss%

rem yyyy/mm/dd hh:mi:ss:sss
set datetime=%yyyy%/%mm%/%dd% %hh%:%mi%:%ss%:%sss%
```
CodeMirrorの設置

## CodeMirror

* [公式ページ](http://codemirror.net/)
* [config](https://codemirror.net/doc/manual.html#config)
    * [css - Set size to CodeMirror editor? - Stack Overflow](http://stackoverflow.com/questions/13779519/set-size-to-codemirror-editor)

```html:コピペでそのまま動きます
<link rel=stylesheet href="http://codemirror.net/lib/codemirror.css">
<script src="http://codemirror.net/lib/codemirror.js"></script>
<script src="http://codemirror.net/mode/xml/xml.js"></script>

<textarea id="txt">
<div>aa</div>
</textarea>

<script>
  var txt = document.getElementById("txt");
  var editor = CodeMirror.fromTextArea(txt, {
    lineNumbers: true
   ,lineWrapping: true
  });
  editor.setSize("100%", "100%");
</script>
```

![txt.png](https://qiita-image-store.s3.amazonaws.com/0/25728/925c0e08-aee7-9011-714d-25579f28984b.png)


## その他

* [CLEditorの設置、カスタマイズ - Qiita](http://qiita.com/tukiyo3/items/b53b26b347adfdbf47f0)
Jenkinsでbuildするときにmerge漏れを検知する方法

# 概要
`git branch -r --merged`を利用したチェックスクリプトを噛ませる

# やりたいこと
- 最新のdevelop(またはmaster)ブランチの内容をmergeしてないfeatureブランチを開発環境に上げてしまうミスを無くしたい
    - 上げたあとに気づいて再デプロイ&再テストするコストがかかる

# 経緯
- 「merge漏れしてるモジュールでテストしてしまっていて、実はデグレってました」とかがちょいちょいあった。
- 「基準ブランチに変更があったら、必ずfeatureブランチに取り込むこと」ってルールづけても、merge漏れを0にするのは不可能だから、何とかしたかった。

# アプローチ
### Jenkinsでjobを実行する際、build対象のブランチがmerge漏れを起こしていたら、そのbuildを失敗させる
#### merge漏れの定義
- 基準ブランチに含まれていて、build対象ブランチに含まれていないcommitが存在する
    - fast-forward mergeができない状態

#### 手順
1. build対象のブランチが、基準ブランチの内容を含んでいるかどうかをチェックするスクリプトを用意する
2. そのスクリプトをJenkins jobの前処理として実行する
3. そのスクリプトのチェックに通ったときだけbuildを継続し、そうでない場合はbuildを失敗させる

### チェックスクリプトの詳細

```sh:branch_validator.sh
# 基準ブランチ(e.g. origin/master)の内容がmerge済みなら、IS_BASE_MERGEDに"1"が入る
IS_BASE_MERGED=`git branch -r --merged | egrep -c 'origin/master'`
OK_FLG=1
if [ ${IS_BASE_MERGED} -ne ${OK_FLG} ] ; then
  echo "please merge from base branch"
  exit 1
else
  echo "go ahead"
  exit 0
fi
```

# まとめ
__ルールとGitおじさん頼りの運用を減らしていきましょう__
mysqlで複数行を1行にまとめて１クエリで取得してphpで配列に戻す(フリーテキストを考慮エスケープあり)

とりあえず簡易処理です。
例えば１記事に対してタグが複数つくようなシステムがあるとします。
記事テーブルてきなものに、記事タグテーブルてきなものが１対多になっている感じとします :exclamation: 

posts (記事テーブル)

| id | title |
|:-:|:-:|
| 1  | 夏休みのおすすめスポット |

post_tags (記事に付与されたタグ)

| post_id | tag_id | name |
|:-:|:-:|:-:|
| 1 | 34  | 夏休み  |
| 1 | 567 | おすすめ  |
| 1 | 98 | 子供  |

これを諸所の理由により、１クエリしかできない時に記事の１レコードに複数のタグも一緒にまとめて、１行で取得したい!

そんなときは、

```sql
SELECT
    p.id AS id,
    p.title AS title,
    t.ids AS tag_ids,
    t.names AS tag_names
FROM
    posts AS p
LEFT JOIN (
    SELECT
        pt.post_id,
        GROUP_CONCAT(pt.tag_id) AS ids,
        GROUP_CONCAT(REPLACE(REPLACE(pt.name, '&', '&amp;'), ',', '&#44;')) AS names
    FROM
        post_tags AS pt
    GROUP BY 
        pt.post_id
) AS t ON t.post_id = p.id
```

タグの複数行をGROUP_CONCATを使って１行にまとめます。
GROUP_CONCATで「34,567,98」のように、カンマ区切りで１行になってくれます。
これをphpで

```php
$tagIds = explode(',', $row['tag_ids'])
```
のようにカンマ区切りで配列にもどせば完了!

**しかし、ちょっとだけ注意!**

注意したいのがこれがidで中身が数値とわかってる場合のみ。
フリーテキストであるタグの名前「夏休み」とかの場合を考慮しなければいけない。
なぜなら、タグの名前に
**「カ,ン,マ,区,切,り,し,て,や,ん,よ」**
みたいな意地悪なタグを付けられてしまうかも。

それを考慮すると

```sql
GROUP_CONCAT(REPLACE(REPLACE(pt.name, '&', '&amp;'), ',', '&#44;'))
```

htmlのエスケープ処理をちょっとだけ借用
取得時に「,」を「&amp;#44;」に置換してエスケープします。
さらにタグに「&amp;#44;」を含めるいじわるもできるので、「&」を「&amp;amp;」に置換してエスケープします。

そしてphp側でエスケープを戻す処理を足して

```php
function unescape ($str)
{
    return str_replace('&amp;', '&', str_replace('&#44;', ',', $str));
}
```

```php
$tags = [];
$ids = explode(',', $row['tag_ids']);
$names = explode(',', $row['tag_naames']);
foreach ($ids as $index => $id) {
    $tags[] = [
        'id'   => (int)$ids[$index],
        'name' => unescape($names[$index]),
    ];
}
```

と、すれば１クエリの縛りでも１対多のタグデータもphp上で配列として取り出せます :+1: 
以上です!
ShinobiLayer: BluemixやSoftLayerが動いているデータセンターをtracerouteで調べる方法

#はじめに
「BluemixってSoftLayerで動いているみたいだけど、どこのデータセンターで動いているんだろう！？」「このサーバーってSoftLayerで動いているみたいだけど、どこのデータセンターで動いているんだろう？」っていうことはありませんか？実は簡単にtracerouteからでも調べることができるのです。本記事ではそのTipsをお伝えします。

#tracerouteで出力されるbbrとかdarとかって何？

bbr=Back Bone RouterなのでネットワークPOPの場所
dar=Distribution Aggregation Routerなので、データセンターの場所
fcr=Frontend Customer Routerなので、サーバーやVyattaのdefault gatewayの1st hop


#やってみよう1: SoftLayer上のサーバーのIPを指定する

```txt:traceroute
C:\>tracert xx.xx.xx.xx

xx.xx.xxxx.ip4.static.sl-reverse.com [xx.xx.xx.xx] へのルートをトレースしています
経由するホップ数は最大 30 です:

  1     3 ms    19 ms     2 ms  xx.xx.xx
  2     8 ms    21 ms     4 ms  xx.xx.xx [xx.xx.xx.xx]
  3    36 ms     9 ms    16 ms  xx.xx.xx [xx.xx.xx.xx]
  4     *        *        *     要求がタイムアウトしました。
  5     6 ms    19 ms     4 ms  xx.xx.xx.xx
  6   195 ms    73 ms   101 ms  ae1.bbr01.eq01.sng02.networklayer.com [xx.xx.xx.xx]
  7    80 ms   116 ms    82 ms  ae5.dar01.sr03.sng01.networklayer.com [xx.xx.xx.xx]
  8     *        *        *     要求がタイムアウトしました。
```

キャリアとの相性のせいか、日本からアクセスしているのに直接SNG02のPOPに吸い込まれていますね。最終的には対象のサーバーは、

- ae1.**bbr01**.eq01.**sng02**.networklayer.comなので、sng02のネットワークPOP
- ae5.**dar01**.sr03.**sng01**.networklayer.comなので、sng01のデータセンター

が使われていることが分かります。

※fcrはサーバー側のFW設定などで応答しないためにtracerouteで見えないこともあります。



#やってみよう2: Watsonのサービス 
気になるサービスに対して、tracerouteを打ってみましょう。
たとえば、Watsonの「Speech to Text」サービスは、`https://stream.watsonplatform.net/speech-to-text/api`を使っているので、stream.watsonplatform.netをチェックしてみましょう。

```txt:traceroute
C:\>tracert stream.watsonplatform.net

stream.watsonplatform.net [xx.xx.xx.xx] へのルートをトレースしています
経由するホップ数は最大 30 です:

  1    21 ms     2 ms    16 ms  xx.xx.xx
  2    33 ms     4 ms    16 ms  xx.xx.xx [xx.xx.xx.xx]
  3     5 ms    18 ms     5 ms  xx.xx.xx [xx.xx.xx.xx]
  4     *        *        *     要求がタイムアウトしました。
  5    25 ms     7 ms    16 ms  xx.xx.xx.xx
  6   115 ms   132 ms   112 ms  ae2.bbr02.eq01.sjc02.networklayer.com [xx.xx.xx.xx]
  7   133 ms   113 ms   130 ms  ae0.bbr02.cs01.lax01.networklayer.com [xx.xx.xx.xx]
  8   113 ms   126 ms   114 ms  ae7.bbr01.cs01.lax01.networklayer.com [xx.xx.xx.xx]
  9   161 ms   142 ms   159 ms  ae19.bbr01.eq01.dal03.networklayer.com [xx.xx.xx.xx]
 10   143 ms   159 ms   141 ms  ae5.dar02.dal06.networklayer.com [xx.xx.xx.xx]
 11   173 ms   149 ms     *     po2.fcr01.sr02.dal06.networklayer.com [xx.xx.xx.xx]
 12   381 ms   141 ms   158 ms  xx.xx.xx.xx -static.reverse.networklayer.com [xx.xx.xx.xx]
 13     *        *        *     要求がタイムアウトしました。
 14     *        *        *     要求がタイムアウトしました。
```

こちらもキャリアとの相性のせいなのか、日本からアクセスしているのにtok01のPOPではなくsjc02のPOPに吸い込まれています。laxのPOPを経由した後、最終的には、

- ae19.**bbr01**.eq01.**dal03**.networklayer.comなので、dal03のネットワークPOP
- ae5.**dar02**.**dal06**.networklayer.comとかpo2.**fcr01**.sr02.**dal06**.networklayer.comなので、dal06のデータセンター

のサーバーにアクセスしていることが分かります。

※もちろん、サービスの外部インターフェースの場所がdal06だというだけであって、内部実装がどこでされているかまでは分かりません。
fluentdのrequire_ack_response設定は、やっぱり必須設定だと再認識したときの検証メモ

#1.検証背景
## 参考記事  
[Fluentd v0.12のAt-least-once Semanticsを試す](http://ogibayashi.github.io/blog/2014/12/16/try-fluentd-v0-dot-12-at-least-once/)
[fluentdでログが欠損する可能性を考える](http://blog.livedoor.jp/sonots/archives/44690980.html)

などで、fluentd v0.12を使ったときに、「require_ack_responseを必ず設定しておくように」というノウハウは、大分浸透するようになったと思われる。
ただ、fluentdを運用する中で、require_ack_responseの設定漏れに気付かず、受信側のfluentdをreloadしてしまうケースも考えられる。
ということで、実際の運用下でこの設定がどれぐらいの効果を発揮するのかを検証してみた。

#2.検証環境
##2-1.構成図
![td-agent ack.png](https://qiita-image-store.s3.amazonaws.com/0/14190/37622def-1b07-f3aa-515f-121e57d7287c.png "td-agent ack.png")
図にするほどでもないが、fluentdの送信側と受信側のEC2を準備する。
OSとfluentdのバージョンは以下の通り。

##2-2.検証環境
|環境|バージョン|
|:---|---:|
|OS|Ubuntu14.04|
|fluentd(td-agent)|0.12.20|

インストールが楽なので、td-agentを利用した。

##2-3.設定ファイル
送信側と受信側の設定ファイルは以下の通り。

###送信側のtd-agent.conf
```
<source>
  type forward
  @label @raw
</source>

<label @raw>
  <match test.**>
    buffer_type file
    buffer_path /tmp/hoge.buffer
    flush_interval 1s

    type forward

    require_ack_response #ここの設定をコメントアウトしたりする
    flush_at_shutdown true

    <server>
       host [受信側のホスト]
       port 24224
    </server>
  </match>
</label>
```

###受信側のtd-agent.conf
```
<source>
  type forward
  @label @raw
</source>

<label @raw>
  <match test.**>
    buffer_type file
    buffer_path /tmp/hoge.buffer

    type file
    path /tmp/hoge.log
  </match>
</label>
```

#3.検証結果
fluent-catを使って、1,000件のデータを送信しながら、10secごとにreloadするパターンとlogrotateするパターンの2ケースを検証してみる。

## 送信側

```
for i in `seq 1 1000`;do echo "{\"test\":\"$i\"}" | /opt/td-agent/embedded/bin/fluent-cat test.1;done
```


## 受信側
### 3-1.td-agentをreloadしたときのケース
```
for i in `seq 1 10`;do /etc/init.d/td-agent reload;sleep 10;done
```

実行後のログ受信結果は、以下の通り

### require_ack_responseなし

|試行回数|recieverに届いたログの件数|
|:---|---:|
|1回目|946|
|2回目|951|
|3回目|970|
|4回目|960|
|5回目|947|
大体54~30件ぐらいのログのロストが見られた。

### require_ack_responseあり

|試行回数|recieverに届いたログの件数|
|:---|---:|
|1回目|1,000|
|2回目|1,000|
|3回目|1,000|
|4回目|1,000|
|5回目|1,000|

ログのロストなし。

### 3-2.td-agentがlogrotateしたときのケース
```
for i in `seq 1 10`;do pid=/var/run/td-agent/td-agent.pid;test -s $pid && kill -USR1 "$(cat $pid)" ;sleep 10;done
```

実行後のログ受信結果は、以下の通り

### require_ack_responseなし

|試行回数|recieverに届いたログの件数|
|:---|---:|
|1回目|1,000|
|2回目|1,000|
|3回目|1,000|
|4回目|1,000|
|5回目|1,000|
ログのロストなし。

### require_ack_responseあり

|試行回数|recieverに届いたログの件数|
|:---|---:|
|1回目|1,000|
|2回目|1,000|
|3回目|1,000|
|4回目|1,000|
|5回目|1,000|

ログのロストなし。


#4.まとめ
日々のlogrotate時ではログの欠損は見られないが、設定ファイルの変更などでreloadしたりするときにはログの欠損が見られた。本番環境など、今回のケースよりさらにログ流量が多い環境では、かなりのログを欠損することがあると考えられる。

AWSとはいえど、ネットワークの瞬断などの不調なときは発生するし、EC2インスタンスも再起動するときがあるので、やっぱりrequire_ack_responseは確実に設定しておくことが必要かと。
あと、fluentdがまだv0.10環境下のシステムは、やっぱりアップデートしておきましょう^^;
Sphinxってこんなもの（主観）


Sphinx user group JPの方々がハンズオンしてくださったので、まとめ直した上でSphinxについて紹介します。
なお、この記事の内容に関する質問はこの記事のコメントにお願いします。

# TL;DR
- テキストベースのドキュメントツール
  - 出力は様々なドキュメントフォーマット 
  - ドキュメントツールなので、Webサーバとは別 (素のドキュメントのみ)
- 学習コスト低そう
  - Python使いなら更に低そう

# Sphinxをざっと眺める
## 文書を整形してくれるツール
一通りの機能がある

- 見出し
- 強調
- 斜体
- 箇条書き

## メンテしやすい
- 目次の自動生成ができる
- 文書ごとに変えたい箇所を設定ファイルとして外に出せる
- 拡張機能が豊富

## データの取り込みができる
- CSVファイルを読んで、整形して表示できる
- make時にコマンドも実行できる

## ホスティングサービスもある
- Read the Docs https://readthedocs.org/
- オンプレミスも可能なので社内向け / 個人のクローズド利用もできる

## 根っこはPython
- Pythonコードを書ける。もとい困ったらPython書いちゃえば良いらしい
- Sphinxが利用しているreStructure形式はPythonの持ち物
  - →大雑把に言うと、SphinxはPythonの拡張モジュールらしい

# Sphinxインストール
## Windows
(すいません現状では未稿です。後日試して追記予定)
(それまではお手数ですがSphinx公式サイトのインストール方法をご覧下さい)
http://www.sphinx-doc.org/ja/stable/install.html

英語版はこちら↓
http://www.sphinx-doc.org/en/stable/install.html

## Linux(Cent OS 7)

```shell-session
sudo yum install python-pip
sudo yum install python-devel

sudo pip install sphinx
```

## Mac

```shell-session
# pre check
which python
#=> /usr/bin/python

# install python 2.X
brew install python

# after check
which python
#=> /usr/local/bin/python

which pip
#=> /usr/local/bin/python

# install sphinx
pip install -U Sphinx

# version check
sphinx-build -v
#=> Sphinx v1.4.4 (with usage)
```

# 最初にやるといいもの
## エディター設定
- 文字コードはUTF-8
- フォントは等幅(縦の位置を揃えたりするため)
- インデントは半角スペースで３個(ディレクティブ以外は２個)
  - Tabを使うのはやめた方が良い 
- reStのシンタックスハイライトができると楽(vim, emacs, atom, sublimeなど)
  - vimだとriv.vim https://github.com/Rykka/riv.vim
  - 補完の省力化
  - 見出しの設定
  - 表のアライメント

## sphinx-quickstart
https://pythonhosted.org/an_example_pypi_project/sphinx.html#sphinx-quickstart

## sphinx-quickstartのオススメ設定
- Project language [en]
  - → ja (日本語にしておくのがベター)
- todo利用(todo: write “todo” entries that can be shown or hidden on build (y/N) [n]:) [n]
  - → y (TODOの表示/非表示機能を使う)

# Tips
## テーマ(ドキュメントの外観)
- HTMLドキュメントの場合、html_themeという設定値を自分で書き換え可能
- 割と自由に選べる
- 選んだものにより、見出しの最大レベルが多少違ったりする(らしい)

## 箇条書き
- 記号を３種類から選べる
- 箇条書きの開始前に空行が必要(見出しの直後なら不要)
- 箇条書きの途中の空行は無視される
- 記号を変えることで箇条書きをブロック分け(カテゴリ分け)できる

## 見出しのレベル設定
- 基本的に１ずつ増やす
- レベル減らす際は一遍に減らせる
  - h5の次にh2を書くとか
- レベル表記の見出しの後に空白行はなくても良い

## 表
- CSVファイルから読み込んで表にできる
  - ファイルのパスは相対パス指定
- 表の列幅は全体を100とした割合(百分率)で決まる
  - 幅の比を書き手が指定できる

## ディレクティブ
- 拡張機能
- 自分で追加することもできる
- 便利な物はいっぱい公開されてる

## toctree (目次のディレクティブ)
- 目次の最大レベル→maxdepth
- 小見出しの細かいナンバリング→numberd
- 見出しの順序を入れ替えたり、見せ方を検索条件で制御する→glob

## 全体を通して、慣れが必要そうな点

- インデントで縦の位置をちゃんと揃える 
- 等幅フォント使えるエディタの利用を推奨
- 表も縦位置をちゃんと揃える
  - AAで表を作るイメージ
- 幅変えるのはエディタの支援がないと大変そう
- ブロック単位で構造化する
  - 素のPythonと同じ
- 必要な箇所に空行を入れ忘れないように気をつける
  - make時に警告が出るので気づけるかも

# 日本のSphinxコミュニティー

※Sphinx作者はドイツの方だそうですが、日本のコミュニティーは割と活発です

# Twitter
```#sphinxjp```で検索 https://twitter.com/search?q=%23sphinxjp&src=typd

# Sphinx日本ユーザグループ
http://sphinx-users.jp/

- 公式ML 
- 公式Slack https://sphinxjp.herokuapp.com/

# Connpass
http://sphinxjp.connpass.com/

- だべり会（月１回）
- なんでもやる回（月１回）（聞いた感じだともくもく回）
技術英語 > Architecture [Prerequisite] / requisite

@ Code Complete > Architecture Prerequisite (No. 2271 / 36077)

Prerequisite 
http://ejje.weblio.jp/content/prerequisite
> 前提条件

requisite
http://ejje.weblio.jp/content/requisite
> 必要な、必須(ひつす)の、なくてはならない

pre + requisiteで「前提条件」
innerHTMLがHTMLをそのまま取得できるわけではない

## 参考

* [innerHTML や jQuery.html() は HTMLをそのまま取得できるわけではない | jmblog.jp](http://jmblog.jp/archives/876)

> innerHTML や jQuery.html() は HTML のソースをそのまま返すわけではなく、ブラウザが一度 DOMツリーに変換したものを返すとのこと。従って、invalid な HTML コードだと、それぞれのブラウザが解釈したDOMツリーが返ってくるというわけでした。

## 例1

```html:li.html
<li>1 <li>2 <li>3 <li>4
<script>
    alert(document.body.innerHTML);
</script>
```

![li.png](https://qiita-image-store.s3.amazonaws.com/0/25728/df9b5d5f-7533-5006-6534-a38b5b193a4e.png)

![chrome.png](https://qiita-image-store.s3.amazonaws.com/0/25728/0b4c283c-b16e-0db1-f731-fe98c94c0417.png)

![child.png](https://qiita-image-store.s3.amazonaws.com/0/25728/378dbceb-470a-80cb-3a76-5e5afd0913d2.png)


## 例2

```html:body.html
<body>aaa</body>
<script>
    alert(document.body.innerHTML);
</script>
```

![html.png](https://qiita-image-store.s3.amazonaws.com/0/25728/90b925df-9061-7cef-d5ff-c164e7618934.png)

## 例3

```html:p.html
<p>
<script>
alert(document.body.innerHTML);
</script>
```

![e2.png](https://qiita-image-store.s3.amazonaws.com/0/25728/72b39ad7-28f6-bcd3-5d60-5b5c0566b58b.png)
conemuでトリッキーな事をせずにpowershellのターミナルを開く

出来た。
`"C:\ConEmu\ConEmu64.exe" /dir "%d" /cmd powershell -cur_console:n`

/hereとかのオプションは[ConEmu \| ConEmu\.exe Command Line Switches](https://conemu.github.io/en/ConEmuArgs.html)がドキュメント
-cur_console:nのオプションは[ConEmu \| Switches \-new\_console and \-cur\_console](https://conemu.github.io/en/NewConsole.html)がドキュメント
たった3人でnVidiaを作った漢　黃仁勳(ジェン スン ファン）


![nvidia.001.jpeg](https://qiita-image-store.s3.amazonaws.com/0/131316/165530e6-8164-64e9-1a5d-2acafb69ceab.jpeg)

PCビデオカード市場をリードするnVidiaは、社員数１万人前後を要する世界大企業だ。

しかし、nVidiaの最初の一歩はとても小さいもので
1993年　たったの３名で創業した。
![nvidia.002.jpeg](https://qiita-image-store.s3.amazonaws.com/0/131316/06eaa6ff-0a5c-c96d-7d63-112e9af7b58e.jpeg)
創業者の名は**黃仁勳(ジェン スン ファン）**
現在もnVidiaの最高経営責任者CEOで、全米で第42位の大富豪でもある。

まだDirectXの影も形もない1993年にNV1の開発はたったの3人でひっそりスタートした。

![nvidia.003.jpeg](https://qiita-image-store.s3.amazonaws.com/0/131316/ad3ce5c9-9e1c-e03d-f56a-1c9f3f1d7211.jpeg)

当時、ちょうどLSIの「設計」と「製造」が分離されようとした時期だった。
つまり「設計」だけに専念するファブレス企業と
ひたすら「製造」だけに専念するファウンドリー企業とで
お互いに分業されはじめた時期でもあった。
そしてMicrosoftもWindows95のリリースに合わせてＤｉｒｅｃｔＸの開発を進めていたことも追い風だった。

**黃仁勳** はファブレス時代の到来を予感し、全部を賭けていた。
![nvidia.004.jpeg](https://qiita-image-store.s3.amazonaws.com/0/131316/9de995d6-0a3a-f51c-5c7a-92364f4b48ac.jpeg)

黃仁勳はただ単に高速な3Dビデオカード作ってもただの箱であることを良く知っていた。
だからYUAN 3DS-100の発売時は、事前に当時のSEGAと直接交渉。バーチャファイターとパンツァードラグーンを移植＆バンドルさせることに成功する。

それにしても天才LSI設計者 **黃仁勳** とは何者？

![nvidia.005.jpeg](https://qiita-image-store.s3.amazonaws.com/0/131316/d5cfe3c2-5594-3858-f428-1fdb9db31d83.jpeg)

**黃仁勳**は中国の青田県というところで生まれ、ほどなくして台湾に移民。
さらに家族と共に米国へ移民した。
渡米後の15歳の時、卓球を始めて全米卓球OpenのJr.ダブルスでなんと第3位。

![nvidia.006.jpeg](https://qiita-image-store.s3.amazonaws.com/0/131316/796b42af-4619-5d72-c9e4-009c23e67ff8.jpeg)

その後、オレゴン州立大学へと進学。スタンフォード大学で博士号を取得。
![nvidia.007.jpeg](https://qiita-image-store.s3.amazonaws.com/0/131316/b3c181c4-df63-80ce-e327-ea01f35fbb1d.jpeg)

大学卒業後、新卒で就職した会社はあの**LSIロジック**

![nvidia.008.jpeg](https://qiita-image-store.s3.amazonaws.com/0/131316/b019e6e6-9393-6adb-e9ba-6d8ae66f5745.jpeg)

その後、**AMD**に移籍しマイクロプロセッサの設計に携わる。
しかし**黃仁勳**は「CPUの時代は終りだ。GPUの時代だ。コンピュータは全てピクセルで出来ている」と確信し**ｎＶｉｄｉａ**を創業するのだ。
この時の回想は、中国でのテレビ番組でもインタビューという形で本人自ら語っている。

![nvidia.010.jpeg](https://qiita-image-store.s3.amazonaws.com/0/131316/1503d053-98ad-91f4-1524-e1663593bb34.jpeg)

YouTube
https://www.youtube.com/watch?v=D3xB8M2GF7E
nVidia本社の中にもカメラを入れている興味深い番組に仕上がっている。
FPGAによる開発ではなく、スパコンでシミュレータを利用している様子らしき映像も流れている。
有名な話だが、nVidiaは10年ほど前からFPGAを一切使わずシミュレータのみで開発している。
番組中　卓球の腕前も披露している。

![nvidia.009.jpeg](https://qiita-image-store.s3.amazonaws.com/0/131316/d9cc2da7-8220-5aaf-d938-8e0b9eaa66dd.jpeg)

TSMCの40nm -> 28nm -> 16nm と製造ラインのロードマップを説明する**黃仁勳**
しかし、最近ではGPUの性能に対する需要も頭打ちだ。ブラウザとメーラを起動する用途ならば高速なGPUなどいらないのだ。
そこで、CUDAなどグラフィックス以外の用途に目を向けている。

![nvidia.011.jpeg](https://qiita-image-store.s3.amazonaws.com/0/131316/38aebe35-6cd5-62f4-9503-42fc2a46ddea.jpeg)

TITANを利用した時のベンチマーク。
人工知能は久しぶりにおとずれたブームだ。いや一過性のブームではない。人類の英知の特異点が迫っているとも言われている。
スパコンもこの分野に力を入れている。

* Intelビビってる 世界最速スパコン神威太湖之光
http://qiita.com/homhom44/items/f91bb8962a40286171b0

* nVidiaもビビってる 世界最速スパコン神威太湖之光
http://qiita.com/homhom44/items/4b03123920f4788dfca4

![nvidia.012.jpeg](https://qiita-image-store.s3.amazonaws.com/0/131316/636ef1d1-267f-fbf6-8ced-0bc4ad06dbf3.jpeg)

nVidiaはCUDAで対抗する。事実、nVidiaのGPUがスパコンに採用されているケースも多いのだ。

**黃仁勳** 率いるｎＶｉｄｉａはこの先どこに向かうのだろうか？今後も目が離せない。
moment.jsのtimezoneを１行で日本に設定。

```js:
var moment = require('moment-timezone');
moment.tz.setDefault("Asia/Tokyo");
console.log( moment().format() ); // 日本の現在時刻になっていることが確認できる。
```

公式サイトの情報はこちら。
http://momentjs.com/timezone/docs/#/using-timezones/default-timezone/
csv のほどよい完全外部結合



# 問題

http://qiita.com/isseium/items/20eb6802898d9b1ba2b4

で、 join コマンドを用いて完全外部結合を行う方法が示されている。ただ、output のフォーマットを毎回指定するのはめんどい。かといってフォーマットがないと、下みたいに列がそろわず、あまりよくない感じで join されてしまう。具体的には、外部結合部分の、行の列の数が、異なって出力されてしまう。

```shell-session:problem-example
: 1.csv
hoge,100
fuga,200
piyo,300

: 2.csv
hoge,Adam
fuga,Bill
moge,Charlie

$ join -a 1 -a 2 -t, -j 1 1.csv 2.csv
hoge,100,Adam
fuga,200,Bill
moge,Charlie
piyo,300
```

# 解決方法

output のフォーマットを生成しながら join を実行することにより、この問題を解決する。

```shell-session:nice-join.sh
#!/bin/bash

if [ $# -ne 2 ]
then
    echo "usage: $0 [-j num_field ][ -1 num_field1 ] [ -2 num_field2 ] 1.csv 2.csv" 1>&2
    exit 1
fi

j1_field=1
j2_field=1

while true; do
    case "$1" in
        -j)
            j1_field="$2"
            j2_field="$2"
            shift 2
            ;;
        -1)
            j1_field="$2"
            shift 2
            ;;
        -2)
            j2_field="$2"
            shift 2
            ;;
        *)
            break
            ;;
    esac
done

count_commas() {
    sed 's/[^,]//g' | wc -c
}

make_format() {

    if [ $# -ne 3 ]
    then
        echo "usage: $0 file_num join_field num_commas" 1>&2
        exit 1
    fi

    seq 1 $3 |
        grep -v $2 |
        awk -v num=$1 '{printf ("%s.%s\n",num,$0)}' |
        { tr '\n' , ; echo; } |
        sed 's/,$//'
}

cat "$1" | {
    exec 3<&0
    read -r line1
    num_commas1=$(printf '%s\n' "$line1" | count_commas)
    format1=$(make_format 1 $j1_field $num_commas1)
    cat "$2" | {
        read -r line2
        num_commas2=$(printf '%s\n' "$line2" | count_commas)
        format2=$(make_format 2 $j2_field $num_commas2)
        join -o 0,$format1,$format2 \
             -a 1 -a 2 -t, \
             -1 $j1_field -2 $j2_field <(
            printf '%s\n' "$line1"
            cat <&3
        ) <(
            printf '%s\n' "$line2"
            cat
        )
    }
    exec 3<&-
}
```

```shell-session:how-to-use
$ nice-join.sh 1.csv 2.csv
hoge,100,Adam
fuga,200,Bill
moge,,Charlie
piyo,300,
```
rubyの代入演算子 ||

github上の他人のコードを見ていると 『a = || b』や『a = || b』といったコードが割と頻繁に出てきて、出てくるたびに調べるけどすぐ忘れるといったことが何回か続いたので忘れないようにメモしておこうと思う。

『a = a || b』の場合、『a = a || b』が実行されるたびに変数 a に値が格納される。
他方、『a ||= b』は、a が nil か false の場合だけ、変数 a に値が格納される。

    #下記の二行はほぼ同じ振る舞い
    a ||= 100
    a || a = 100