OmniAICreator/Qiita-1.07M huggingface dataset:
【Minecraft PE】ModPE Scriptsを使ったModの作り方をまとめてみた（１）〜Hello World編〜

Minecraft PEはModPE Scriptsというツールを使ってJavascriptでMod開発ができるらしいので試してみた。
が、思いのほか作り方がちゃんとまとまっているページがなかったりハマりポイントが多かったりしたので、自分で作ってみた結果を踏まえてのまとめです。

# 前提
- **Minecraftって？**
    - オープンワールドの積み木ゲームです。詳しくはダウンロードしてみてください。PC版、スマートフォン版、PS Vita版、PS3版等があります。今回はスマートフォン版（特にAndroid）が対象です。
- **Modって**
    - すでにあるゲームに対してサードパーティの開発者が作る追加プログラムのようなものです。PCゲームではよくある仕組みです（と思います。PCゲームやらないのでよく分からない）

# 環境
- **Minecraft PE (Android版) ver0.12.1**
    - Minecraft本体アプリ
    - ダウンロードは[こちら](https://play.google.com/store/apps/details?id=com.mojang.minecraftpe&hl=ja)
- **BlockLauncher Pro ver1.10.3**
    - ModPE Scriptを読み込んだ状態でMinecraftを起動することができるアプリ。（それだけではないですが）
    - ダウンロードは[こちら](https://play.google.com/store/apps/details?id=net.zhuoweizhang.mcpelauncher.pro&hl=ja)
- **ModPE IDE ver4.6.73**
    - ModPE Scriptの開発環境。といってもただのエディタにModPE Script用の関数一覧表がついたようなシンプルなアプリ。
    - とはいえスマートフォンでのコーディングはツラいので、実際はPCでコーディング→メッセンジャー等でスマートフォンにコードを送信→ModPE IDEにコピペ の手順でコーディングしていました。
    - 最終的にソースコードが書かれたUTF-8の.jsファイルが端末内の任意のディレクトリにあれば良いので、このアプリ必須ではありません。
    - ダウンロードは[こちら](https://play.google.com/store/apps/details?id=com.KillerBLS.modpeide&hl=ja)

# 参考
- [Script modの作り方](http://wiki.mcpe.jp/d/Script%20mod%A4%CE%BA%EE%A4%EA%CA%FD)（非エンジニア向け）
- [Mod Script Wiki](https://github.com/Connor4898/ModPE-Docs/wiki)
- 勉強用に作成したMod[「旅の扉Mod」](https://github.com/chooyan/modpe/blob/master/warpdoor.js)のソースコード

# コーディング
ModPE Scriptは上記[Mod Script Wiki](https://github.com/Connor4898/ModPE-Docs/wiki)に記載されているHooks関数をエントリポイントとして実行されます。

今回は簡単なHello Worldです。
ゲーム開始と同時に"Hello ModPE Script World!!"を画面上に表示します。

```js:hello.js
// ゲーム開始と同時に発火するイベント
function newLevel(hasLevel) {
  // 画面左上に文言を出力する
  clientMessage("Hello ModPE Script World!!");
}
```

これを以下の手順で実行します。
- "hello.js"としてAndroid端末内の任意のディレクトリに保存
- BlockLauncherアプリを起動 **(注：Minecraftアプリではない）**
- 画面上部のレンチアイコンをタップ
- "Manage ModPE Scripts"を選択
- 右上のトグルボタンをタップしてスクリプトを有効にする
- "IMPORT" > "Local storage" を選択し、表示されるエクスプローラでhello.jsを選択する。
- BlockLauncherのスタート画面まで戻り、「プレイ」からゲームを開始する
- ゲーム開始と同時に"Hello ModPE Script World!!"が表示される

あとは通常のJavascriptプログラムを書く要領で、Mod Script WikiのAPI一覧を頼りにコーディングを進め、同様の手順で動作確認します。
が、Wikiの情報が不完全だったり用語が直感的でなかったりと数多くの罠が仕掛けられていますので、そのあたりは次回以降でまとめようと思います。


先にざっくりまとめてみると以下のような感じ。。。

- 戻り値の型が分からない、引数の型が分からない。型が分かっても何を意味する値なのかがよく分からない。
- 何が起こる関数なのかよくが分からない
- なんかgetPlayerX()で取得した座標を他のAPIに渡すと座標がズレる
- そもそもブロックIDの一覧とかまとまってない

などなど。
自分の場合はとにかく関数を使ってみてclientMessage()とかで出力してみて、と試行錯誤しながらコーディングを進めました。
いったいいくつのワールドを作っては消したことか。。。

うまくいくとクリーパーに乗ったりサバイバルで空飛んだりワープできたりで面白いんですけどね。
Swiftの中間言語を出力して読む方法

https://speakerdeck.com/matuyuji/swiftzhong-jian-yan-yu-wodu-mu
この資料によると、Swiftは

1. .swift
2. Swift AST
3. SIL
4. LLVM IR
5. LLVM BC
6. Native asm
7. Native binary

と辿っていくらしいです。どうやれば各段階のコードを得られるかというお話。

----

# .swift

今回は.swift単品が対象。適当に

```swift:hello.swift
print("hello, world!")
```

とか書いておく。

# Swift AST

```bash
swiftc -dump-ast hello.swift
```

いきなり長いものが出るが、
```print``` と ```()``` があって、括弧の中には ```"hello, world!"``` がある……
というのがちゃんと読める。

# SIL

```bash
swiftc -emit-silgen hello.swift > hello.sil
```

```swiftc -emit-silgen``` は結果を標準出力してくるので適当なファイルに書かせておく。
できたhello.silは

```bash
swiftc -parse-sil hello.sil
./hello
```

といった感じで実行するとこまで進められる。

# LLVM IR

```bash
swiftc -emit-ir hello.swift > hello.ll
```

この辺りはまだ人間の目で読める。

# LLVM BC

読めない。

```bash
swiftc -emit-bc hello.swift > hello.bc
```

## LLVM周りの話

### LLVMインストール

Mac(Xcode?どっちだろう)にはこの手のものが最初から入っているらしいが、LLVMをフルで使うには足りないので、今後LLVMで遊ぶ予定がある場合は

```bash
brew install llvm
```

とか

```zsh:.hogerc
export PATH=$PATH:/usr/local/opt/llvm/bin
```

とかしておく。

### IRからBCへ

↑で ```llvm-as``` というのが使えるようになっているはずなので、そいつでhello.llからhello.bcをつくる。

```bash
llvm-as hello.ll
```

### .bcの実行

ちゃんとした.bcなら

```bash
lli hello.bc
```

で実行できるはずなのだが、

```txt
LLVM ERROR: Program used external function '_swift_once' which could not be resolved!
```

と怒られてしまう。多分なんか方法あるんだろうけど面倒くさいので省略。

# Native asm

読める。

```bash
swiftc -emit-asm hello.swift > hello.s
```

## LLVM BCからアセンブリへ

```bash
llc hello.bc
```

でhello.sが増える。↑とはちょっと違うけどだいたい似たようなことが書いてあるような気がする。

# Native binary

できあがり

```bash
swiftc hello.swift
./hello
```

hello.sをgccに渡したらlswiftCoreがないって言われた(lswiftCore.dylibのことかな)。
Terraformで管理している環境にCodeDeployでアプリをデプロイするときに使ってるコマンド

※terraformとaws-cliが必要です

```bash
#!/bin/bash

APP=myapp
BRANCH=master
DEPLOYMENT_GROUP=$(terraform output 'asg_name')
COMMIT_ID=$(git ls-remote git@github.com:$GITHUB_REPO refs/heads/$BRANCH | awk '{ print $1 }’)

aws deploy create-deployment --application-name $APP \
  --deployment-group $DEPLOYMENT_GROUP \
  --github-location commitId=$COMMIT_ID,repository=$GITHUB_REPO
```
windowsでvagrant & dockerそしてproxy対応してCoreOsからCentOS7コンテナに接続

## 目的
windowsでcygwinからcoreosを起動してそこから開発用の仮想環境を構築する。
あくまでも個人用である。
試してないけどmacでも同じように動く気はする。

### 前提
- 64bitマシンであること
- cygwinはインストールされていること。
- 他にもgitやopenssh等使えること。


## virtualboxのインストール

以下からバイナリDLしてインストール

https://www.virtualbox.org/

### ハマりどころ

BIOSの設定で仮想化機能を有効になってることを確認する。
これは「vagrant up」で起動起動できない時にgui起動するとエラーメッセージが表示されるのでわかる。

## vagrantのインストール

以下からバイナリDLしてインストール

https://www.vagrantup.com/

### プラグインのインストール

vagrant-winnfsd プラグインのインストール

```bash
vagrant plugin install vagrant-winnfsd
```

参考：http://qiita.com/RichardImaokaJP/items/c612a5a19eeb4f341519

vagrant-vbguest プラグインのインストール

```
vagrant plugin install vagrant-vbguest
```

参考：http://weblabo.oscasierra.net/vagrant-vbguest-plugin-1/

vagrant-proxyconf　 プラグインのインストール

※proxyな環境な場合のみ

```
vagrant plugin install vagrant-proxyconf
```

参考：http://qiita.com/shouta-dev/items/7b8a462504f7d6c91e99

### コマンドメモ

```
# boxの一覧
vagrant box list

# boxの削除
vagrant box remove BOX_NAME

# 起動
vagrunt up

# 停止
vagrunt halt
```

## vagrantでcoreosを立ち上げる

### coreosのvagrantfileを持ってくる

注意）ホームディレクトリにvagrantディレクトリを作成して実行

```
# ホームディレクトリに移動
cd

# 作業フォルダの作成（名前はなんでも良い）
mkdir vagrant

# 作業フォルダに移動
cd vagrunt

# 以下は共有フォルダの設定とproxyの設定をいれたバージョン。
# 必要なければfork元から取得してください。 https://github.com/coreos/coreos-vagrant
git clone https://github.com/astrsk-hori/coreos-vagrant.git

# 上記を実行すると`coreos-vagrant`というディレクトリが作成されている。
```

### vagrant起動

```
# 先程gitでcloneしたディレクトリに移動。
cd coreos-vagrant

pwd

# 以下のような感じになるはず
# /home/HOGE/vagrant/coreos-vagrant
# このディレクトリの２つ上の階層（/home/HOGE）が共有ディレクトリになります。

# 起動
vagrant up
```

これで起動します。最初のみ時間がかかります。
※起動しない場合はエラーメッセージでググったり、guiをtrueにして起動するとエラーがわかりやすいかも。

### 仮想環境にログイン

```
vagrant ssh
```

上記コマンドでcoreosにログインできます。
またホームディレクトリの`share`ディレクトリがPCのホームディレクトリとリンクしてます。


### Proxy環境の場合
予め環境変数にセットされてれば今回使用してるVagrantfileで読み込まれます。

こんな感じ
`http_proxy=http://xxx.xxx.xxx.xxx:8080`
`https_proxy=http://xxx.xxx.xxx.xxx:8080`

詳細は`Vagrantfile`を見てください。

#### vagrant-proxyconfを使わない場合

参考　coreosでproxy
http://qiita.com/kawasima/items/6cdb79913b5dfffd1a31

### coreosの環境整備
`.bashrc`を変更しようと思ったらシンボリックリンクでしかも読み込み専用になってるのでシンボリックリンクを削除して元の`.bashrc`をコピーして変更すると良い。
dockerコマンドとか打つくらいだと思うのでaliasさえ設定できれば良い気がする。

## dockerでcentos7を起動する(2015/09/29時点)。

```
docker pull centos
docker run --privileged --name myCentos7 -v /home/core:/share_dir -d centos /sbin/init
```

centosコンテナに接続するには`docker exec -it 6ba5c277ddbe /bin/bash`でできる。
`--privileged`を指定した場合は「docker attach」では接続できない。
ちなみにコンテナID(6ba5c277ddbe)は`docker ps`で確認できます。

`-v`オプションでホストとゲストのディレクトリをマウントできる。
ここではcoreosのホームディレクトリをcentosの`/share_dir`にマウントしてる。

今回の記事の通りに作成してればPCのホームディレクトリにも`/share_dir`からアクセスできる。

とりあえず今回はここまで。
Cの構造体を、C#の構造体にマーシャリングしたらメンバの値が正しくなかった

# やりたいこと

こんなC++の構造体を

```c
struct example {
    int a;
    bool b;
    bool c;
    int d;
    int e;
}:
```

この構造体にマーシャリングしたい。

```csharp
[StructLayout(LayoutKind.Sequential)]
struct ExampleCS
{
    public int a;
    public bool b;
    public bool c;
    public int d;
    public int e;
}
```

# 問題
C#側で受け取った時に、なんか、値が変わる。困る。

# 対処
こんな風にした。

```csharp
[StructLayout(LayoutKind.Sequential)]
struct ExampleCS
{
    public int a;
    [MarshalAs(UnmanagedType.I1)]
    public bool b;
    [MarshalAs(UnmanagedType.I1)]
    public bool c;
    public int d;
    public int e;
}
```

要は、C#側でboolとして受け取りたいメンバが、ネイティブ側で何バイトなのかを指定しましょう、ということ。

マーシャリング時、C#構造体におけるboolは、ネイティブ（C/C++）側の構造体においてデフォルトでは
（おそらく）4バイトを想定しているんでしょうね。

boolじゃなくてBOOLなんでしょう。

# 蛇足

そもそもboolのサイズは規定されていない（と思う）ので、
UnmanagedTypeの値は、ネイティブ側の実装に合わせましょう。

考えてみれば当たり前だけど、結構ハマる。
Javaとシェルスクリプトの論理演算子・比較演算子を対比

## 数値の比較演算
| Java   | シェルスクリプト   | 備考 |
|:------:|:----------------:|:--------|
| a == b | a -eq b          |  EQuals  <br>シェスルクリプトで``=``と書くと文字列による比較になるので注意|
| a != b | a -ne b          | Not Equals <br>シェスルクリプトで``!=``と書くと文字列による比較になるので注意 |
| a > b  | a -gt b          | Greater Than |
| a < b  | a -lt b          | Less Than |
| a >= b | a -ge b          | Greater or Equals |
| a <= b | a -le b          | Less or Equals |

## 文字列の比較演算
| Java                            | シェルスクリプト  | 備考        |
|:-------------------------------:|:----------------:|:-----------|
| a.equals(b)                     | a = b            |  ==ではない |
| !a.equals(b)                    | a != b           |            |
| a.isEmpty() <br>a.length() == 0 | -z a             |            |
| !a.isEmpty() <br>a.length() > 0 | -n a             |            |

## 論理演算
| Java   | シェルスクリプト   | 備考 |
|:------:|:----------------:|:----------------------------|
| !a     | ![a]             | [!条件]ではなく![条件]        |
| a && b | [a] && [b]       | [条件1 && 条件2]ではなく[条件1] && [条件2]と記述する |
| a &#124;&#124; b | [a] &#124;&#124; [b]       | [条件1 &#124;&#124; 条件2]ではなく[条件1] &#124;&#124; [条件2]と記述する |
| a & b  | [a] -a [b]       |
| a &#124; b  | [a] -o [b]       | |
【PHP】UTCタイムスタンプを強制的にJST（日本時刻）表示する方法

APIからUnix,UTCで時刻取得する機会があったのですがどうやってもJSTに変換できなかったので成功例の記録。
（特にレンタル）サーバーの設定によらず正しい時刻を表示する方法を紹介します。

Apache2.0 PHP5.6.10で動作確認

#目標の動作
例として`$utc = 1443576433`を使用。
`echo date('Y/m/d H:i', $utc);`とすると
2015/09/30 03:27
と出力されました。これをJST変換して
2015/09/30 10:27
となることを目指します。

##注意：サーバーの問題点
PHPを触ったことある方、UTCに詳しい方ならすぐ異変に気づくはずです。
（時差が9時間でない）
調べてところApacheのTimeZoneが**Europe/Berlin**でした。
初期設定が変だったのでしょう。

#解決策
DateTimeクラスを使います。

```php:success.php
<?php
$time = new DateTime();
$time->setTimestamp($utc)->setTimezone(new DateTimeZone('Asia/Tokyo'));
echo $time->format('Y/m/d H;i');
```
DateTimeZoneクラスで目的のタイムゾーンを作り、setTimeZoneの引数にします。
Redmine3.0.0 新機能の紹介(No.4)

#Redmine3.0.0 新機能の紹介(No.4)

2015年2月19日にリリースされた「Redmine3.0.0」バージョンの新機能は全部で33種ありますが、本書ではその代表的な16種の新機能をご紹介します。

##13.「フィルタ追加」のプルダウンの内容を階層表示機能

以前のバージョンでは、「チケット」ページの「フィルタ追加」のプルダウンの内容が全て並列的に列挙されていましたが、3.0.0バージョンからは階層表示され、項目がグループごとにまとめて表示されるようになりました。これにより、目的の項目を簡単に探せるようになりました。


![13.png](https://qiita-image-store.s3.amazonaws.com/0/94912/f12a8d82-01dc-d5fd-0f85-fddc67ffe908.png)


##14.「長いテキスト」書式のフィールド変更時、diff形式で表示

以前のバージョンでは、「長いテキスト」書式のカスタムフィールドが変更された場合、diff形式で表示をすることができませんでしたが、3.0.0バージョンからはdiff形式で表示することが可能になりました。
更新履歴で、「diff」をクリックすると、diff形式で変更箇所が表示されます。


![2.png](https://qiita-image-store.s3.amazonaws.com/0/94912/fcbc47fc-50b1-8eb1-5498-9040abfbc91f.png)![14.png](https://qiita-image-store.s3.amazonaws.com/0/94912/c101fe9c-9e71-fac4-c02b-1e5027a25145.png)


##15.チケットをコピー時、履歴に自動で関連チケットを登録

以前のバージョンになかった、「管理」->「設定」->「チケットトラッキング」->「チケットをコピーしたときに関連を設定」項目が、3.0.0バージョンから追加されました。
チケットをコピーすると、「コピーしたチケットに関連を設定」項目が追加され、チェックをオンにすると、コピーしたチケットに「コピー元」の関連チケット情報が自動で登録されます。


![15.png](https://qiita-image-store.s3.amazonaws.com/0/94912/c6cce495-2b4a-a365-7fc4-b186b99502b1.png)


##16.トラッカーが登録されていない場合、「新しいチケット」項目を非表示

以前のバージョンでは、プロジェクトにトラッカーが設定されていない場合に、「新しいチケット」項目をクリックすると、「このプロジェクトにはトラッカーが登録されていません。プロジェクト設定を確認してください。」と表示されましたが、3.0.0バージョンからは、「新しいチケット」項目自体が表示されなくなりました。


![16.png](https://qiita-image-store.s3.amazonaws.com/0/94912/0009d74a-a288-4c65-8cd8-453ebc36b973.png)


（この資料は [「Ankosoft」](http://www.ankosoft.co.jp/) 社の[「Redmine3.0.0 新機能のご紹介」](http://www.ankosoft.co.jp/wp-content/uploads/2015/04/Redmine3.0.0.%E6%96%B0%E6%A9%9F%E8%83%BD%E3%82%AC%E3%82%A4%E3%83%89-Ankosoft.pdf)より引用して作成しました。）
Windows 2008 ServerのSoftLayer仮想サーバーから物理サーバー上ののHyper-Vに引越し

　今回はSoftlayerの仮想サーバー(VSI)で稼動しているWindows 2008 (Windows Server 2008 R2 Enterprise)をWindows Server 2012 R2搭載物理サーバー上にHyper-Vを稼動しその上の仮想マシーンに移行してみました。

![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/59741/3f6405f1-b0dc-0ce9-1952-ce503861f803.jpeg)

手順としては
1)	仮想サーバーをテンプレートイメージに保存（SoftLayerポータルから）
2) イメージテンプレートをVHDにエクスポート（同じくポータルから）
　　（この作業をするのにObject Storageが必要になります、Object Storageのオーダーに関してはこちらを参照ください
　http://gg-web.jp/document/ConfigGuide/05001/index.html
3) 物理サーバーをWindows 2012R2でオーダー
4) 物理サーバーにobject storageのファイルをダウンロード
5) Hyper-Vマネージャーで仮想マシーンを作成、VHDファイルを読み込む
6) 仮想マシーンのネットワーク設定を行う（SoftLayerのPortable IP addressが必要になります）
7) ライセンス認証を行う。

では詳しく紹介します。

1仮想サーバーをテンプレートイメージに保存（SoftLayerポータルから）
 ポータルサイトでメインメニューからDevice device Listで対象のサーバーをクリックし、次に右側のActionからCreate Image Templateを選びます。
![2.jpg](https://qiita-image-store.s3.amazonaws.com/0/59741/8ab8751c-2cc0-0870-92ec-0b45b92f82d8.jpeg)
　次に画面でTemplate Imageの名前をつけて保存します。

2 イメージテンプレートをVHDにエクスポート（同じくポータルから）

　メインメニューから　Device  Manage  Imageで先ほど保存したTemplate Imageを選択してください。
![3.jpg](https://qiita-image-store.s3.amazonaws.com/0/59741/5f492fbc-cd2a-d2ea-3b75-245cf37b15d0.jpeg)

次にObject Storageのどこに保存するかを入力します。
![4.jpg](https://qiita-image-store.s3.amazonaws.com/0/59741/e66ea70d-2f8e-0abd-7851-efd7a7b212e3.jpeg)

　Object Storageのリストで上記のファイルを確認します。***.vhdというファイル名になってます。

3 物理サーバーをWindows 2012R2でオーダー
　こちらを参考に物理サーバーをオーダー。今回は以下のスペックでした。
　　データセンター：東京
　　CPU： 3.5GHz Intel Xeon-Haswell (E3-1270-V3-Quadcore)
    メモリー：8GB
    OS: Windows server 2012 R2 (64)
　　Storage: SATA 1TB
  サーバーが出来上がった後にサーバーマネージャーでHyper-Vを有効にしました。

4 物理サーバーにobject storageのファイルをダウンロード
　ダウンロードするためにPythonとGitのインストールが必要になります。こちら
https://github.com/takara9/os_tools
を参考に設定をしてして以下のコマンドを使用して物理サーバーにObject Storageのvhdファイルをダウンロードしてください。
 >python os_download.py コンテナ名　VHD名　ダウンロード後のファイル名

5 Hyper-Vマネージャーで仮想マシーンを作成、VHDファイルを読み込む
　Hyper-Vマネージャーを立ち上げて新しいVMを作成しましょう。
![5.jpg](https://qiita-image-store.s3.amazonaws.com/0/59741/840e0ad1-c9e7-5fbf-54bf-a08ed1b009c9.jpeg)

Virtual Hard Diskのところで先ほどダウンロードしたVHDファイルを指定してください。

![6.jpg](https://qiita-image-store.s3.amazonaws.com/0/59741/f987b189-6a2e-26ae-2403-20d0a90f756a.jpeg)

そのまま続けて仮想マシーンを起動するとWindows 2008が無事立ち上がります。(WindowsはSoftLayerの仮想サーバーにあるときに日本語化しておきました）

![7.jpg](https://qiita-image-store.s3.amazonaws.com/0/59741/8e415790-063c-f5bd-5928-118e6b8e32d8.jpeg)

6 仮想マシーンのネットワーク設定を行う（SoftLayerのPortable IP addressが必要になります）
　Hyper-Vマネージャーで仮想スイッチを追加してこちらを参考にネットワークの設定をしました。

http://qiita.com/osonoi/items/26cb69adf58f1f79f49b

7 ライセンス認証を行う。

　最後にライセンスの認証を行います。上記の画面の下のほうにある“今すぐ行う場合はここをクリックしてください”をクリックして認証を行ってください。（ライセンスキーが必要になります）

![8.jpg](https://qiita-image-store.s3.amazonaws.com/0/59741/0a6b1d4d-0b54-0496-4b52-5ad27e68929a.jpeg)
Redmine3.0.0 新機能の紹介(No.3)

#Redmine3.0.0 新機能の紹介(No.3)

2015年2月19日にリリースされた「Redmine3.0.0」バージョンの新機能は全部で33種ありますが、本書ではその代表的な16種の新機能をご紹介します。

##9.トラッカー毎に「デフォルトのステータス」を指定する機能

以前のバージョンでは、トラッカー設定時に、デフォルトのステータスを設定できませんでしたが、3.0.0バージョンから、「デフォルトのステータス」を設定できるようになりました。


![9.png](https://qiita-image-store.s3.amazonaws.com/0/94912/52a87a38-20c6-e53f-00c5-8331c068da86.png)


##10.「新しいカスタムフィールドを作成」で「文書」項目が追加

以前のバージョンでは、「管理」->「カスタムフィールド」->「新しいカスタムフィールドを作成」欄に「文書」項目がありませんでしたが、3.0.0バージョンから「文書」項目が追加されました。これにより「文書」ページにカスタムフィールドを作成することが可能です。


![10.png](https://qiita-image-store.s3.amazonaws.com/0/94912/0a418f63-fe66-335b-0666-c2feb117e622.png)


##11.「ユーザー」、「グループ」を複数のプロジェクトに追加可能 

以前のバージョンでは、「ユーザー」、「グループ」をプルダウン方式で、一度に一つのプロジェクトにしか登録できませんでしたが、3.0.0バージョンからチェックボックス方式に変更され、複数のプロジェクトに同時に登録ができるようになりました。


![11.png](https://qiita-image-store.s3.amazonaws.com/0/94912/f60e5e69-3976-4347-c23f-6eedc643a54d.png)


##12.プロジェクトのメンバー以外の名前を非表示にする機能

以前のバージョンでは、「新しいチケット」などで、「チケットのウォッチャー」の「ウォッチャーを検索して追加」をクリックすると、Redmineに登録されている全てのメンバーの名前が表示されました。3.0.0バージョンからはプロジェクトに所属しているメンバー以外の名前が表示されないようになりました。
下図の例示のように、「A社Web通販システム」には、二人のメンバーが所属しているので候補者として名前が表示されていますが、「B社Web通販システム」にはメンバーが所属していないので、「A社Web通販システム」に所属しているメンバー名が表示されません。


![12.png](https://qiita-image-store.s3.amazonaws.com/0/94912/7acbf075-0907-469f-01e9-d56f797976bd.png)


（この資料は [「Ankosoft」](http://www.ankosoft.co.jp/) 社の[「Redmine3.0.0 新機能のご紹介」](http://www.ankosoft.co.jp/wp-content/uploads/2015/04/Redmine3.0.0.%E6%96%B0%E6%A9%9F%E8%83%BD%E3%82%AC%E3%82%A4%E3%83%89-Ankosoft.pdf)より引用して作成しました。）
Redmine3.0.0 新機能の紹介(No.2)

#Redmine3.0.0 新機能の紹介(No.2)

2015年2月19日にリリースされた「Redmine3.0.0」バージョンの新機能は全部で33種ありますが、本書ではその代表的な16種の新機能をご紹介します。

##5.Wikiのヘルプページに「階層化されたリスト」の記述例が追加 

以前のバージョンのWikiのヘルプページになかった「階層化されたリスト」の記述例が3.0.0バージョンに追加されました。


![5.png](https://qiita-image-store.s3.amazonaws.com/0/94912/46d08427-6797-8478-8d25-40f570e9167f.png)


##6.Wikiのヘルプページに「テーブル」についての記述例が追加 

以前のバージョンのWikiのヘルプページになかった「テーブル」の記述例が3.0.0バージョンに追加されました。


![6.png](https://qiita-image-store.s3.amazonaws.com/0/94912/dc13f646-fe67-ba08-b28b-8e0f0407c4f1.png)


##7.Wiki記法ページに「ニュースとフォーラム」についての記述例が追加 

以前のバージョンのWiki記法ページになかった「ニュースとフォーラム」の記述例が3.0.0バージョンに追加されました。


![7.png](https://qiita-image-store.s3.amazonaws.com/0/94912/450131fc-728b-c8bf-6ad9-16390750d0fd.png)


##8.Wikiページを別のプロジェクトにコピーする機能

以前のバージョンでは、Wikiページを他のプロジェクトに移動させることができませんでしたが、3.0.0バージョンから、Wikiページを他のプロジェクトに移動させることができるようになりました。
Wikiページで、「名前変更」ボタンをクリックすると、以前のバージョンでは「タイトル」、「既存のリンクをリダイレクトする」、「親ページ」の３つの項目がありましたが、3.0.0バージョンでは、「プロジェクト」という項目が追加されました。
「プロジェクト」項目で選択した任意のプロジェクトに、現在のWikiをコピーすることができます。


![8.png](https://qiita-image-store.s3.amazonaws.com/0/94912/cb91518c-55c5-b7a2-41d9-80c4dcd27bd3.png)


（この資料は [「Ankosoft」](http://www.ankosoft.co.jp/) 社の[「Redmine3.0.0 新機能のご紹介」](http://www.ankosoft.co.jp/wp-content/uploads/2015/04/Redmine3.0.0.%E6%96%B0%E6%A9%9F%E8%83%BD%E3%82%AC%E3%82%A4%E3%83%89-Ankosoft.pdf)より引用して作成しました。）
Redmine3.0.0 新機能の紹介(No.1)

#Redmine3.0.0 新機能の紹介(No.1)

2015年2月19日にリリースされた「Redmine3.0.0」バージョンの新機能は全部で33種ありますが、本書ではその代表的な16種の新機能をご紹介します。

##1.検索で「オプション」の追加-「未完了のチケットのみ」を検索可能

以前のバージョン※１では、検索ページに「オプション」項目がありませんでしたが、3.0.0バージョンから、オプション項目が追加され、「未完了のチケットのみ」が選択可能になりました。これにより、未完了のチケットのみ検索対象にすることが可能です。
※１：本書で使用する「以前のバージョン」は「2.4.6.stable」バージョンで確認しました。

![1.png](https://qiita-image-store.s3.amazonaws.com/0/94912/e8b788d5-d466-54c7-b435-137e7bcb67a0.png)

##2.検索で「オプション」の追加-「添付ファイルの名前と説明も検索」機能

以前のバージョンでは、検索ページに「オプション」項目がありませんでしたが、3.0.0バージョンから、オプション項目が追加され、「添付ファイルの名前と説明も検索」を選択できるようになりました。これにより、添付ファイルの名前や説明も検索対象にすることが可能です。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/94912/fcbc47fc-50b1-8eb1-5498-9040abfbc91f.png)

##3.添付ファイルをアップロード後に、添付ファイルの説明項目が編集可能

以前のバージョンでは、添付ファイルを登録する時に、「任意のコメント」を記載することができましたが、一度登録した「任意のコメント」は編集することができませんでした。

![3.png](https://qiita-image-store.s3.amazonaws.com/0/94912/65c14a67-467b-d1e5-9de5-277501e0fb27.png)

##4.ユーザーに複数のメールアドレスを登録可能

以前のバージョンでは、一人のユーザーに対してメールアドレスを一つしか登録できませんでしたが、3.0.0バージョンから、複数のメールアドレスを登録できるようになりました。
ユーザー登録画面で「メールアドレス」というアイコンが追加されました。これをクリックすると、追加のアドレスを登録できる「メールアドレス」というポップアップウィンドウが表示されます。
「追加」ボタンをクリックすることでメールアドレスを追加でき、追加できるメールアドレス数に制限はありません。

![4.png](https://qiita-image-store.s3.amazonaws.com/0/94912/c56bed37-1017-f6db-b938-6cb0199fa683.png)

（この資料は [「Ankosoft」](http://www.ankosoft.co.jp/) 社の[「Redmine3.0.0 新機能のご紹介」](http://www.ankosoft.co.jp/wp-content/uploads/2015/04/Redmine3.0.0.%E6%96%B0%E6%A9%9F%E8%83%BD%E3%82%AC%E3%82%A4%E3%83%89-Ankosoft.pdf)より引用して作成しました。）
DataPipelineでEC2インスタンスのバックアップと停止してみた

開発サーバーとして利用している、EC2インスタンスのバックアップと日々の停止処理をDataPipelineを利用して行ってみました。

DataPipelineの使い方としては、<a href="http://qiita.com/imaifactory/items/6dc16820c4bec67a7d05" target="_blank">こちらの記事</a>のようにシェルスクリプトのスケジューラとして利用しただけです。

DataPipelineの設定としては、ActivityにShellCommandActivityを選択し、ResourceにはEC2インスタンスを自VPCで起動するようにします。

ActivityのCommand欄に下記のシェルスクリプトを設定します。

```
#!/bin/sh

backup(){
    type=$1
    ami_name=$2

    # 指定タグの起動中のインスタンスIDを取得
    InstanceId=`aws ec2 describe-instances --region ap-northeast-1 --filters "Name=tag:type,Values=${type}" "Name=instance-state-name,Values=running" | grep InstanceId | awk -F : '{print $2}' | sed -e 's/[ ",]//g' | sed -n '1p'`

    if [ ${InstanceId} ];then
        # 前日分のami_id取得
        OldImageId=`aws ec2 describe-images --region ap-northeast-1 --filters Name=tag:type,Values=${type} | grep ImageId | awk -F : '{print $2}' | sed -e 's/[ ",]//g' | sed -n '1p'`
        # 前日分のsnapshot_id取得
        OldSnapshotId=`aws ec2 describe-images --region ap-northeast-1 --filters Name=tag:type,Values=${type} | grep SnapshotId | awk -F : '{print $2}' | sed -e 's/[ ",]//g' | sed -n '1p'`
        # 前日分のami削除
        if [ ${OldImageId} ];then
            aws ec2 deregister-image --region ap-northeast-1 --image-id ${OldImageId}
        fi
        # 前日分のsnapshot削除
        if [ ${OldSnapshotId} ];then
            aws ec2 delete-snapshot --region ap-northeast-1 --snapshot-id ${OldSnapshotId}
        fi

        # ami作成
        today=`date '+%Y%m%d%H%M%S'`
        CurrentImageId=`aws ec2 create-image --region ap-northeast-1 --instance-id ${InstanceId} --name "${ami_name}-${today}" --no-reboot | grep ImageId | awk -F : '{print $2}' | sed -e 's/[ "]//g'`
        if [ ${CurrentImageId} ];then
            # amiにタグつけ
            aws ec2 create-tags --region ap-northeast-1 --resources ${CurrentImageId} --tags Key=type,Value=${type}
        fi
    fi
}

stop_instance(){
    type=$1

    # 指定タグの起動中のインスタンスIDを取得
    InstanceId=`aws ec2 describe-instances --region ap-northeast-1 --filters "Name=tag:type,Values=${type}" "Name=instance-state-name,Values=running" | grep InstanceId | awk -F : '{print $2}' | sed -e 's/[ ",]//g' | sed -n '1p'`

    if [ ${InstanceId} ];then
        # インスタンス停止
        stop=`aws ec2 stop-instances --region ap-northeast-1 --instance-ids ${InstanceId}`
    fi
}

# ec2 backup
backup [ec2_tag] [ami_name]
stop_instance [ec2_tag]
```
シェル末尾のec2_tagとami_nameを置き換えると、起動中のインスタンスのamiを取り、そのインスタンスを停止します。

操作したいインスタンスには、あらかじめtypeというタグにec2_tagと同じ名前のタグ名をつけておきます。
ami_nameは作成するamiのprefixになり、末尾に日時文字列がくっつきます。

読みにくいコードでごめんなさい。
あと本当はインスタンス止めてからamiとったほうがいいと思うので、そのうちなおすかも。
ASP.NET MVC プロジェクトで参照設定がおかしくなったときの対処

# ASP.NET MVC プロジェクトで参照設定がおかしくなったときの対処


## 問題

プロジェクトを開く、またはビルドするとエラーが発生し、プロジェクトの [参照] ツリーを表示すると異常を示し、ビルドできなくなって困ったときの対処を記録する。

**破壊的な操作を含むので、事前にバックアップを取った方がよいだろう。**  


## 対処

1. **対処1**  パッケージ マネージャーを開き、[復元] ボタンが表示されていればクリックする。これで解決すれば完了。解決しない場合は以降を試す。
2. [復元] ボタンが表示されない、もしくは復元してもダメな場合は、下の設定を確認し、一度 Visual Studio を閉じる。

3. **対処2**  エクスプローラーでプロジェクトフォルダの直下にある `packages` のすべての **フォルダ** を削除する。このとき、フォルダに `repositories.config` などのファイルがある場合は、削除しない。

4. Visual Studio で、当該プロジェクトを開く。
5. ビルドすると自動的に必要なパッケージがダウンロードされた。

## Visual Studio の設定

Visual Studio 2015 では、デフォルトで次のように設定されているようなので、単に確認になるが。

1. メニュー [ツール] のノード [NuGet パッケージ マネージャー] をクリックする。
2. [パッケージの復元] 項目で、[見つからないパッケージのダウンロードを NuGet に許可] と [Visual Studio でのビルド中に見つからないパッケージを自動的に確認] 項目がチェック状態にしておくとビルド時に不足するパッケージがある場合は自動的に取得してくれる。


##### 確認した環境
- 日本語 Windows 10 Pro 64ビット
- Visual Studio Community 2015
- ASP.NET MVC 5
geminaboxでgemをカジュアルに消せないようにする

おれのgemサーバを立てる際に便利な、[geminabox/geminabox](https://github.com/geminabox/geminabox)ですが

![スクリーンショット 2015-09-30 10.38.00.png](https://qiita-image-store.s3.amazonaws.com/0/1172/a115a5b9-1fb6-efa2-522e-f1287e426989.png)

WEB UIに`delete`ボタンがあって、カジュアルに`gem`が削除できてしまい。うぉーい！と思っていたんですがよく見たら[設定がありました](https://github.com/geminabox/geminabox/blob/master/lib/geminabox.rb#L79)。

[このあたりでmergeされた](https://github.com/geminabox/geminabox/pull/117)みたいですね。

```config.ru
require "rubygems"
require "geminabox"

Geminabox.allow_delete = false
run Geminabox::Server
```

こんな感じで設定して立ち上げると、削除しようとしても

```
Gem deletion is disabled - see https://github.com/cwninja/geminabox/issues/115
```

と出て、消せなくなります。めでたい。
[Unity] 当たり判定のある線を引く　〜超簡易版〜

Game画面をなぞると**線が引けて**、かつそれに**当たり判定を付けたい**場合、簡易的なものをサラッと実装できる方法をまとめておきます。

色々と粗が目立ちますが大目にみてください。。
超簡易版なので。。


##事前準備
1. 空のオブジェクトを作っておきます。これに後述のスクリプトを追加します。
2. Cubeを作り、Prefab化しておきます。パラメータなどは何も変えなくていいです。

##スクリプト
```csharp:drawPhysicsLine
using UnityEngine;
using System.Collections;

public class drawPhysicsLine : MonoBehaviour
{
	
	public GameObject linePrefab;
	public float lineLength = 0.2f;
	public float lineWidth = 0.1f;
	
	private Vector3 touchPos;
	
	void Start(){
		
	}
	
	void Update (){
	    drawLine ();
	}
	
	void drawLine(){
		
		if(Input.GetMouseButtonDown(0))
		{
			touchPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
			touchPos.z=0;
		}
		
		if(Input.GetMouseButton(0))
		{
			
			Vector3 startPos = touchPos;
			Vector3 endPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
			endPos.z=0;
			
			if((endPos-startPos).magnitude > lineLength){
				GameObject obj = Instantiate(linePrefab, transform.position, transform.rotation) as GameObject;
				obj.transform.position = (startPos+endPos)/2;
				obj.transform.right = (endPos-startPos).normalized;
				
				obj.transform.localScale = new Vector3( (endPos-startPos).magnitude, lineWidth , lineWidth );
				
				obj.transform.parent = this.transform;
				
				touchPos = endPos;
			}
		}
	}
}
```

#使い方
事前準備で作成した空のオブジェクトに上記のスクリプトを追加します。
追加するとこのような↓状態になりますので、
![drawPhysicsLine.png](https://qiita-image-store.s3.amazonaws.com/0/94654/ceb26eb9-bc90-2a19-8a53-512be6291634.png)
Line Prefabのところに事前準備で作成したCubeのPrefabをDrag&Dropで設定します。
あとは実行してGame画面上でマウスを左クリックすれば線が引けます。

Cubeの色を変えれば線の色を変えられます。
Line Lengthは線の最小の長さです。このパラメータ以上の距離をドラッグしないと線が描画されません。数値を1.0とかにすればわかりやすいです。
Line Widthは線の幅です。
Genymotionと実機をみわける話


## Genymotion

[Genymobile](http://www.genymobile.com/)社が開発しているAndroidのエミュレータです。

https://www.genymotion.com/

無料版と有料版がありますが、特に有料版だと至れり尽くせりで、開発目的だけでなく、パソコン上でAndroidアプリを動かすのにまぁ不自由はないって感じです。ゴニョれば、Play Sroreアプリも入れられるし。

と言っても有料版は結構[高い](https://www.genymotion.com/#!/store)ですが。

## 見分ける必要がでてきたので考えた

最初に考えたのは、加速度センサの挙動を使うというものでした。
普通に考えて、加速度は検知しないだろうと。

だがしかし、Genymotionの有料版では、Accelerometerが使えたりします。orz

* マイクで音を拾ったらどうか → 実機でもマイクのない機種がありそう
* CPUクロックを実測したらどうか → どうやって？
* MACアドレスのベンダー調べたらどうか → MACアドレスを取得すること自体好ましくない

と、いろいろ考えたあげく、なんか弱点はないものか、[FAQ](https://www.genymotion.com/#!/support#faq)をあさったところ、ようやく見つけました。

##### Why doesn't the battery level chart visible in the system settings reflect the charge level?

The battery level chart is only updated when the battery is in discharging state. Other states of charge do not affect the battery chart, whatever mode is used (host or manual).

## バッテリー情報が実機と違う

そりゃ当然、バッテリーの情報は実機とは異なってくるよね。
ということで、[ここ](http://www.adakoda.com/android/000140.html)とか[ここ](http://seesaawiki.jp/w/moonlight_aska/d/%A5%D0%A5%C3%A5%C6%A5%EA%BE%F0%CA%F3%A4%F2%BC%E8%C6%C0%A4%B9%A4%EB)とかを参考に、バッテリー情報を取得してみます。

```java

@Override
protected void onResume() {
    super.onResume();
        
    IntentFilter filter = new IntentFilter();        
    filter.addAction(Intent.ACTION_BATTERY_CHANGED);
    registerReceiver(mBroadcastReceiver, filter);
}

@Override
protected void onPause() {
    super.onPause();
        
    unregisterReceiver(mBroadcastReceiver);
}

private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
            //ここで、intent.get???Extra("???")で、各種情報が得られる
        }
    }
};
```

Genymotionの場合、onReceive()メソッドのところで得られる情報のなかに、実機じゃまずこれはないだろーというようなものがあるので、それを使って判別することになります（詳細は、実際に試してみてください）。

もし、間違えて実機をエミュレータだと判別してしまうと困るので、いくつかの情報を組み合わせるのがよいでしょう。

## 問題点

レシーバーへのコールバックで判別するので、処理としては非同期になります。また、onReceive()が呼ばれるタイミングは、特に決まっているわけではないので、そのあたりは何らかの割り切りをして実装する必要があります。

## 余談

この方法は、[Bluestacks](http://www.bluestacks.com/)でも有効です。
なんだかんだぐぐってしまう git tag の必要最小限なコマンドおさらい


## タグ一覧を見る

```bash
git tag
```

## タグを打つ


```bash
git tag v1.0
```

## 注釈付きタグを打つ

```bash
git tag -a v1.1 -m 'my version 1.1'
```


## gitのtagをremoteにpushする

```bash
git push origin --tags

or 

git push origin :tagname
```

ひとまずこれだけあれば事足りますね。
rails開発をPry使用してデバックの効率化

Pryを利用することで、rails consoleでコマンドを使用して対話型でデバックができて便利。
なので、使用方法をまとめておくことにしました。


## Railsコンソールで利用できるようにする
GemfileにPryを追加する

```
  group :development, :test do
    gem 'pry-byebug'
    gem 'pry-rails'
  end
```

Bundlerでgemをインストールする

```
bundle install
```

Railsコンソールを開く

```
$ rails c
Loading development environment (Rails 4.2.3)
[1] pry(main)>
```

irbからpryに変わっている

## Pryを使う
helpを打って打って利用可能なコマンドなどの説明を見る

```
$ rails c
Loading development environment (Rails 4.2.3)
[1] pry(main)> help
Help
  help               Show a list of commands or information about a specific command.

Context
  cd                 Move into a new context (object or scope).
  find-method        Recursively search for a method within a class/module or the current namespace.
  ls                 Show the list of vars and methods in the current scope.
・
・
・
```

pry-railsで追加されるコマンドの抜粋

|コマンド|意味|
|---|---|
|recognize-path|引数に渡した文字列などルーティングのactionやcontroller情報にパースする|
|show-middleware|読み込んでいる Rake Middleware を表示する|
|show-model|引数で渡したモデルの情報を表示する|
|show-models|すべてのモデルの情報を表示する|
|show-routes|ルーティング情報を表示する|

show-modelの実行例

```
[1] pry(main)> show-model User
User
  id: integer
  username: string
  email: string
  encrypted_password: string
  reset_password_token: string
  reset_password_sent_at: datetime
  remember_created_at: datetime
  sign_in_count: integer
  current_sign_in_at: datetime
  last_sign_in_at: datetime
  current_sign_in_ip: string
  last_sign_in_ip: string
  created_at: datetime
  updated_at: datetime
  has_many :user_work_groups
```

## ステップ実行でデバック
pry-byebugをインストールしたことによって、デバッグ実行するが可能なっている

ソースコードの中にbinding.pryを記述することによって、ブレークポイントとなる。
binding.pryと入力していた行が実行された時にプログラムが中断されるようになる。

```
$ rails s
=> Booting WEBrick
=> Rails 4.2.3 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server

省略

    2: def index
    3:   @users = User.all
 => 4:   binding.pry
  　5:   puts "test"
    6: end
[1] pry(#<UsersController>)> 
```

ステップ実行のコマンド

|コマンド|意味|
|---|---|
|step|メソッドの内部に入って1行進める|
|next|現在のメソッドのレイヤーで1行進める|
|finish|現在のメソッドを抜ける|
|continue|デバッグを抜けてプログラムの実行を続ける|
|break|ブレイクポイントを管理する|

nextコマンド実行例

```
[1] pry(#<UsersController>)>  next
省略

    2: def index
    3:   @users = User.all
    4:   binding.pry
 => 5:   puts "test"
    6: end

```
Convex Formulation for Learning from Positive and Unlabeled Data を読んだ

# ICML2015 Convex Formulation for Learning from Positive and Unlabeled Data を読んだ
## どんなもの？
正例とラベルなしデータから二値分類する問題を考える。
提案法が最適解に最適なレートで収束することを理論的に証明し
従来法と同程度の精度をより少ないコストで実現できることを
実験的に示した。

## 先行研究と比べると？
従来は非凸なロス関数で最適化していた所を、凸関数で最適化できるようにした

## 技術や手法のキモはどこ？
- 正例とラベルなしデータに別々のロス関数を割り当てる
- ダブルヒンジロス関数を使う
Tsubameへのsshの同時接続可能数

Tsubameにはsshの同時接続数の制限があります。

設定は `/etc/sshd_config` で行われていると思いますが、管理者権限でないと見られないため詳細は分かりません。
HPには
>一定時間内に一定回数以上の SSH 接続を行うと、一時的にシステムにログインできなくなります。
(http://tsubame.gsic.titech.ac.jp/node/1111)

と書かれています。

実際に試してみたところ、とりあえず4回は接続可能でした

| 同時接続数 | 同時接続可否 |
|-----------:|------------:|
| 20 | NG |
| 10 | NG |
| 4 | OK |

拒否られると30分間、拒否され続けます。
rsyncのTips

### ①rsyncはオリジナルのパーミッション情報とともに転送先のファイルが作られるわけではない
rsyncには `-p` オプションがあり、コピー元のファイル/フォルダのパーミッション情報を転送することができるのですが、それを使ったときに不思議な現象に遭遇しました。
一部のフォルダはオリジナルと同じパーミッションで作成されるのに、ほかのフォルダはこちらが指定していないパーミッションに指定されて作成されたという事象です。
これは、明示的に `--chmod` オプションで指定しても起こりました。

そして、分かったことは、パーミッション情報は徐々に更新されるということです。
時間経過とともにどんどんパーミッションも更新されていきます。

正確にrsyncの仕様を見たわけではないので、よくわからないですが、ファイルのメタ情報をはじめに送らないみたいですね。

### ②rsyncはリソースを複数指定できる

下記のようにして、リモートホスト上のリソースを複数指定することができます。
`rsync -e ssh ${USER_NAME}@$HOST:$RESOUCE1, :$RESOUCE2, :$RESOUCE3 $DESTINATION/`

これで指定すれば、一回のsshアクセスで複数のリソースをrsyncできるので、sshの接続制限がある環境下では使用したほうがよいでしょう。
Storyboardにxib利用

自分用メモ

xibで作成したカスタムViewをStoryboradに配置して利用する方法。

xibでデザインをしてFile's OwnerのCustom ClassのClassでClassを指定。
![スクリーンショット 2015-09-30 6.46.48.png](https://qiita-image-store.s3.amazonaws.com/0/30834/d06f7e83-5dd2-5a65-b112-6484425f2694.png)

そのままだとStoryboardで読み込んだ場合に、高さ300でうまく動作しなかった。
対策として、xibのSimulated MetricsのSizeを変更し、Storyboardでそのサイズを初期値指定する。

xibファイル設定
![スクリーンショット 2015-09-30 6.47.16.png](https://qiita-image-store.s3.amazonaws.com/0/30834/2d1bd8f9-2254-a1c1-48c1-aa90a2be77c0.png)

Storyboard設定にてClassを指定
![スクリーンショット 2015-09-30 6.48.49.png](https://qiita-image-store.s3.amazonaws.com/0/30834/94e3188c-e85c-78db-4a9e-b9acb98917c9.png)
Storyboard側の制約をxibファイルに合わせて指定
![スクリーンショット 2015-09-30 6.49.28.png](https://qiita-image-store.s3.amazonaws.com/0/30834/729fbd2a-6970-4e5b-3236-93102986f874.png)

最後にClass内のinitでxibをロード。

```swift
class VideoNavView: UIView {

    private var v: UIView?

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        v = NSBundle.mainBundle().loadNibNamed(
            "VideoNavView",
            owner: self,
            options: nil
        )[0] as? UIView
        self.addSubview(v!)
    }
}
```

これで一応思った通りに動作できました。
いい方法が他にあればご教授お願いします。

あと、xibファイルのViewを読み込み時に動的に設定する場合、サイズに関係ない場合はinitで指定、Viewの位置についてはdrawRectに指定すればOK。

UISliderのつまみの画像変更など。

```swift
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        v = NSBundle.mainBundle().loadNibNamed(
            "VideoNavView",
            owner: self,
            options: nil
        )[0] as? UIView
        self.addSubview(v!)

        /* Viewのカスタム */
        spdSdr.setThumbImage(
            UIImage(named: "spdSdrThum"),
            forState: UIControlState.Normal
        )
        spdSdr.setThumbImage(
            UIImage(named: "spdSdrThum"),
            forState: UIControlState.Highlighted
        )
        spdSdr.setThumbImage(
            UIImage(named: "spdSdrThum"),
            forState: UIControlState.Selected
        )
    }
```

Auto Layoutにてサイズ変更後のViewを基準にあるViewの位置を指定したい場合など。
この時基本のサイズや位置だけ指定しておけば、iPad等は相対的に勝手に位置などは修正されるので、iPadの場合にボタンサイズを2倍にする制約があっても個別処理は不要。

```swift
    override func drawRect(rect: CGRect) {
        super.drawRect(rect)

        /* スライダーの右端と左端にViewを配置 */
        var posStBtnR: CGRect = posStBtn.frame
        posStBtnR.x = posSdr.x - (posStBtnR.w * 0.5)
        posStBtnR.y = posSdr.y + (posSdr.h * 0.5)
        posStBtn.frame = posStBtnR

        var posSpBtnR: CGRect = posSpBtn.frame
        posSpBtnR.x = posSdr.x + posSdr.w - (posStBtnR.w * 0.5)
        posSpBtnR.y = posSdr.y + (posSdr.h * 0.5)
        posSpBtn.frame = posSpBtnR
    }
```
sublime text > 行末の空白削除 > trim_trailing_white_space_on_save / パッケージ TrailingSpaces

http://qiita.com/shingargle/items/047f759f339398ff836d
を見ていて、よく使うsublime textではどうだろうかと調べた。

参考ページ http://megane-blog.com/2014/08/15/1284

> "trim_trailing_white_space_on_save": true
> これでファイル保存のたびに、行末の不要なスペースやタブが自動的に削除されます。

自動削除では問題がある場合は、同じ参考ページに記載があるTrailingSpacesを使えばよさそう。

> もし自動的に消えるのが、Git管理とかでノイズになってしまうということであれば手動で削除する。その場合は、パッケージ TrailingSpaces。文末など不要なスペースに色をつけて警告してくれる。

https://github.com/SublimeText/TrailingSpaces

<hr>
(追記 2015/10/02)
以下に記載したが、どうもTrailing Spacesを入れておくと、Sublime Text側でファイルが開いた状態が保持されるのではないかと思うエラーが見られた。

http://qiita.com/7of9/items/5b8ed637411e556bf098
技術英語 > no + 無冠詞名詞 > 決して...ではない > She is no liar. / There is no single path to that.

引用: 冠詞マスター教本 by 石井隆之さん

> [no + 無冠詞の普通名詞]で「決して〜ではない」の意味。
(a) She is no liar. (彼女は嘘つきどころではない[むしろ正直ものだ])
(b) She is not a liar. (彼女は嘘つきではない)
※ (a)は(b)より意味が強調される。

noの場合は「a」が付かない（無冠詞)。

She is not a liar. She is rather an honest person.
を
She is no liar.
と短く言えるということなのだろう。

<hr>
noつながりで思い出したのは

No offense. (気を悪くしないでね)

Star Trek Voyagerのいくつかのエピソードで出てきた。
トレス中尉が同僚に言う場面だったかと思う。

<hr>
昔の勉強メモを見ていて、以下の文例を見つけた。

There is no single path to that.
「not the only possible one」という意味というメモが残っている。

この場合の no single は not a single の強調と考えてもいいのだろう。

意味としては「そこへ至る道は一つとは限らない」。

「そこへ至る道は一つもない」という意味に対応するのは以下なのだろう。
There is no path to that.
ansible-playbookコマンドでsshが繋がるのにssh errorが出た際の解決策

#前提
* vagrant上で2つのARTACK/debian-jessieを構築
* 鍵の交換は済ませており、sshで入れる
* ```ansible-playbook -i hosts -m ping```が成功する
* ```git clone```で取得したplaybook

#エラー
```
GATHERING FACTS ***************************************************************
fatal: [192.168.33.12] => SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue
```

#解決策
対象のplaybookがrootを前提としていた為でした。
Debian Jessie 8.1.0 Release x64 (Minimal, Guest Additions 4.3.26)にはrootユーザが存在しない為に上記のエラーが出ます。

```yaml
# 変更前
- hosts: all
  user: root
```
管理者権限はsudoで付ける事にします。

```yaml
# 変更後
- hosts: all
  sudo: yes
```
簡単な事ですが、表示されるエラーと原因が直接結びつかない場合ちょっと戸惑いますね。
node-ffiでOSXのフレームワークをロードするには

# 背景

Node.jsで共有ライブラリを扱え、CやC++のコードを書かずにネイティブのライブラリが扱えるnode-ffiがNode.jsのv4.x系に早くも対応している。

[とあるIssue](https://github.com/node-ffi/node-ffi/issues/195)でCocoaフレームワークをロードする必要があり、

```js
ffi.Library("/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa")
```

としても、ダメ(拡張子が.soや.dylibでないと怒られる)だったので、[回りくどい書き方](https://github.com/node-ffi/node-ffi/issues/195#issuecomment-142835185)をしていた。

# 解決方法

```js
var lib = ffi.DynamicLibrary('/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa');
```

とDynamicLibraryというメッソッドがnode-ffiには用意されいた。

# 関連記事

- [node-ffiをGoで入門してElectronを使って応用してみる](https://abrakatabura.hatenablog.com/entry/2015/12/11/000722)
- [Node.jsでFaceTime HDカメラを使う](https://abrakatabura.hatenablog.com/entry/2014/11/24/192128)
【翻訳】初心者のためのErlang - Cowboy

[Cowboy Users Guide の翻訳記事の目次はこちらへ](http://qiita.com/hayabusa333/items/ac692bdb08fa3d81e312)

#本文
おそらくあなたはCowboyを利用したいと興味を持っているだろうが、どのようにErlangのプログラムを書けばよいのか全くわかっていないのでしょう。
大丈夫！
この章はあなたがErlangを始めるお手伝いをします。

私たちは初心者のために2つの本をオススメをします。
これらは2つの全く異なる視点からErlangを進めているため両方をお読みください。

## すごいErlangゆかいに学ぼう!（Learn You Some Erlang for Great Good!）
Erlangを始めるための最も簡単な方法は私たちが愛情をこめてLYSEと呼んでいる面白い名前の本を読むことです。
それは構文として正しく、速く、初心者が尋ねる問題に対して答えています。そしてすごくおかしな絵を示して、洞察に満ちた冗談が書かれています。
無料のオンラインブックの初期バージョンを読むこともできますが、実際に試すならば遥かに洗練された紙の本か電子書籍版を購入したほうが良いでしょう。

## Programming Erlang
いくつかのコードを書いた後、あなたはおそらくErlangが今に至った概念に対して理解したいと凄く感じるでしょう
それを感じたなら ジョー・アームストロング。Erlangのゴッドファーザーによって書かれた最高の本であるProgramming Erlangを読むことによって説明されています。

言語の全ての詳細に立ち入る代わりにジョーはErlangの中心的概念に集中して、彼がどのように色々なアプリケーションを書くことに慣れることができるかについて教えてくれています。

執筆時点ではこの本の第二版はベータ版であり、現状では使用できない今後のErlangの機能についていくつかの詳細が含まれています。
必要なエディションを選択して読んでみてください！
RubyMineでgem is ** not available in sdk


RubyMineだけの限った話ではないと思うが、
以下の様なメッセージが出る時がある。

`gem is ** not available in sdk`

そんな時は。`bundle update`を実行してから bundle installを実行。

意外と資料がなくてびっくりしたので記録します。
ebでnginxの設定が楽になる

らしい。
http://aws.typepad.com/aws_japan/2015/09/elastic-beanstalk-update-support-for-java-and-go.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+AmazonWebServicesBlogJp+%28Amazon+Web+Services+%E3%83%96%E3%83%AD%E3%82%B0%29

```
新しいプラットフォームはweb層で動作するNginxリバースプロキシを構成するプロセスを簡素化します。 Nginxの構成を上書きするために.ebextensions/nginxフォルダー内にnginx.confを配置することが可能です。また、そのプラットフォームによって提供されるNginxの構成の中に含めるため.ebextensions/nginx/conf.dフォルダー内に構成ファイルを配置可能です。詳細はリバースプロキシの構成をご参照ください。

1. .ebextensions/nginx/nginx.conf - Nginx構成を上書きする
2. .ebextensions/nginx/conf.d - Nginx構成内に含められるファイル群
```

試してみたら未だ出来なかった

```bash
eb --version
EB CLI 3.5.4 (Python 2.7.1)
```

次のバージョンからなのか？
【jQuery】<input type="reset">（リセットボタン）でリセットされる初期値を変更する

フォーム・保存(Submit)・元に戻す(Reset)を組み込んだajaxを利用したフォームアプリケーションを製作した時のメモ。
元に戻すボタンを押すと保存前（読み込み後に保存していない場合は読み込み時）の値にリセットしようと考えていたのですが、本来のリセットボタンは`$(selector).val()`で上書きしようとしても初期値として適用してくれません。

動作はjQuery 1.11.2で確認
コード中の`selector`はフォーム部品のセレクタを意味します。

#15/10/01追記
全フォーム部品に対応したまとめを作成しました。
[【jQuery】フォーム部品のリセット初期値を変更する（まとめ）](http://qiita.com/Ryoto20707/items/44943d3cf05545ffa771 "Qiita")

#前提：`$(selector).val()` VS `$(selector).attr("value")`
jQueryでinputの値を取得・変更する際に`$(selector).val()`を使うべきか`$(selector).attr("value")`を使うべきかの問題はよくある話で、[こちら](http://qiita.com/kazunari-yamashiro/items/72ed73e401b88a6a507b "Qiita")にも投稿があります。
一般には`$(selector).val()`の方が良いです。

#本題：`<input type="reset">`の問題点
フォームを簡単に初期値（value属性に指定されていた値）にリセットできる`<input type="reset">`はフォームのコーディングによく利用されますが、JavaScriptで書き換えた値も元に戻されてしまうという問題点がありました。（フォームをまっさらにする「クリア」については別記事を参照してください。）

#リセットの初期値ごと変更するには
ここで`$(selector).attr("value")`を利用します。
保存（ajaxで送信）する時に同時にattrでvalue属性を書き換えると、リセットボタンを押した時に保存時の値に戻ります。

#サンプルコード（初期値変更のみ）
````html:test.html
<!DOCTYPE html>
<html>
<head>
    <script src="jquery-1.11.2.js"></script>
    <script src="script.js"></script>
</head>
<body>
    <form>
        <input type="text" id="input" value="A">
        <input type="reset" value="Reset">
        <button id="set_val">Set value to B</button>
        <button id="set_attr">Set attribute to B</button>
    </form>
</body>
</html>
````

````js:script.js
$(function(){
    $("#set_val").click(function(){
        $("#input").val("B");
        return false;
    });
    $("#set_attr").click(function(){
        $("#input").attr("value", "B");
        return false;
    });
});
````
フォームには初期値としてAが設定されています。
Set value to Bをクリックするとフォームの値がBに変わりますがResetでAに戻ってしまいます。
Set attribute to Bをクリックすればvalue属性をBに変えてくれるのでReserをクリックするとBに変化します。
ただし、前述のリンクに書かれている通り、Set attribute to Bで変更されるのはvalue属性値だけなので見た目は変化しません。
見た目（実際のvalue）を変化させるためには$(selector).val()が必要なので注意してください。

#補足
検証したところ
ロード→#set_val　⇨　valが変化（当然）
ロード→#set_attr　⇨　valも変化
ロード→#set_val→#set_attr　⇨　valは変化しない
となるようです。
attrを変更した時にvalが伴うのはロードしてから一度もvalをいじってない時限定みたいですね。
Ottoに既存のVagrantfileを食わせて仮想マシンを起動した

# はじめに

2015-09-28に発表されたHashicorpの新プロダクトである[Otto](https://ottoproject.io/)はVagrantの後継となることを予定されたものである。
そこで現時点でVagrantの代わりになるかを、既存のVagrantfileを食わせることで確認してみた。

先に結論を書くと、今のところはVagrantのラッパーになっているだけで、このような用途ではVagrantの代わりに使う意味は特にないだろう。

# Ottoの簡単な説明をしながら試していく

OttoはVagrantの後継として作られたものだが、Vagrantで行う開発環境の構築だけでなく本番環境の構築からデプロイまで一貫して行うことまでを目的としている。
そのため、現時点ではOttoはVagrant, Packer, Terraformのラッパーとなって動作する。将来的には少なくともVagrantは取り込まれることになるのだろう。
この記事ではVagrantが担当する部分しか試さない。

Ottoのインストールは例によって[ダウンロードページ](https://ottoproject.io/downloads.html)から適切なzipファイルをダウンロードしてきてパスの通ったところに展開するだけである。
VagrantのラッパーになっているのでVagrantも同様にパスの通ったところに展開されている必要もある。使うのだったらPacker, Terraformもまた同様である。

今回使う環境はWindows 8.1 Updateであり、cygwinでコマンドを実行している。仮想環境はVirtualBox 5.0.2を使用している。Ottoのバージョンは0.1.1である。

Ottoを使うにあたって最初に行うことは、プロジェクトルートで`otto compile`を実行することだ。
`otto compile`はVagrant, Packer, Terraformが使用する設定ファイルやスクリプトなどを生成するコマンドである。

プロジェクトルートとはどういうことか。Ottoはそのプロジェクトで使われている言語を見て、その言語を自動的にインストールしてくれるshell provisionerを持つVagrantfileを自動生成する。これが`otto compile`の役割の1つである。
また、生成されたVagrantfileではプロジェクトルートをsynced_folderとするようになっており、Ottoのsshログイン用のコマンド(`otto dev ssh`)ではこのsynced_folderにログイン後自動でcdされる。

という代物である結果、`otto compile`を空ディレクトリで実行するとエラーになるので、適当に1.rbという空ファイルでも作ってから実行する。
Vagrantfileは.otto/compiled/app/dev/Vagrantfileに生成されるので、既存のVagrantfileを使いたければこれを差し替えてしまえば良い。

本来ならばAppfile（`otto compile`による自動生成をオーバーライドするための設定ファイル）に[ドキュメント](https://ottoproject.io/docs/apps/custom/index.html)に書かれているようにcustomのApp Typeを使ってVagrantfileの位置を指定してやれば良いような気がするがやっても上手く行かなかった。
ソースを見ると必ず.otto/compiled/app/dev/Vagrantfileを見に行っているがcustomのApp Typeを使うと.otto/compiled/app/devディレクトリが作られもしないから、という話のようだ。

仮想マシンを起動するコマンドは`otto dev`である。つまりこれが`vagrant up`に相当する。
実行時に何かIPアドレスが表示されるが自前のVagrantfileには関係ない。

`otto dev (なんとか)`はすべてVagrant関係のコマンドである。ちなみにPacker関係は`otto build (なんとか)`、Terraform関係は`otto deploy (なんとか)`である。
要するにOttoはコマンドを`otto compile`→`otto dev`→`otto infra`（デプロイ先のクレデンシャルを入力するためのコマンド）→`otto build`→`otto deploy`の順に実行し、開発環境で開発→本番環境の作成→本番環境のデプロイを行うことを目的としたツールということだ。

仮想マシンを終了する場合は`otto dev destroy`である。つまり`vagrant destroy`に相当する。

また、`otto dev vagrant (コマンド)`でvagrantの各コマンドを実行することもできる。例えば`vagrant reload`を実行したい場合は`otto dev vagrant reload`である。
この環境にはVagrantのプラグインは入っていないので試していないが、この方法でコマンド拡張系のプラグインも使用できると思われる。

先程書いた`otto dev ssh`はこのやり方ではエラーになる。自動生成されたVagrantfileでは上手く行くので何か追加すればエラーにならずに実行できるようになるかもしれない。`otto dev vagrant ssh`は問題ない。

# 追記

QiitaのOttoタグは他のものに先に取られていた。
Vagrant で VirtualBox に Ubuntu Server 14.04 をインストールする

[前記事](http://qiita.com/flny/items/a3b7869503895a12f841)の続きです。
Vagrantで VirtualBoxへ Ubuntu Server 14.04 をインストールします。

```
$ vagrant box add develop https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box
```
developは任意につける仮想マシンの名称です。URLはUbuntu Server 14.04(Trusty/amd64)のイメージファイルを指しています。

```
Downloading box from URL: https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box
Progress: 3% (Rate: ...
```
と進捗が表示されつつイメージファイルのダウンロードが始まります。400MB弱のファイルですが30分程度の時間が掛かりました。

```
Downloading box from URL: https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box
Extracting box...te: 290k/s, Estimated time remaining: 0:00:01))
Successfully added box 'develop' with provider 'virtualbox'!
```
と表示されれば完了です。この時点でディスク容量が300MB程度減っています。

```sh:before
/dev/sda3        224G  1.6G  211G   1% /home
```
```sh:after
/dev/sda3        224G  1.9G  211G   1% /home
```

```
$ vagrant box list
develop (virtualbox)
```
box list でインストールした仮想マシンの名称が表示されます。
Travis CIでfatal: ambiguous argument 'origin/master'



Travis CIでgit diffのような現在ブランチと別のブランチを比較して差分のみを扱うようなコマンドを書いた場合に次のようなエラーとなる場合があります。

```
# 変更されたファイルのみを扱う
> git diff --name-only --diff-filter=ACMR origin/develop | echo

fatal: ambiguous argument 'origin/develop': unknown revision or path not in the working tree.

Use '--' to separate paths from revisions, like this:

'git <command> [<revision>...] -- [<file>...]'

```


ローカルでは起きなくて、Travis CIのみで起きるのはそもそもTravis CIはデフォルトでリポジトリを
shallow cloneしているからです。

- https://travis-ci.org/jser/jser.github.io/builds/82738025#L66

> $ git clone --depth=50 --branch=2015-09-29JavaScript https://github.com/jser/jser.github.io.git jser/jser.github.io

という感じで、`--depth`を付けて一部だけcloneしています。

そのため、Travis CIでcloneした直後は、`--branch=`で指定したブランチのみで、`master`などが存在しないようになっています。

なので`git diff --name-only --diff-filter=ACMR origin/develop`というように、現在ブランチと`origin/develop`を比較しようとするとそんなブランチがないと言われます。

## 修正方法

一部しかcloneしてないので、全部`fetch`するようにすれば問題なくなるはずです。

なので、`.travis.yml`で`git fetch --unshallow`で全部fetchするようにしておけば問題なくなります。(その代わり全部ダウンロードするので遅くはなります)

```
before_install:
- git fetch --unshallow
```

参考

- [Disabling git --depth option · Issue #3412 · travis-ci/travis-ci](https://github.com/travis-ci/travis-ci/issues/3412 "Disabling git --depth option · Issue #3412 · travis-ci/travis-ci")
jQueryプラグインを作るときのソース


「指定したリンク先へのaタグで囲ってくれるプラグイン」
　jquery.wrapLink.js という例です。

(実用性あるか謎ですが)


```html:plugin
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>jQueryプラグインを作る</title>
	<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
</head>
<body>

	<ul>
		<li>わたしaタグで囲われたい</li>
	</ul>


	<script type="text/javascript">
	$(function(){
		// 実行部分
		$('li').wrapLink("http://qiita.com/");
	});
	</script>



	<script type="text/javascript">
	// jQueryプラグイン定義

	// 1、即時関数でくくる
	;(function($){
		// 2、$.fn.ほにゃららで定義(jQuery.prototype の別名)
		$.fn.wrapLink = function(aUrl){
			//thisで対象のjQueryエレメントを指定可能
			this.wrap('<a href="' + aUrl + '">');
			// メソッドチェーン対応の為 自分を返してつなげる
			return this;
		}
	})(jQuery);
	</script>

</body>
</html>
```
Consulクラスタ全体が不安定になった事案と原因

## 環境

Consul Server(0.5.2) x 3
Consul Agent(0.5.2) x 数十台

## 現象

とある日、プロダクトのConsulクラスタ管理下のサーバがちょいちょいアラート出すので
Consulログを確認するとノードが数分間隔で ``EventMemberFailed`` と ``EventMemberJoin`` を繰り返していた。
特に特定のノード、というわけでもなく、ランダムにノードがFailし、数十秒後にJoinし直す、というログがひっきりなしに出力されていた。

「consul flapping」でぐぐってみると、いくつか同じような現象で悩んでいる事案があるようだった。

## 原因となったサーバ

ほぼ全てのノードがflapping状態だったので原因つかめず途方に暮れていたが、[この投稿](https://groups.google.com/forum/#!msg/consul-tool/GDS8h0XaUgE/A-HQ2QuDTRMJ) で

```
memberlist: Refuting a suspect message (from: a-01)
```

のfromのサーバを見るといいよ、とあったのでgrepしてみるとビンゴ。
そのサーバにログインしてみると動作がめっちゃ重い。
ただ、topやvmstatでみても過負荷ではないし特に原因は見当たらず…
しかしEC2のステータスを見るとなんか定期的にFailしてたのでサーバ自体がなんかおかしかった様子。

![スクリーンショット 2015-09-29 1.55.43.png](https://qiita-image-store.s3.amazonaws.com/0/9099/56495612-ca93-e96b-5300-52572c744d0c.png)


## 復旧

原因となったEC2 stop＞start でインスタンスリフレッシュしたらサーバが正常に戻り
全てのサーバログに出力されていたRejoinのログもピタリと止まり、
クラスタ全体も安定稼働に戻った。

## Agentサーバが不安定になった根本的な原因？

よくわかってないけど、２つの可能性を考えてみた。

1. EC2自体がおかしくなってリタイアする予定だった？
   - 通知は来てないけど、たまにあるし…
2. I/O クレジット食いつぶしてた？
   - t2.microだったし、しばらく起動しっぱなしだったし、ネットワークも定期的に使われてたので、I/Oクレジットがなくなって不安定になった説。  ※そもそもこれ（I/Oクレジット残）確認する方法あるんだっけ？

## まとめ

Agentの１台のネットワークが不安定になると、全体的に不安定になるのちょっと怖いなーと思いました。
常に監視しといて、怪しいサーバはforce-leaveで切り離すとかしないといけないのだろうか…
もう少しマジメに監視する必要ありそう
水平分割されたDBにクエリを発行してデータを取得する


必要に迫られて書いたのでメモを残しておく。
DBはMysql、要ssh接続。
[net-ssh-gateway](https://github.com/jamis/net-ssh-gateway)、[parallel](https://github.com/grosser/parallel)、[maysql2](https://github.com/brianmario/mysql2)を使用。
スレッドを使用して並列に処理する。プロセスでも特に問題なく動作するはず。（動作確認していない）

```query.rb
require 'net/ssh/gateway'
require 'mysql2'
require 'parallel'

gw = Net::SSH::Gateway.new(
  'host',
  'user'
)

db_address = ->(i){ "database_server#{i}" }
db_name = ->(i){ "db_#{i}" }

query = <<EOQ
select *
from hoge
EOQ

result = Parallel.map(0.upto(db_count - 1), in_threads: 4) do |i|
  res = []
  gw.open(db_address.call(i), 3306) do |port|
    client = Mysql2::Client.new(
      host: '127.0.0.1',
      username: 'username',
      password: 'password',
      database: db_name.call(i),
      port: port
    )
    client.query(sql).each{|row| res << row}
    res
  end
end

result = result.flatten
```

ハッシュの配列が戻ってくるので、あとは煮るなり焼くなり。