OmniAICreator/Qiita-1.07M huggingface dataset:
第2回 アナウンスを流す - TwilioとRailsでミニマムコールセンターを作ろう

`別サイトで2014/4/6に投稿した記事です。別サイト閉鎖につき、移転しました。情報が古い可能性があるので、ご注意ください。`

今回は、Twilioを使って、自分の携帯番号に電話して、アナウンスを流してみます。

Twilioアカウントの取得は終わっていることを前提にしています。Twilioアカウントの開設は、[日本のTwilio公式サイト](http://twilio.kddi-web.com/)からどうぞ。

## 今回の流れ
* Railsのコンソールから Call.voice_message メソッドを呼び出すことで、
* Twilioから自分の携帯番号にコールし、
* 着信したら、「お電話ありがとうございます。こちらはABCお客様サポートセンターですです。」というメッセージを流します。

## Ruby on Railsで実装してみよう
### Railsプロジェクトの作成
    $ rails new twilio_rails_test # 「twilio_rails_test」という新しいRailsプロジェクトを作成する
    $ cd twilio_rails_test

### RubyでTwilioで制御するためのgemを Gemfile に追加
    gem "twilio-ruby"

["twilio-ruby" gem のGithubページ](https://github.com/twilio/twilio-ruby)

### call.rb というモデルを追加
```
class Call
  def self.voice_message
    account_sid = ENV['TWILIO_SID'] # Twilioで取得したSID
    auth_token = ENV['TWILIO_TOKEN'] # Twilioで取得したトークン

    client = Twilio::REST::Client.new(account_sid, auth_token)

    client.account.calls.create(
      from: ENV['TWILIO_CALL_FROM'], # 発信元電話番号： 取得したTwilioの電話番号
      to:   ENV['TWILIO_CALL_TO'], # 発信先電話番号： トライアルの場合は、発信先電話番号に制限があります。自分の場合は、Twilioの管理画面から自分の携帯番号を設定しました。すると、SMSで携帯番号を通知が来てました。無事、Twilioが認識すると、その番号に発信できます。
      url: ENV['TWILIO_XML_URL'], # インターネット上にあるXML形式のファイル。XMLにアナウンスする内容を記載。設定内容は後ほど。
      method: 'GET' # HPPTのGETメソッドを使うことにしました。
    )
  end
end
```

### 環境変数を設定
call.rb のENV['xxx']を使って、環境変数を取得できます。

    export TWILIO_SID=xxx
    export TWILIO_TOKEN=xxx
    export TWILIO_CALL_FROM=+8150xxx
    export TWILIO_CALL_TO=+8180xxx
    export TWILIO_XML_URL=http://xxx

.bash_profile 辺りに上記の環境変数を設定しておくと便利です。

設定後、

    source ~/.bash_profile

コマンドを実行して、追加した環境変数を有効にするのをお忘れなく。

### XMLファイルサンプル
call.rb の ENV['TWILIO_XML_URL'] は、コール着信後に流すメッセージをXML形式で定義しています。
↓ は今回使用するXMLファイルです。
このファイルをTwilio（インターネット）からアクセスできる所に置いてください。

```
<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Say language="ja-jp">お電話ありがとうございます。こちらはABCお客様サポートセンターです。</Say>
</Response>
```

### Railsコンソールでテストコール
    $ rails console
    > Call.voice_message

トライアルの場合は、現在トライアルで使用中であるというTwilioアナウンスが流れた後、Twilioから自分の携帯番号に電話がかかってきます。
応答すると、「お電話ありがとうございます。こちらはABCお客様サポートセンターです。」というアナウンスが流れます。

### サンプルコードのダウンロード
上記のサンプルコードは、Githubよりダウンロードできます。
[https://github.com/fuji3zpg/twilio-call-test](https://github.com/fuji3zpg/twilio-call-test)

## 次回
無事、アナウンスが流れたでしょうか？
はじめてアナウンスが流れた時は、私は感動しました。

今でもコンピュータ側から公衆回線網経由の電話を制御するのは相当なコストと労力が必要ですが、Twilioの登場によって、クラウドAPIで操作できるようになりました。

Railsのプログラマになる前、私はCTIという電話とコンピュータを連動させる分野の仕事をしていました。私が携わっていたプロダクトは高品質なものでしたが、その分複雑で理解するのも動かすもの、なかなか骨が折れたものです。

今回の例は単純なものだとはいえ、こうして公衆回線網の電話をRailsを通じて動かせたというのは大変な驚きです。

さて、次回は、エージェント（コールセンターで電話に対応する人）がブラウザでTwilioのコールを扱えるようにします。


## 関連するページ
* [第3回 顧客の電話をエージェントのブラウザで受ける](http://qiita.com/fuji3zpg/items/4d9a2fa7c397f940118d)
* [連載「TwilioとRailsでミニマムコールセンターを作ろう」一覧](http://qiita.com/tags/Twilio%E3%81%A8Rails%E3%81%A7%E3%83%9F%E3%83%8B%E3%83%9E%E3%83%A0%E3%82%B3%E3%83%BC%E3%83%AB%E3%82%BB%E3%83%B3%E3%82%BF%E3%83%BC%E3%82%92%E4%BD%9C%E3%82%8D%E3%81%86)
androidでTensorFlow その2

#概要
androidでtensorflowやってみた。
api17でinception/5hアプリ作って見た。

#写真
![device-2017-05-18-084249.png](https://qiita-image-store.s3.amazonaws.com/0/18104/facf45e9-4917-865f-da07-84be160f4c7e.png)

#環境
windows 7
ADT v22.6
android 4.2.2 api17

#ダウンロード
libtensorflow_inference.so
tensorflow java
inception5h.zip
githubから、以上を落とす。
imagenet_comp_graph_label_strings.txt
tensorflow_inception_graph.pb
を、取り出す。

#プロジェクトに配置
imagenet_comp_graph_label_strings.txt
tensorflow_inception_graph.pb
assetsに置く
libtensorflow_inference.so
libsに置く
tensorflow java
srcに置く

#プログラムの手順
カメラを使って、プレビューする。
イベントは、ボタン。
カメラ画像を読み込む。
２２４×２２４にリサイズする。
画像を表示する。
tensorflow_inception_graph.pbと
imagenet_comp_graph_label_strings.txt
をtensorflowに読み込む。
tensorflowに画像をくわせて、tensorflowからラベルを取得。
ラベルを表示する。
以上
KotlinはAndroidだけじゃない。サーバーサイドKotlinの波もきっと来る。

KotlinがAndroidの正式な開発言語となりました。

[［速報］「Kotlin」がAndroidの正式な開発言語に。開発元のJetBrainsとGoogleが「Kotlin財団」の設立も計画。Google I/O 2017](http://www.publickey1.jp/blog/17/kotlinandroidjetbrainsgooglegoogle_io_2017.html)

そして、サーバーサイドJavaフレームワークの大御所Springの次期メジャーバージョンSpring 5.0も正式にKotlinに対応することを表明しています。Spring 5.0 は現在RCで、正式リリースはもうまもなくです。

サーバーサイドKotlinはこれまで十分に評価されて来ませんでしたが、AndroidやSpringへの公式採用の波を受けて改めて評価される機会が増え、徐々に広まっていくと考えています。

サーバーサイドKotlinは他の言語と比べてもとてもバランスの良い選択肢です。

 - Javaとほぼ同等の高いパフォーマンス
 - 覚えやすく書きやすいシンタックス
 - 豊富なライブラリ(Javaのライブラリが使える)
 - コルーチンやnull安全な変数などモダンな言語機能

パフォーマンスが要求されるサーバーの場合、最近ではGoやNodeJSなどが使われることが多いと思います。しかし、GoやNodeJSは実際に使ってみると、独特の辛さがあります。Goは高速で堅牢ですが、Javaや一般的な軽量言語に慣れた開発者には言語機能が少なく感じられたり、標準ライブラリによるコレクション操作が弱いなどの問題があります。NodeJSは強みでもあるシングルスレッドの制約があるため、より高度な設計や複雑なコーディングを強いられます。これらに比べてKotlinのよいところは、「普通に進化している」ところです。
KotlinはGoほど特殊なシンタックスではないですし、シングルスレッドでもありませんし、関数型言語でもありません。
Kotlinには特別で突出した機能はないかもしれません。しかし、十分な言語機能とライブラリと使いやすさを備え、これといった短所がありません。短所を強いていうなら、サーバーサイドKotlinの利用者が少ないことによるエコシステムの弱さです。ただしライブラリは基本的にJavaのものが使えるため、何かを実現するためのライブラリがないといったことはまずありません。

僕自身は去年にスマホアプリ向けのWebApiサーバーとしてサーバーサイドKotlinを投入しており、既にサーバーサイドKotlinの使用は実用的でメリットがあると確信しています。この機会にサーバーサイドKotlinについても評価してくれる方が増えることを願っています。
Blender使い方・ショートカットまとめ

※随時追加予定（2017/6/4現在）
Blenderについての個人的なメモ

基本的にはマウスを重ねるとショートカットがツールチップで表示される

## 初期設定
日本語化（システム）
インターフェイス→カーソル深度X
インターフェイス→選択範囲を中心に回転〇
ファイル→バージョンを保存
入力→３ボタンマウス模倣
入力→テンキー模倣
→ファイル→スタートアップファイル保存

## 3Dビュー
N：プロパティシェルフ ON／OFF
5：透視投影／平行投影 ON／OFF

## 視点操作（主にテンキー）
1：フロント（正面図）
3：ライト（右面図）
5：透視投影／平行投影 ON／OFF
7：トップ（上面図）
9：ユーザービュー
0：カメラビュー
それぞれCtrlと組み合わせると反転
[中]：視点回転
Ctrl+[中]：奥行移動
Shift+[中]：水平移動
※設定変更している場合は[中]またはAltでも可

2：奥に回転
4：左回転
6：手前に回転
8：右回転
※各15度ずつ
Ctrl+2：下移動
Ctrl+4：左移動
Ctrl+6：右移動
Ctrl+8：上移動

Ctrl+Alt+Q：4分割画面

## 基本操作
G：移動
R：回転
S：拡大縮小
→ XYZ：それぞれの軸に固定
※基準は1回押しでワールド、2回でローカル

Shift+S：スナップのショートカット
Shift+Ctrl+Alt+C：各原点移動のショートカット
Shift+A：追加
GitHubでAndroid Studioプロジェクトを管理する際に.gitignoreへ追加すべきもの

Android StudioのプロジェクトをGitHub管理するぜと思っても、流石に全て公開するのは気がひける。
それに個人設定を見られて有益なことなさそうですし。邪魔だし。

色々考えた結果、私は.gitignoreを以下の設定にしています。

```
*.iml
.gradle
/local.properties
/.idea
.DS_Store
/build
/captures
*.apk
```

Android Studio 上でGitの設定を行えば自動である程度は作成されます。
別にそれで十分とは思いますが、.ideaは全部消してもある程度自動で復活するので
無視リストに追加しました。すっきり。

ただしそうすると、他端末でcloneする際にlocal.propertiesがありません作れませんと怒られたので、local.propertiesは自分で追加してください。

適当に新規プロジェクト作成して、そこからlocal.propertiesを拝借すれば問題ありません。
Pythonのデコレータについての適当な説明

デコレータとはデコレータ用の関数である関数を装飾し，装飾された関数にすり替えてくれる機能です．

例えば以下のようなデコレータ用の関数を用意します．

```python
def my_decorator(func):
    def decorated_my_func(*args, **kwargs):
        print("デコレートしました")
        func(*args, **kwargs)
    return decorated_my_func
```

そして普通の関数を上の関数でデコレートして宣言します．

```python
@my_decorator
def my_func(str):
    print(str)
```

そして実行すると

```python
>>> my_func("ああああああ")
デコレートしました
ああああああ
```

となります．つまり`my_func()`宣言時に`@my_decorator`をつけることによって

```python
>>> my_func = my_decorator(my_func)
... my_func("ああああああ")
デコレートしました
ああああああ
```

と同じことをしてくれるのがデコレータです．
9patchを入れたらFrame pixels must be either solid or transparent (not intermediate alphas).

### 9patchファイルをandroid studioのdrawableディレクトリに入れたらエラーが出た
9patchファイル入れる
↓
ビルド
↓
エラー

エラーメッセージ。
`Frame pixels must be either solid or transparent (not intermediate alphas).
Found at pixel #5 along right edge.`

http://qiita.com/natsuki_summer/items/6073ace74f21f25cd4e4
ここ見て9patchファイルが悪いのかと思いきや、
AndroidStudio上で9patchファイルを編集して（適当に1px塗りつぶす→塗りつぶしたところを戻す）からビルドしなおしたらビルドできた。
9patchファイルのピクセルをどこか塗りつぶしたりしたわけでもない。。
Google VR SDKのバージョン選び

iOSおよびAndroid用にGoogleが開発しているGoogle VR SDK(旧CardBoard SDK)ですが、順調なアップデートと、それに伴う破壊的変更が多いため、どのバージョンを選ぶべきかの選択が大変です。

とりあえず触ったことのあるバージョンと、簡単な特徴をまとめます。
凄く大雑把に進化の歴史に関する個人の感想をまとめておくと

旧Cardboard(-0.6)→audio周りに手が入り、ネイティブプラグインに機能を委譲(0.8)→プログラマが変更できる余地が段々狭まる(0.81-1.10)→Daydreamと両対応(1.x)→UnityネイティブVRサポートと統合(1.40)→下位互換ほぼ切り捨ててDaydream keyboardが追加(1.50)

という流れです。

## 0.8
戻るボタンの左向き矢印を消せる最後のバージョン
(0.81から消せなくなっています)

左向き矢印を消したい、という方はこのバージョンにしましょう。

## 1.0.3
Unity5.5.0p3と組み合わせてCardBoardとして使うなら比較的安定しています。
http://greety.sakura.ne.jp/redo/2017/01/20170103cardboardunity550p3-google-vr-sdk-v103.html

## 1.30.0
dynamic library loading前の最後のバージョン

iOS+Unity5.6で使うときにクラッシュする不具合があるためiOS+Unity5.6を使うなら1.40推奨
https://github.com/googlevr/gvr-unity-sdk/issues/504
## 1.40.0
Legacy扱いでGvrMainやGvrHeadなどのprefabが使える最後のバージョン。
例の"You must enable dynamic library loading in VrCore to get the latest C++ GVR Updates"
がこのバージョンから必要になります。

UnityのネイティブVRサポートに対応しているはずですが、Unityバージョンの組み合わせが大変そうです。
Unity5.5以下のバージョンであれば1.40.0が最後のリリースです。

## 1.50.0
Unity5.6以降のみ対応。UnityネイティブVRサポート対応(旧形式サポートは完全切り捨て)。旧バージョンのprefabやscript類を削除、などドラスティックな変化があります。
また、2017/5/18時点では公式のドキュメントが追従していないため、ちょっと試すには勇気が必要です。
windowsでFinagleのQuickStart

ここ参考に
https://twitter.github.io/finagle/guide/Quickstart.html

コマンドプロンプトだと‘‘ではなく、""なので注意

```コマンドプロンプト
git clone https://github.com/twitter/finagle.git
cd finagle/doc/src/sphinx/code/quickstart
sbt compile
sbt "run-main Server"
```

port 8080が使われていたため、エラーが発生した場合、下記をコマンドプロンプトに入力

```
netstat -nao|find "8080"
```

一番右に表示されるPIDを参考に、タスクマネージャ>詳細で探して停止

私の場合、Jenkinsのportと被っていました。ご注意を。
RailsのActionCableに設定したURL以外から接続する方法

## 概要
- RailsのActionCableはサーバで設定したURL以外からはアクセスできない
- しかし、テストなどで他のURLからアクセスしたいことがある
- HTTPヘッダのOriginを偽装することでアクセスできる

## 背景
ActionCableを使ったアプリケーションの負荷試験のため、任意のクライアントで動作するスクリプトからActionCalbleに接続したくなった。
しかし、単純にやると接続に失敗してしまう。
これはCSRF(Cross Site Request Forgeries)を防ぐための機能によって、Railsで指定したサイト以外からのアクセスを拒否するようになっているためである。

- `config.action_cable.disable_request_forgery_protection = true` と設定し、セキュリティ機能を無効化する
- `config.action_cable.allowed_request_origins` でスクリプトを実行するURLを許可設定に追加する
    - 正規表現の配列を指定し、許可するURLを設定できる
    - 通常、ActionCableを使用するアプリケーションのURLをセットする

のようなサーバ側の設定変更による対応(参考: [ActionCableをwebsocket APIとして使ってUnityと通信する](http://qiita.com/wakaba260/items/b23721d5cfd73cd47ada))も可能ではあるが、テストのためにサーバの設定を変更するのは、できれば避けたい。


## 対応
ということで、テストスクリプト側で工夫する。

まず、ActionCableのCSRF対策機能が何をやっているかを見てみる。
この機能は単純で、HTTPヘッダのOriginを見て、それが設定した許可URLに合致した場合にだけ接続を許可するようになっている。
つまり、HTTPヘッダさえ偽装すれば、CSRF対策を回避し、接続できるという寸法である。

以下はその実例である。
テストスクリプトにはRubyを使用し、ActionCalbeのwebsocketへの接続は先人の作ってくれたgemを利用している。

```ruby
# Rails側で、このようにOriginが設定されているものとする
config.action_cable.allowed_request_origins = ["https://myapp.example.com"]
```

```ruby
# websocket-client-simpleを使う場合の例
origin_url = "https://myapp.example.com"
ws_url = "https://myapp.example.com/cable"
ws = WebSocket::Client::Simple.connect(ws_url, headers: { Origin: origin_url })
```

```ruby
# websocket-eventmachine-clientを使う場合の例
ws = WebSocket::EventMachine::Client.connect(uri: ws_url, headers: {"Origin" => origin_url})
```

以上で、CSRF対策を有効にしたまま、ActionCableに接続することができる。
mysql"p"umpでバックアップしたデータを別名データベースにリストアする

# mysql"d"umpじゃないよ mysql"p"umpだよ

けっしてtypoじゃないのです。「mysqlダンプ」じゃなく「mysqlパンプ」の話になります。MySQL5.7の新機能です。なんでこんなややこしい名前にしたのか…

ざっくり特徴を上げると

- 並列ダンプ
- 出力の圧縮機能オプション
- バックアップ時に進捗がでる

などが上げられます。基本的には「mysqlダンプ」とほぼ同様の使い方ですので慣れている人は同じ感覚で使えます。詳しくはこちらをご覧頂くなどしてください。

MySQL 5.7 Reference Manual 
https://dev.mysql.com/doc/refman/5.7/en/mysqlpump.html

mysqlpumpの紹介(MySQL Server Blogより)
https://yakst.com/ja/posts/3042

# mysql"p"umpのバックアップをリストアしようとした際に困ったことが起きた件

仕事でこの春にリリースしたサービスがありまして、1日1回深夜にバックアップをとっているのですが、新し物好きの私は「mysqlパンプ」を使っておりました。幸い、サービスで大きなトラブルも出ていないので、このバックアップを使うことはないのですが、ちょっと調べ物をしようと手元の開発環境にこの本番環境のバックアップを使ってリストアしようとしたところ、以下のようなエラーが出ました。

```
# mysql -u root -p[PASSWORD] restore_db < /tmp/backup_db_dump.sql
ERROR 1049 (42000) at line 15: Unknown database 'backup_db'
```

元々は「backup_db」というDB名からのdumpファイルなのですが、リストア先DBは別名の「restore_db」です。

「ああ、この環境には存在しないDBの'backup_db'にリストアしようとして怒られてるのか…」と思って、本番環境のDB（のレプリケーション/サービスから切り離されてる）で再度 --no-create-db オプションを付けてバックアップを作成して、再度リストアを試みたのですが、やはり同様のエラーが出てきます。

？？？

とりあえずダンプしたファイルを開いてみたのですが、どうやらCREATE DATABASE文はないのですが、CREATE TABLE文にリストア元のデータベース名が修飾されているのです。


CREATE TABLE **\`backup_db\`**.\`failed_jobs\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`connection\` text CHARACTER SET utf8mb4 NOT NULL,
\`queue\` text CHARACTER SET utf8mb4 NOT NULL,
\`payload\` longtext CHARACTER SET utf8mb4 NOT NULL,
\`failed_at\` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
;

こんな感じで。同名DBへのリストアは問題ないのですが…　DB名を修飾しないSQLを出力をするオプションがないか探してみたのですが見当たらず。探し方が悪いのか。。。それともかつてあった```RENAME DATABASE```が消えたのと同じ運命？で、危険だからこういう仕様にしたのか？

# 分からんのでとりえあずsedで逃げる

分からんのでsedで逃げました。

```
cat /tmp/backup_db_dump.sql | sed -e "s/backup_db/restore_db/g" | mysql -u root -p[PASSWORD] restore_db
```

DB名が単純だと正規表現をもう少しちゃんと書かないとダメでしょう。これ以外の方法なら、一度同じDB名でリストアした後、MySQLプロセスを停止して、データがあるディレクトリ名を変えてもいいかもしれません（試してないけど）。もし、もっとスマートな方法がありましたら教えていただけますと幸いです。

# 謎

紛らわしい名前といい、この仕様？といい、「mysqlパンプ」謎が多いな。。。
ReactでSVGを読み込んでdata:で埋め込む

いくつかローダーあったけど、これが素直でした。

```
npm i svg-url-loader -D
```

でWebpackの設定は

```js
const path = require('path');

module.exports = {
    entry: {
        console: './src/console/index.js'
    },
    output: {
        filename: './static/dist/[name]/a.js'
    },
    module: {
        rules: [
        {
            test: /\.js$/,
            exclude: /(node_modules|bower_components)/,
            use: {
                loader: 'babel-loader',
                options: {
                    presets: ['env','es2015', 'react']
                }
            }
        },
        {
            test: /\.svg$/,
            use: {
                loader: 'svg-url-loader',
                options: {
                    noquotes: true
                }
            }
        }
        ]
    }
}
```
※上記はこの記述だけではない。「test: /\.svg$/」あたりのオブジェクトが該当箇所です。

ポイントはオプションに`noquotes`を`true`で渡すこと。
最初なにもつけずにやったら<img src="" ... "" >みたいにダブルクォーテーションがかぶった。

SVGの読み込みはとくに特別なことせず

```js
import Logo from '../assets/svg/logo.svg';
```

こういう感じでimportすればOKです。

書きながら「React v15.0」からSVGの云々がサポートされるように云々というのを目にしてしまったけど、
Webpackの設定が悪かったのかコンパイル通らなかったから見なかったことにしよう。
Node.jsをインストールしてみよう

##Node.jsとは？
いろんなサイトで書いているとは思うけど
簡単に言うとサーバーサイドのJavaScriptです。

##今回インストールするもの
1. nvm
2. Node.js
3. npm

##nvmとは
Node Version ManagerといってNode.jsのバージョンを管理する
ためのものです。
Node.jsはバージョンによって動作しないものがある為いろんなNode.jsのバージョンを
インストールしたり、使用するバージョンを変更したりできるnvmはとても便利なので
インストールすることをお勧めします。

##nvmインストール
https://github.com/coreybutler/nvm-windows/releases
上記のURLからzipファイルをダウンロードし、インストールしよう。

node -versionでインストールしたバージョンが見れます。
Macだと node --version

<img width="173" alt="スクリーンショット 2017-05-18 1.30.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/180742/c0af20e3-caef-ca93-e11d-540d03ae18e3.png">

このように表示されたら完了

##Node.jsとは？
Node.jsとはなにか？
知っておくべきことはサーバーサイドのJavaScript
非同期 (I/Oの処理結果を待たず処理を進める)という二つです。

##Node.jsをインストール

node ls-remoteでインストールできるNode.jsのバージョンを見ることができます。
<img width="173" alt="スクリーンショット 2017-05-18 1.32.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/180742/0c3cd368-6ff0-3b2e-288c-eb7defb60082.png">
node install (version)でインストールすることができます。
インストールしたらnode -vで確認しましょう。
<img width="137" alt="スクリーンショット 2017-05-18 1.35.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/180742/23b4ac52-51c1-039f-12a8-9badc97e9851.png">
こう出たらインストール完了です！

さて最後にnpmのお話です。

##npmとは？
npmとは簡単にいうとパッケージ管理ツールです。
Node.jsで拡張機能を使いたい際にnpmでインストールしたりします。

##npmインストール
namのインストールは実は完了しています。
なぜならnamはNode.jsをインストールした際に一緒にインストールされるからです！
さてではインストールされているかを確認しましょう！
nam -vとコマンドプロンプトorターミナルで打ってみましょう。
<img width="131" alt="スクリーンショット 2017-05-18 1.46.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/180742/b8457991-e038-2bc5-f153-055fb52489e4.png">
しっかりとバージョンが表示されましたね。
これでインストールの確認ができました。

以上です。
Windowsでnpmからyarnをインストールしたけどyarn initできない

# 経緯

Windows10でJavaScript関連の作業環境を構築するためにyarnを導入しようと思ったが、`yarn init`で引っかかったときのこと

結局 `yarn` だけで実行するのが良さそう

# 環境

## GitBash (MINGW64)

今回は結局こちらを採用しました

|package|version|
|----|----|
|Node|7.10.0|
|npm|4.2.0|
|yarn|0.24.4|

## コマンドプロンプト

|package|version|
|----|----|
|chocolatey|0.10.5|

# ストーリー

## GitBashでてきとーに動かしてみる

webpackやreactを導入したくて、yarnを使おうとしていました。

特に何も調べず、NPMでパッケージをインストール(`npm install -g yarn`)して、
特に何も考えず、リポジトリ上で`yarn init`したところ下記のエラーが発生しました。

```shell-session
yarn init v0.24.4
error An unexpected error occurred: "Can't answer a question unless a user TTY".
```

どうやらこのままでは使用できないご様子でしたが、色々調べながら`yarn`だけで実行してみたら特にエラーなくlockfileが作成されました。

成功？

◆追記(2017/05/29)

コメントにて指摘いただきましたが、package.jsonが出来ていれば良さそうです。

何もないところで`yarn`を実行すると空のlockfileができるだけなので、`yarn add --dev csv`のように必要なパッケージを追加することでpackage.jsonを作成し、これを管理すれば良さそうです。

また、GitBashについてくるwinptyを利用することで、対話形式の`yarn init`が実現できました。詳細はコメント欄に記載のあるとおりです。

## コマンドプロンプトでやろうとしてみる

ただし、以下によるとnpmは非推奨とのこと
[yarn (+ webpack) を使ってみる](http://qiita.com/knjname/items/0cc813622e0121c05723)

推奨されている方法でもやってみました。

コマンドプロンプトを管理者権限で立ち上げて、
`choco install yarn`を実行してインストール完了でした。

意気込んでworkspaceがあるDドライブへ移動しようと思って`cd D:\~~~~`をしました。

ところが、移動に失敗しました。コマンドプロンプトでは、C:直下にいるときに`D:`としないとドライブ移動できないようです

## 決断

コマンドプロンプトでは早々に戦意が失われたので、npmでインストールしたもので進めていこうと思います。

これで作業してみて詰まったら追記します。

# 参考

[Yarn init fails on Windows under Git bash / MinGW / Cygwin #743](https://github.com/yarnpkg/yarn/issues/743)
werckerを使っていてローカルではテストが通るのにCIではコケる場合にデバッグする3つの方法

werckerを使っていてローカルではテストが通るのにCIではコケる場合にデバッグする方法です。
いづれの方法もテスト実行時の状態のdocker imageをローカルに持ってくる方法になります。

## 前提条件　

ローカルでdockerが使えること。

## 方法1: ローカルでCIを実行する

wercker cliをつかってローカルでCIを実行する方法です。

#### wercker cliのインストール(Mac)

```
brew tap wercker/wercker
brew install wercker-cli
```

#### 実行

```
wercker build --no-remove
```

`--no-remove`をつけるとdocker containerが残るので　containerに入ってデバッグします。

## 方法2: werckerでbuildしたimageをpullする

wercker上でbuildしたimageをpullする方法です。
方法1と同様にwercker ciを使います。

#### wercker.yml

以下を追加します。

```yaml:wercker.yml
build:
  after-steps:
    - internal/store-container
```

### wercker pull

wercker上でbuildが走ったあとに以下のコマンドでpullできます。

```
wercker login
wercker pull isule/test
```

githubのアカウントを使っていてログインできない、ってひとは[こちら](https://skatsuta.github.io/2015/07/21/wercker-github-login/)を参照ください。

## 方法3: werckerでbuildしたimageをdockerhubにpushする

方法2は自分の環境では以下のエラーになって実行できませんでした。

```
ERROR No finished builds found for this application
FATAL Exiting.
```

そんなときはwerckerでbuildしたimageをdockerhubにpushしましょう。

#### wercker.yml

以下を追加します。


```yaml:wercker.yml
build:
    after-steps:
        - internal/docker-push:
            username: $DOCKER_HUB_USERNAME
            password: $DOCKER_HUB_PASSWORD
            tag: debug
            repository: my/repository #適宜変更
            registry: https://registry.hub.docker.com
```

`DOCKER_HUB_USERNAME`と`DOCKER_HUB_PASSWORD`を環境変数に追加します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/152997/d2fd9f22-0c11-d42b-7279-ba1eabbb91c3.png)

### 実行

buildを実行すればdockerhubにpushされるはず。

以上です。
Material-UI(α版)でCSS in JS！

## Material-UI α版
[こちらの記事](http://qiita.com/vimyum/items/5ba06ca166ebe4992617)引き続き、React.js向けのマテリアルデザインMaterial-UIについて、αブランチ(v1.0-alphe 14)の機能をみていきます。
現在v0.18ではCSSはLESSによって構築されていますが、v1.0からはCSS in JSの仕組みが提供されるようです。別途CSS-Moduleを入れたりWebpackに設定する必要もないので簡単に利用できそうです。
α版のインストールにはnpmで@nextを指定します。

```shell-session
$ npm install --save material-ui@next
```


## CSSinJS in Material-UI
Material-UIのCSSinJSでは`createStyleSheet`と`withStyles`という2つのAPIを利用します。`createStyleSheet`でDOMに適用するスタイルを生成し、`withStyles`でスタイルを適用したDOMを生成するという手順です。

### createStyleSheet
createStyleSheetは第１引数に名前、第２引数にスタイルのオブジェクト、またはスタイルのオブジェクトを返す関数を指定します。第１引数は単にデバッグ目的に利用されるだけのようです。第２引数に渡す関数の引数`theme`についてはあとで説明します。

```js
import { createStyleSheet } from 'material-ui/styles';

let myStyleSheet = createStyleSheet("myStyle", (theme) => {
    root : {
        color: '#CCC',
        width: '500px',
    },
});
```
### withStyle
withStyleの第１引数には先ほど生成したスタイルを指定します。返り値は高階コンポーネント(higher-order component)です。高階コンポーネントの正しい意味はよくわかりませんが、高階コンポーネントにReactコンポーネント(DOM)を渡してあげると、先ほどのスタイルが適用される新たなDOMが生成されます。
スタイルが適用されるコンポーネントには`props`を通して`classes`プロパティが渡されます。classNameにclassesのプロパティを指定することで、その要素にスタイルが適用されます。

```js
import { withStyles } from 'material-ui/styles';

// いつものReactコンポーネント（ただしpropsにclassesが渡される)
const MyApp = (props) = (
    <div className={props.classes.root}> //渡されたclassesを適用
       Hello World
    </div>
)

// スタイルを適用したコンポーネント
let StyledMyApp = withStyles(myStyleSheet)(MyApp);

// スタイル付きコンポーネントは<MuiThemeProvider>の子要素にする
ReactDOM.render(<MuiThemeProvider><StyledMyApp /></MuiThemeProvider>,
 document.querySelector('#app'));
```

## themeProvider

アプリケーション全体でデザインを統一するためにテーマ(theme)の概念があるようです。themeは`createMuiTheme`で作成して、`MuiThemeProvider`の属性値として渡すことで適用できます。
前述の`cteateStyleSheet`の第２引数の関数に渡される`theme`は`MuiThemeProvider`に適用されたものになります。themeオブジェクトのプロパティはたくさんあるので[こちら](https://github.com/callemall/material-ui/blob/next/src/styles/theme.js)を参照してください。色は[こちら](https://material-ui-1dab0.firebaseapp.com/style/color)を参照。
使い方は例えばこんな感じ。

```js
import { purple, green, red } from 'material-ui/styles/colors';

// 独自テーマを作って
const theme = createMuiTheme({
  status: {
    danger: 'orange',
  },
});

// 適用する
ReactDOM.render(<MuiThemeProvider theme={theme}> ...
```

ただ、実際にはあまりテーマを作成することはなく、テーマはそのまま利用し、自作コンポーネントにそのテーマから値(色とかフォントとか）を適用する、というのがメインになるかなと思います。たとえばこんな感じで。

```js
let myStyleSheet = createStyleSheet("myStyle", (theme) => {
    root : {
       backgroundColor: theme.palette.primary[200],
       color: theme.palette.getContrastText(theme.palette.primary[200]),
       padding: `${theme.spacing.unit}px`,  //余白もテーマで統一できる
    },
});
```

上の例のとおり、paletteに対してgetContrastTextを使うと、背景色に適したテキスト色が選択されます。これで色環とかもう考えなくても良いですね。

## やってみた
適当にテーマをいじったりしてみました。いくらフレームワークがしっかりしていても、マテリアルデザインに則らずに適当に値を指定してしまったので、全然イケてないですね。。

<img width="1431" alt="スクリーンショット 2017-05-18 0.53.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/160451/4e3c39a2-b1d3-47ce-4141-fe5e3e615689.png">


Material-UIを利用することで、見た目に関する色々な機能が(ほぼ)オールインワンで提供されるので、僕のような初学者にはオススメかと思います。
Cookieをオブジェクト形式で取得するJavaScriptコード

##Cookieのリストをオブジェクト形式で取得するJSコード

[document.cookie - Web API インターフェイス | MDN](https://developer.mozilla.org/ja/docs/Web/API/Document/cookie)に載っているやり方だと、同名のCookieが複数あったときに1つの値しか取り出すことができず、不都合があったため作成。

以下のコードによりCookieを取得すれば、オブジェクトの中に配列としてCookieの値を格納しているので、同名のCookieが複数あった場合でもすべての値を取り出すことができる。

###コード
```js:getCookieObj.js
var cookie = {
  getObj : function(){
    var cookie = document.cookie;
    var cookieObj = {};
    if(!!cookie){
      Array.prototype.forEach.call(cookie.split(';'),function(c){
       var array = [c][0].split('=').map(function(a){return a.trim()});
       var key = ~c.indexOf('=')? unescape(array[0]) : '';
       var val = ~c.indexOf('=')? unescape(array[1]) : unescape(array[0]);
       if(!cookieObj.hasOwnProperty(key)){
         cookieObj[key] = [val];
       }else{
         cookieObj[key].push(val);
       }
      });
    }
    return cookieObj;
  },
  getByName : function(name){
    var ret = [];
    var cookieObj = this.getObj();
    if(cookieObj.hasOwnProperty(name)){
      ret = cookieObj[name];
    }
    return ret;
  },
  deleteByName : function(name,path){
    var str = escape(name) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT' + (path ? '; path=' + path : '');
    document.cookie = str;
  }
};
```

##実行例

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103957/4bd6ca17-32ca-9dca-d228-1e91afc2b1ff.png)




**完**
tigがLibrary not loadedとエラーになってしまう現象の対応

# TL;DR

`tig`が以下のエラーを吐いて動かなかったのでいろいろ試した。
結論からいってしまうとHomebrewで使用しているreadlineのバージョンをスイッチすればだいたいOK
そのあとワーニングが出る場合の対処は後述する。


# 対象読者 or 前提条件 or 環境
## 対象者:

- 気軽に`brew update`してしまい急にtigが動かなくなった人

## 前提条件:

- brew経由でreadline入れてる
- brew経由でtig入れてる
- 気軽に`brew update`した OR ついつい間違って`brew update`してしまった

## 環境:

- macOS 10.12.4

## 経緯:

元々のエラーは↓

```
# tigで使用しようとしているlibreadline.x.dylibが見つかんねえぞ！と怒られてる
dyld: Library not loaded: /usr/local/opt/readline/lib/libreadline.7.dylib
  Referenced from: /usr/local/bin/tig
  Reason: image not found
zsh: abort      tig
```

`readline`は確かすでに入れてあったしこの前`tig`コマンドを実行したときは普通に動いてたよなー確かと記憶を探る。
そういえばさっき`brew update`したから動かなくなったのかなー？
…と思い「Library not loaded tig」とかで検索しいくつかのサイトを参考にした。

- [Mac OS10.9にしたらHomebrewで入れていたコマンドとか、いろいろ動かなくなった。](http://chaika.hatenablog.com/entry/2014/06/11/170441)
- [psqlしたらreadlineのエラーが出るようになって](http://blog.skylarking.me/2016/10/07/psql-readline-error/)

で結局原因としてはやはりというか当たり前だが`brew update`したことによって`tig`が求めている`readline`のバージョンが上がったということだった。

```
brew switch readline 7.x.x
```

なので↑のコマンド叩いて問題解決！
とは残念ながらならなかった…。

## `tig`のwarningを消す:

```
tig warning: /usr/local/etc/tigrc:90: status-untracked-dirs has been renamed to status-show-untracked-dirs
tig warning: Errors while loading /usr/local/etc/tigrc.
```

今度は↑のワーニングが出るようになった。
なおワーニングなのでtigそのものは動く、動くんだけどワーニングが表示されたままだと気持ち悪い。
ちなみにどうでもいいがワーニングとカタカナで書くのも書かれているのも気持ち悪い。
置換が面倒なのでこのまま押し通すが。

とりあえず素直にワーニング文を読んだところ、`/usr/local/etc/tigrc` の90行目がリネームされているのはわかった。

出来れば直接いじらずになんとかしたかったがググったりインストール/アンインストールしてもどうにもならんかった。
brewだけで問題を解決するのは難しそう&そこまで時間をかけるほどの価値がないので↓のコードを書き換えた。

```/usr/local/etc/tigrc
# 元々は↓だったがコメントアウトしてリネーム後のものに書き換えた
# set status-untracked-dirs   = yes       # Show files in untracked directories? (status)
set status-show-untracked-dirs  = yes     # Show files in untracked directories? (status)
```

そしてようやくエラーやワーニングに煩わされない快適なtig ライフが戻ってきた。

# あとがき

homebrewは便利なんだけどもこの手の依存関係で時間を取られることがまれにあって鬱陶しい。
依存関係も諸々含めて解決して欲しい。
本質的でないところで時間を取られる感じがしてすごく嫌だ。
とはいえこの手の開発ツールに対する自分の理解度が低い問題もあるので一概に攻められはしないのだが。
【Java入門】javaの演算の基礎（初学者向け）

１年目の駆け出しプログラマです。復習を兼ねて、自分用メモを整理して公開したものです。
間違っている可能性も高いのでお気を付け下さい。

## 心構え
- 学校で習った数学のイメージでやると違いにビビる

```java
x = x + 1;
```
とか

```java
count += 2;
```

とか、プログラマとしては「ああ、はい」といった感じなのだが初めてプログラミングを始めたばかりの人からすると「！？？」となることがある。

- このように一般的な数学の演算子の意味と異なることがあるので、基本的には別の意味と思って臨むことが必要。

その上で共通な所を見出していけばよい。

## 式の構成要素
1. 演算子（Operater）：「＋」「－」「＝」など
2. オペランド（Operand）：演算子以外のこと

## リテラル（Literal）
- ソースコードに記述されている値であり、それ自体が要素となるもの
- オペランドとの違いは、リテラルは記述された値そのものが要素となるが、オペランドは記述された値が要素そのものとは限らない

```java
int a , b;
a = 10;          //10は整数リテラル
b = a + 27;     //a,b,27はオペランドだが、リテラルは27のみ

boolean flag;
flag = true;     //trueはbooleanリテラル
```

## 評価

- 演算子は周囲のオペランドを使って計算を行い、オペランドと共に値へと変化する

```java:例
int numA = 1;
int numB = 2;
int ans = numA + numB;
// 演算子+がnumAとnumBと共に値3へと変化する。

if(numA < numB){
    System.out.println("numAはnumBより小さい");
}
// 演算子>がnumAとnumBと共にtrueへと変化する

System.out.println(numA == numB);
// 実際に文字出力すると、結果はfalseになる
```

## 演算子

- 右記サイトが分かりやすい（丸投げ）。参考）[Javaの道：演算子](http://www.javaroad.jp/index_basic.htm#enzan)

- ざっと表にまとめておく

|種類|演算子|意味（ざっくり）|備考
|:-:|:-:|:--|:--|
|算術演算子|+|足す|
||-|引く|
||*|掛ける|
||/|割る|
||%|余りを求める|
|代入演算子|=|右辺を左辺に代入する|
||+=|左辺に右辺を足した値を代入する|
||-=|左辺から右辺を割った値を代入する|
||*=|左辺に右辺を掛けた値を代入する|
||/=|左辺から右辺を割った値を代入する|
||%=|左辺割る右辺の余りを代入する|
|インクリメント演算子|++|値を1増加させる|a++と++aで意味が異なる<br>†注1
|デクリメント演算子|--|値を1減少させる|a--と--aで意味が異なる<br>†注1
|比較演算子|==|等しい|†注2
||!=|等しくない|
||>|大きい|
||>=|以上|
||<|小さい|
||<=|以下|
論理演算子|&|かつ|
||&&|かつ|短絡評価を行う<br>†注3
|| &#124;|||
||&#124;&#124;|または|短絡評価を行う<br>†注3
||!|否定|

†注1：a++は値を代入してから+1する。++aは+1してから代入する。

```java:例
int a = 0;
int b = 0;
System.out.println(a++);    // 結果は0
System.out.println(++b);    // 結果は1

System.out.println(a);    // 結果は1
System.out.println(b);    // 結果は1
```

でも実際```i++;```とか単独で見ることがほとんどで、区別できないと駄目ってコードは（今の所）見たことないし書いたこともない。
頭の片隅において置けばいいと思う。

†注2：オブジェクトの比較を行う場合注意が必要。参考）[オブジェクトの比較](http://www.okapiproject.com/java/java_ref/foundation/manual_06.htm)
†注3：短絡評価とは

```java
int num = 5;
if(num > 2 || num > 7){
    // 処理Ａ 
} else {
    // 処理Ｂ
}
```

のような処理があった場合、num > 2 の評価が終わった時点でtrueとなることが確定しているためnum > 7の評価を行わない。
このように評価が確定した時点で、以降の不要な評価を行わないことを___短絡評価___という。

## 三項演算子
- 下記のように使用する

```java:書き方
[条件] ? [TRUEの場合の返却値] : [FALSEの場合の返却値] ;
```

- 安易に使用すると可読性が悪い、と言われるため注意が必要。慣れるまでは読むとき専用で覚えるとよい

```java
int n = a > 0 ? 1 : 0 ;
// 意味は以下と同じ

int n;
if(a > 0){
    n = 1;
} else {
    n = 0;
}
```

参考）

- [三項演算子は悪か？](http://qiita.com/stkdev/items/cbb83cbd9921b9f755a4)
JavaScriptでオブジェクトの深い階層に安全にアクセスする

# はじめに
[nullsafe-object](https://github.com/remew/nullsafe-object)というnpmライブラリを[公開](https://www.npmjs.com/package/nullsafe-object)したので紹介します（手前味噌かーい）。

## 概要
オブジェクトの深い階層のプロパティに *自然な形で安全に* アクセスする方法を提供するライブラリです。

## Example
```js
const NullSafeObject = require('nullsafe-object');
const srcObj = {};

// 空のオブジェクトなので普通に下のようにアクセスすると
// Uncaught TypeError: Cannot read property 'info' of undefined
// とか言いながら死ぬ
// console.log(srcObj.deep.property.access);

// NullSafeObjectで包む
const obj = NullSafeObject.wrap(srcObj);

// 深い階層にアクセスして unwrap() メソッドで結果を取得できる
console.log(obj.deep.property.access.unwrap()); // => null

// 存在するプロパティにももちろんアクセスできる
const srcObj2 = {
    exists: {
        property: 'some string'
    }
};
const obj2 = NullSafeObject.wrap(srcObj2);

// unwrap() メソッドは必須
console.log(obj2.exists.property.unwrap()); // => 'some string'

// githubのREADMEに書くの忘れてたけどちゃんと代入もできる
obj.new_property = 'hoge';
// 元のオブジェクトに反映されている
console.log(srcObj.new_property); // => 'hoge'
```
## インストール方法
いつもの
`npm install --save nullsafe-object`
`yarn add nullsafe-object`

## 実現方法
ES2015で追加された`Proxy`を使用しています。`Proxy`については[こちら](http://qiita.com/ToshihiroGoto/items/36a4b355ba274ab25b46)の記事が参考になります。あとはMDNとかを見ていただきたいきもち。
対応ブラウザは[このへん](http://caniuse.com/#search=Proxy)を見ると良いと思います。~~IE11ってなんですか？。~~
`NullSafeObject.wrap`は内部で`NullSafeObject`のインスタンスを作成しており、作成されたインスタンスを`Proxy`に渡してプロパティアクセスをフックする処理が書いてあるみたいな感じです。
プロパティアクセスをフックすると「どのキーにアクセスしたか」がわかるので、アクセスしたキーを順番に保存していきます。
`NullSafeObject#unwrap`を呼び出すと、元のオブジェクトから、保存したキーを順番にたどっていき、途中で`null`だったり`undefined`だったりしたら`null`を返すようにしています。
代入もフックできるので、いいかんじにやってます（キーボード打つのにつかれてきた人が書く解説）（そのうち編集しなきゃ）。

## なぜ作ろうかと思ったか
ぶっちゃけ`Proxy`で何か面白いことできないかなって思ったのが9割くらいですね。
あとは前々から途中に`null`やら`undefined`があってしぬみたいなことがあってストレスが溜まってたのが残りの1割（？）
（実は、全然難しい実装ではないのになんで作られていなかったんだろうと心配になっています。知らないだけで類似ライブラリあったのかな・・・）

## これから対応したい機能
- `Array#map`とかの呼び出しにも対応したい（できるのか不明）（テストコードだけ書いて対応してないせいでテストがしんでる）
- ~~`obj._root` `obj._path`とかやると、もとのオブジェクトの`_root`や`_path`ではなく、クラス内部で使用している管理用オブジェクトに触れることができてしまうのでそれをなんとかしたい（方針は立っていて、`Symbol`を使えば良さそう）~~ => 対応しました

## さいごに
使用感の報告やIssueやプルリクをいただけると泣いて喜びます！
RoR｜GETでアクセスするアクションが複数あったらどうするか

Ruby on Railsでコントローラーの中でアクションは違えど
同じHTTPメソッドを使っている場合にどう住み分けをするかという話。

### 準備
scaffoldで本（Book）についてのコードを自動生成します。

```
$ rails g scaffold book title
```

本についての情報をすべてCSVでダウンロードする`BooksController#download`を作成します。
ルーティングは`get`を使って追加します。

```ruby
Rails.application.routes.draw do
  resources :books
  get 'books/download'
end
```

`/books/download`にアクセスすると対応する`BooksController#show`が実行されます。
ルーティングはroutes.rbの上にある設定値が優先されるため`download`があたかも`id`のように処理されて例外が発生しています。

![Error#1.png](https://qiita-image-store.s3.amazonaws.com/0/137044/a3aa57c5-4a7f-d4b7-0396-9aab2c2b900d.png)

### 対策
ベストではないですが、URLフォーマットを特定の形式に制限するとうまくいきました。
`:id`はすべて整数値であること期待するようにします。

つまり、`/books/5`といった`:id`が整数なアクセスであれば`BooksController#show`を実行するように制限すると、
その他のHTTPメソッドがGETであるルーティングはroutes.rbに準ずるようになりました。

```ruby
Rails.application.routes.draw do
  resources :books, constraints: {id: /[0-9]+/}
  get 'books/download'
end
```

`format`を利用してアクションを切り替えてもいいかもしれません。
~~CSVダウンロードだったら別にコントローラを作れという説もあります。~~

### 検証環境
Ruby 2.4
Rails 5.1.1
reduxでimmutablejsの代わりにObject Spreadを使う

[reduxの公式サイト(Using Object Spread Operator)](http://redux.js.org/docs/recipes/UsingObjectSpreadOperator.html)に書いてある話です。

# 結論

こうだったり

```js:Object.assign
case SET_FUGA:
  return Object.assign({}, state, {
    hoge: { fuga: action.fuga }
  })
```

こうだったのが

```js:immutablejs
case SET_FUGA:
  return state.setIn(['hoge', 'fuga'], action.fuga)
```

こうなります

```js:ObjectSpread
case SET_FUGA:
  return { ...state,
    { hoge: { fuga: action.fuga } }
  }
```

# 必要なこと
[babelのpreset](http://babeljs.io/docs/plugins/transform-object-rest-spread/)をつかいます。

```json:.babelrc
{
  "plugins": ["transform-object-rest-spread"]
}
```

# immutablejsのデメリット

[本家曰く](http://redux.js.org/docs/recipes/UsingImmutableJS.html#what-are-the-issues-with-using-immutablejs)

- 他のライブラリとの共存
- コード全体で使うことになる
- object spreadと併用できない
- 小さい変更を行うreducerには適さない
- デバッグが難しい

同時に

> これらの問題はすべて、慎重にコーディングすることで簡単に解決できます。」

とも語られています。

# ちなみに
FlowtypeはObject Spreadをちゃんと解釈してくれます。安心。

# なぜこれを書いたか
Immutablejsがデファクトスタンダードであるかのような話を耳にするのですが、公式サイトだと結構デメリットも語られてて、そのへんの温度感が気になったので書いてみたくなったのでした。
Object Spreadは特にreducerが小さく設計できてるときに簡単に書けるのが魅力な気がします。
本当に必要に迫られたときに必要なだけImmutablejsを使うのが良いように思います。
でもImmutablejsを導入するまえに[icepick](https://github.com/aearly/icepick)も検討されたい。。。こちらはリスク低いですよ。
順番に表示　基本メモ

順番に表示させる記述です。

```js
    function jun(){
      let acco_02 = {
          click_t : $("要素"),
          child : $("要素"),
      };

      let fadeFn = function(){
        $(要素).click(function() {
          $(要素).each(function(i) {
                  $(this).delay(500 * i).fadeIn(1000);
            });
        });
      };
      fadeFn();
    }
```
forを使う方法と、

```js
   var acco_02 = function() {
        var click_t = $("要素");
        var target = $("要素");
        var child = target.children();
        var len = child.length;
        var f = function(){
          for (var i = 0; i <= len; i++) {
            var arr = child[i];
            $(arr).delay(500 * i).fadeIn(1000);
        }
        };
        
        click_t.click(function(){
           f(); 
        });
    };
    acco_02();
```

です。もっとうまいことかけると思います。
かなり、鈍臭くなってしまいました。自分で編集するかもですが。。。

いい書き方ぜひ伺いたいです。

ポイントは、順番に表示させたい要素をnoneしといて、時間差でfadeInするといったことです。

では、参考までに
たった2行で自動テスト時のmockが作れちゃうmockeryに感動したのでポエムを綴ってみました

# mockeryとは

ReflectionClassやPHPUnit内蔵のMockBuilderを小難しく使わずとも2行でmock作れます。そうmockeryならね。

# もうちょっと詳しく

とりあえずサンプル見てもらえると早いと思います。

```php
<?php
$mock = Mockery::mock('Hoge');
$mock->shouldReceive('fuga')->andReturn('hogehogefugafuga!');

echo $mock->fuga(); // hogehogefugafuga!
```

`Mockery::mock('Hoge');`で指定しているクラス名`Hoge`は実在するクラスを指定すれば、そのクラスを継承したmockを作成するとのことです。
テキトーな文字列を指定した場合は空のクラスのmockを作成します。

これだけだとイマイチ凄さが分かりませんが、私が感動したのは下記の方法。

```php
<?php
class Hoge
{
    public static function getFugaName()
    {
        $fuga = new Fuga();
        return $fuga->getName();
    }
}

class Fuga
{
    public function getName()
    {
        return 'fuga';
    }
}

$mock = Mockery::mock('overload:Fuga');
$mock->shouldReceive('getName')->andReturn('overwritten fuga');

echo Hoge::getFugaName(); // overwritten fuga
```

なんと`:overload`プレフィックスをつけることで、テスト対象（上の例の場合は`Hoge`）の内部で生成している`Fuga`を上書きしてmockを使用させることができます。
Mockeryを使用する前は苦肉の策でメンバ変数や引数などで`Fuga`インスタンスを渡せる仕組みを`Hoge`に実装していて、あんまりイケてない感じがして好きじゃなかったのですがこんなにお手軽に解決できるとはびっくらぽんです。

もちろんPHPUnitのMockBuilderで可能な、引数によって返却値を変える仕組みや、`once()`や`twice()`等のメソッドを呼ぶ回数に制限を掛ける等もできます。
さらにあれこれ返却値を決定する際に処理が必要な場合は`andReturnUsing()`なんてものもあって至れり尽くせりです。

```php
<?php
class Hoge
{
    public static function foo()
    {
        $fuga = new Fuga();
        return $fuga->fugaMethod('引数1', '引数2', '引数3');
    }

    public static function bar()
    {
        $fuga = new Fuga();
        return $fuga->fugaMethod('引数4', '引数5', '引数6');
    }
}

class Fuga
{
    public function fugaMethod()
    {
        //何か色々処理
        return true;
    }
}

$mock = Mockery::mock('overload:Fuga');
$mock->shouldReceive('fugaMethod')->andReturnUsing(function() { return func_get_args(); });

$foo = Hoge::foo(); // array('引数1', '引数2', '引数3')
$bar = Hoge::bar(); // array('引数4', '引数5', '引数6')
```

# 参考にさせていただいたドキュメント
インストール方法や更なる使い方については下記の記事にて詳しく解説されておりますのでそちらを参照されると良いかと思います。
（というかcomposerならインストール一発です）
・Mockery 0.8.0 日本語ドキュメント
https://kore1server.com/202/Mockery+0.8.0+%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88
・「Mockery」を使ってサクッとPHPのテストを書いてみる
http://tech.aainc.co.jp/archives/3918
・MockeryとPHPUnitを使う（最低限）
http://qiita.com/zaburo/items/b559782179565bb1c538

# 最後に
ここまでお読みいただきありがとうございました。
皆様も良きMockeryライフを！ｖ・。・ｖ
Raspberry Piまとめ


## RasPiコマンドまとめ
* Shutdown
`$ sudo shutdown -h now`
* Reboot
`$ sudo shutdown -r now`, `$ sudo reboot`
* ssh config (.ssh/config)
  ```
  Host Sample
        HostName xxx.xxx.xxx.xxx
        User sampleUser
        ServerAliveInterval xx
  ```

## RasPi設定まとめ
### Raspiのupdate
`$ sudo rpi-update`で実行

その後`$ sudo reboot`で再起動

### rootのパスワード設定

```
pi@raspberrypi:~ $ sudo passwd root
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
```

root userでログインできるか確認

```
pi@raspberrypi:~ $ su
Password:
root@raspberrypi:/home/pi# exit
```

### pi userのパスワード設定
```
pi@raspberrypi:~ $ sudo passwd pi
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
```
### user (sampleUser)加える
```
pi@raspberrypi:~ $ sudo adduser sampleUser
Adding user `sampleUser' ...
Adding new group `sampleUser' (1001) ...
Adding new user `sampleUser' (1001) with group `sampleUser' ...
Creating home directory `/home/sampleUser' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for sampleUser
Enter the new value, or press ENTER for the default
	Full Name []: < 空白でOK
	Room Number []:
	Work Phone []:
	Home Phone []:
	Other []:
```

### piと同様の権限をsampleUserに渡す
まずpiがどの権限を持ってるのか確認

```
pi@raspberrypi:~ $ groups pi
pi : pi adm dialout cdrom sudo audio video plugdev games users input netdev spi i2c gpio
```
この権限をsampleUserに渡し、最後に`$ groups sampleUser`で権限確認

```
pi@raspberrypi:~ $ sudo usermod -G pi,adm,dialout,cdrom,sudo,audio,video,plugdev,games,users,netdev,input,spi,gpio sampleUser
```

## SSH KeyをRasPiに渡す
Terminal 2つ [Local]と[Raspi]開きましょう (keygenミスったりすると入れなくなります)
#### 1. Keyを作成
`[local]$ ssh-keygen -t rsa`により`~/.ssh/id_rsa`にpublic keyとprivate key作成される
#### 2. KeyをRaspi側に移す
`[local]$ scp id_rsa.pub yourRasPiAddr:~/.ssh`public Keyを移動

#### 3. public Keyをauthorized_keysに書き出す
```
[Raspi]@raspberrypi:~/.ssh $ cat id_rsa.pub >> authorized_keys
[Raspi]@raspberrypi:~/.ssh $ ls -a
.  ..  authorized_key  id_rsa.pub
```
#### 4. 権限設定
```
[Raspi]@raspberrypi:~/.ssh $ chmod 600 authorized_key
[Raspi]@raspberrypi:~ $ chmod 700 .ssh
[Raspi]@raspberrypi:~/.ssh $ su
Password:
root@raspberrypi:/home/[Raspi]/.ssh# cd /etc/ssh
```
#### 5. デーモン書き換え
```
root@raspberrypi:/etc/ssh# vim sshd_config
```

以下のファイル書き換え

```
AuthorizedKeysFile      %h/.ssh/authorized_keys
PasswordAuthentication no
PermitRootLogin no
```

#### 6. デーモン再起動
```
[Raspi]@raspberrypi:~/.ssh $ sudo /etc/init.d/ssh restart
[ ok ] Restarting ssh (via systemctl): ssh.service.
```

#### 7. RasPiに[local]から接続
[Slack]チャンネルのピンが外されたら再度ピンしてくれるBot

Slackには `Pin` という機能があります。
重要なメッセージやファイルなどをチャンネルにピン留めしておくことで
いつでも参照できるという機能です。

先日、新たに参加したメンバーがSlackの使い方をよく理解しておらず、
チャンネル内にピン留されたメッセージなどをすべてはずしてしまうということがありました。

そこで誤ってピンが外れされてしまったとしても、再度自動でピンをしてくれるBotを
botkitを使って作成してみました。

#　成果物
![repin_bot4.gif](https://qiita-image-store.s3.amazonaws.com/0/55219/b58eb9df-c41f-e373-2ac2-a440c61447cc.gif)

ピンが外れされたら、外した人へ警告メッセージを送信すると同時に
再度ピン留を行っています。

ピンを外したい場合は特定のキーワードを発言することで、
一定時間のみピンをはずすことができます。

# コード

```javascript:bot.js
if (!process.env.token) {
  console.log('Error: Specify token in environment');
  process.exit(1);
}

var Botkit = require('botkit');

var controller = Botkit.slackbot({
  debug: false
});

var bot = controller.spawn({
  token: process.env.token,
  retry: true
}).startRTM(function(error){
  if(error){
    throw new Error(error);
  }
});

let canPinRemoved = false;

controller.hears('ピンはずさせてやー', ['direct_message', 'direct_mention', 'mention'], (bot, message) => {
  canPinRemoved = true;
  bot.reply(message, '30秒だけ待ったる');
  setTimeout((bot, message) => {
    canPinRemoved = false;
    bot.reply(message, 'ほい時間ぎれー');
  }, 10000, bot, message);
});

controller.on('pin_removed', function(bot, message) {

  if(canPinRemoved) return;

  bot.api.users.info({
    user: message.user
  }, function(error, result){
    if(error) console.log(error);

    let userName = result.user.name;

    bot.api.pins.add({
      channel: message.channel_id,
      timestamp: message.item.message.ts
    });

    bot.say({
      text: `ちょっと @${userName} はん。 勝手にピンはずさんといてやー。\nしゃあないからもっかいピンしといたでー`,
      link_names: true,
      channel: message.channel_id
    });
  });


});

```

controller.on で `pin_removed` イベントを待機します。
イベントが発生したら `message` オブジェクトから必要な値を取得していきます。
ここではイベントを発生したユーザーがIDで渡ってくるので
`users.info` API を使用してユーザー名を取得しています。

ピン留は `pins.add` APIを使用して行っています。
ここでは `timestamp` に対象のメッセージのtimestampを設定することで
メッセージのピン留めを行うことができます。

今回の実装ではファイルなどのピン留めには対応していないため、
また対応できるようにしていきたいです。


コードは[こちら](https://github.com/tamanugi/repin-bot)にもあげております。
'str' object has no attribute 'get'

###事象
aws cliでs3コマンドを実行するとタイトルのエラー。
<pre>
$ aws s3 ls

'str' object has no attribute 'get'
</pre>

###原因
.aws/configのs3署名バージョン部で改行が入っていない。

(誤)
<pre>
$ cat .aws/config
[default]
output = json
region = ap-northeast-1
s3 = signature_version = s3v4
</pre>

(正)
<pre>
$ cat .aws/config
[default]
output = json
region = ap-northeast-1
s3 =
      signature_version = s3v4
</pre>
※[]内は各々で定義したprofile名です。

IAM権限が足りない場合(s3:ListBucketが無い)でも同様のエラーが発生しました。

切り分けのためにpython、boto、aws cliのバージョンやIAMを見て少し長引いたため共有です。
rails does not reload on vagrant

confirm on rails 5.0.3 

http://stackoverflow.com/questions/35959490/rails-server-doesnt-see-code-changes-and-reload-files

http://stackoverflow.com/questions/28878832/rails-does-not-reload-controllers-helpers-on-each-request-in-freebsd-9-1

https://github.com/rails/rails/issues/16678

https://github.com/burke/zeus/issues/388
Swiftをもう一度勉強してみた#2

# はじめに
趣味でSwiftをもう一度書こうと思い、ブログを書きました。
つまり、ブログの宣伝です。

※注意：
私自身の勉強備忘ブログでもあります。
そのため、表現等が誤っている可能性もあります。
もしお気付きの場合はご指摘、ご鞭撻等を頂ければ幸いです。
また、質問等も受け付けておりますので、ご気軽にコメントいただけると幸いです。
(ブログへのコメント欄、本記事でのコメント欄どちらでも構いません。)

# ブログ内容
今回は**「フローの制御に関して」**をテーマにしています。
取り扱う内容は以下の通りです。
○ **`if文`**
○ **`switch文`**
○ **`for-in文`**
○ **`while文`**

※注：「**`for-in文`**」と「**`while文`**」については記事は、
今後追加する予定ではありますが、
(2017.05.17現在)書かれていない状態です。
ご了承ください。

# ブログはこちら
[Swiftをもう一度勉強してみた#2](https://fumisite.net/2017/04/17/swift%e3%82%92%e3%82%82%e3%81%86%e4%b8%80%e5%ba%a6%e5%8b%89%e5%bc%b7%e3%81%97%e3%81%a6%e3%81%bf%e3%81%9f2/)

# 改定履歴
-
ItemTouchHelperのドラッグ&ドロップでArrayListも並び替える

RecyclerViewで使うItemTouchHelperは簡単にドラッグ&ドロップやスワイプを実装できます。

しかし、ドロッグ&ドロップでは内部的にリストデータの順番を変えることはできない？
ので、そのリストを保存しても次回起動時に元に戻ってしまう。
そこで少しコード追加。

といっても単純。

```java
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target)
{
    final int fromPosition = viewHolder.getAdapterPosition();
    final int toPosition = target.getAdapterPosition();
    recyclerAdapter.notifyItemMoved(fromPosition, toPosition);
    //追加ここから
    String temp = arrayList.get(fromPosition);
    arrayList.remove(fromPosition);
    arrayList.add(toPosition, temp);
    //ここまで
    return true;
}

```

消してから追加するのがポイント。
GCE(Google Compute Engine)のVMインスタンスのアカウントスコープを後から変更する

# GCE(Google Compute Engine)のVMインスタンスのアカウントスコープを後から変更する
GCEのVMインスタンスでアカウントスコープを途中で変更したい場合、少し工夫する必要があったのでメモ。

## アクセス スコープとは
それぞれのGoogle Cloud Platform上のサービスのAPIに対して、インスタンスがアクセスを許可されている範囲のこと。
Google Cloud Platform上の各サービスのAPIに対して、インスタンスがアクセス可能かどうかを「有効」/「無効」で表している。
これが有効のサービスのみ、インスタンスはそのサービスのAPIにアクセスすることができる。
https://cloud.google.com/compute/docs/access/service-accounts?hl=ja

## アクセススコープを変更する

### アクセススコープを変更するには
ここからが本記事の本題だが、アクセススコープは、インスタンスの作成時か、インスタンスをシャットダウンしている状態でしか編集できないようだ。

そのため、「そのインスタンスで当初BigQueryのAPIを使う予定がなかったので、アクセススコープは、『無効』にしたが、後にやっぱりBigQueryのAPIを使いたくなったので、アクセススコープを『有効』にしたい」
という場合は、前述したが以下の2つの方法しかない。(他にあったら教えてください…)
1.  インスタンスを作成し直す
2. インスタンスをシャットダウンして変更する                                                                                   

自分は当初それを知らなかったため、VMインスタンスのコンソール画面で何回編集を押してもアクセススコープが変更できなくて、泣きそうになりました。

今回は、「2.インスタンスをシャットダウンして変更する」を行い、アクセススコープを変更する。

### アクセススコープを変更するための手順

アクセススコープを変更するためには以下の手順が必要
1. アクセススコープを変更したいVMインスタンスをシャットダウンする
2. gcloudコマンドで、アクセス権を変更する
3. インスタンスを再起動する

### 実際にやってみる
1.アクセススコープを変更したいVMインスタンスをシャットダウンする
以下の公式ドキュメントを参考にVMインスタンスをシャットダウンする
https://cloud.google.com/compute/docs/instances/stopping-or-deleting-an-instance

2.以下のcloudコマンドで、アクセス権を変更する

```
gcloud beta compute instances set-scopes projects/プロジェクト名/zones/ゾーン/instances/インスタンス名  --service-account サービスアカウントのメール <—no-scopes(無効にしたい場合) か --scopes(有効にしたい場合)>  変更するスコープ
```

「変更するスコープ」は、以下の一覧にあるurlかエイリアスを使用する
https://cloud.google.com/sdk/gcloud/reference/beta/compute/instances/set-scopes

3インスタンスを再起動する
https://cloud.google.com/compute/docs/instances/restarting-an-instance#restarting_a_stopped_instance


### 実際にやってみた
実際にインスタンス作成時には「無効」であったBigqueryのアクセススコープを「有効」に変更する。

「1. アクセススコープを変更したいVMインスタンスをシャットダウンする」と「3. インスタンスを再起動する」は、省略

gcloudを実行
```
gcloud beta compute instances set-scopes projects/プロジェクト名/zones/ゾーン/instances/インスタンス名  --service-account サービスアカウントのメール --scopes https://www.googleapis.com/auth/bigquery
```

結果
VMインスタンスのコンソールの「Cloud APIアクセス範囲」のBigQueryが「無効」から「有効」になった。

## 参考にさせていただいたサイト


https://cloud.google.com/compute/docs/access/service-accounts?hl=ja

https://cloud.google.com/compute/docs/instances/stopping-or-deleting-an-instance

https://cloud.google.com/sdk/gcloud/reference/beta/compute/instances/set-scopes

https://cloud.google.com/compute/docs/instances/restarting-an-instance#restarting_a_stopped_instance

http://stackoverflow.com/questions/31855049/how-to-change-the-scope-of-compute-engine-service-account-to-write-data-on-googl
検索値が複数該当する時に2つ目以降の数値をVLOOKUP関数で抽出する

![VLOOKUP2つめ.png](https://qiita-image-store.s3.amazonaws.com/0/160563/3fc3c52f-8485-7861-1784-719e0edf15f0.png)


#利用シチュエーション

* VLOOKUP関数を用いて検索値の二つ目以降のデータを抽出したい時

##直面した問題
　×　VLOOKUP関数では検索値に引っかかる値が複数ある時に、最初に引っかかった値しか抽出しない

#記述方法
```
=VLOOKUP(検索値,INDEX(元データの検索値,MATCH(検索値,元値の検索値,0)+1):元の値の2列目最末行,2,)

<記述例>
=VLOOKUP(A2,INDEX(E2:E13,MATCH(A2,E2:E13,0)+1):F13,2,)

<補足>
※3個目、4個目を抽出したい場合は+1の値を1ずつプラスする
```

**前提条件**
A列に購入日(下に行くごとに1日ずれる)
E列・F列に「購入した日」と「購入した商品」を上から記載
![抽出前.png](https://qiita-image-store.s3.amazonaws.com/0/160563/13e86a2b-1e95-4b9a-cbf2-49c7b761f393.png)





---

**抽出結果**
![抽出後.png](https://qiita-image-store.s3.amazonaws.com/0/160563/2adef7de-32c5-5fae-c163-93c99ec0f7d3.png)






---

**解説**

**範囲の抽出**

* INDEX関数で指定した範囲内で検索値に引っかかる行数をMATCH関数で指定。
* 抽出した行数より1つ下(+1)から商品名の一番下までをVLOOKUPの検索範囲に指定。
* 指定した範囲の2行目から該当のデータを抽出。


####個々の関数の説明####
INDEX関数は指定された行と列が交差する位置にあるセルの値を返す

||書き方|利用例|
|:---|:---|:---|
|書式|INDEX(範囲, 行番号, 列番号, 領域番号)|INDEX(E2:E13,E3:F13,2)|
|引数1|1つまたは複数のセルのを範囲を指定|E3:F13|
|引数2|指定した範囲の上からの行数を指定|2|
|引数3|指定した範囲の左からの行列数を指定|(省略)|
|引数4|複数の領域を選択した場合、どちらの範囲を使用するか指定||

MATCH関数は、指定したセルの範囲から検索値が上から何番目にあるかを返す

||書き方|利用例|
|:---|:---|:---|
|書式|MATCH(検査値, 検査範囲, 照合の型)|MATCH(A2,E2:E13,0)|
|引数1|検索する値またはセル参照を指定|A2|
|引数2|検索するセルの範囲を指定|E2:E13|
|引数3|1、0、-1の数値で指定(0は完全一致)|0|

VLOOKUP関数は、指定された範囲の1列目で値を検索し、その指定範囲内の別の列の同じ行にある値を返す

||書き方|利用例|
|:---|:---|:---|
|書式|VLOOKUP(検索値, 範囲, 列番号, 検索の型)|VLOOKUP(A2,E3:F13,2)|
|引数1|検索する値またはセル参照を指定|A2|
|引数2|2列以上のセル範囲を指定|E3:F13|
|引数3|目的データが入力されている列番号を指定|2|


#サンプル

* [Googleスプレッドシート](https://goo.gl/svhkyt)

##補足
```
サンプルシートでは、2つめの商品がある場合のみVLOOKUPを実行するようにIF関数で制御
=IF(COUNTIF(E2:E13,A2)<2,"",VLOOKUPで検索)
```
Visual Studio Code を外部エディタから開く。

# リンク
この記事は、次の記事と相互リンクです。
[Visual Studio Code から外部エディタを開く。 - Qiita](http://qiita.com/standard-software/items/785e3c27865a8e8d0b92#_reference-592e100b6df0ed455312)

# はじめに
Visual Stusio Code (VSCode) を、EmEditor から開く例です。
EmEditorの外部エディタとして、VSCodeを、カーソル(キャレット)のある行を維持したまま起動できます。

他のエディタからでも、コマンドを呼び出せるなら、同じやり方で動かせると思います。

環境はWindows
VSCodeのコマンドライン引数を指定して呼び出すだけです。

# 設定は次の通り
EmEditorの外部ツールに登録してください。

| 設定名  | 内容 |
|--- | --- |
| タイトル: | VSCodeでこのファイルを開く |
|コマンド: | C:\Program Files (x86)\Microsoft VS Code\Code.exe|
|引数: |. -r -g "$(Path)":$(CurLine):$(CurCol)|
|初期ディレクトリ: |$(Dir)|

VSCodeは基本的にフォルダ単位でプロジェクトとして扱うので、初期ディレクトリの設定をしないと、ファイルは開いているけどプロジェクトは開けてない、という状態でいまいちになるので、しっかりと初期ディレクトリも設定しておいてください。

あと、Code.exe はパスが通っているので、フォルダパスなしの、Code.exe とか Code とかでもいいのかな、と思って試してみたらだめでした。フルパスで設定してください。これはEmEditor側の制限だと思います。

あと、エディタによっては、引数に列を渡せないようなものもあると思いますので、そこは適切に調整してみてください。


# 参考にした記事

* [VSCodeをVSから開く - SourceChord](http://sourcechord.hatenablog.com/entry/2015/07/17/222937)
git checrry-pickとコンクリフトについて

開発中に一部の機能を先行リリースして欲しいとの要望があり、gitについて調べてみると「cherry-pick」という便利なコマンドがあったので備忘録も含め、纏めたいと思います。

##cherry-pickとは
あるコミットの内容を任意のブランチに取り込むコマンド。

##使い方
```
#取り込みたいブランチに移動
git checkout <ブランチ名> 

#取り込みたいコミット内容のIDを指定
git cherry-pick <コミットID>
```
#コンクリフトが発生する場合がある
無事に変更内容が取り込めたかと思えばコンクリフトが発生。
「cherry-pick」コマンドを使用した際のコミット履歴は以下の通りとなります。

```
Ａ―Ｃ'(master)
　＼
　　Ｂ―Ｃ(develop)
```

Ａ：初期（「001.txt」の内容："a"）
コミットID：d5737ed658e4d75dd5b67cb7a26e2b52f7e399aa

Ｂ：「001.txt」に"b"を追記
コミットID：8cfe601d9fb9b0420441a41907d580b5909ea3b3

Ｃ：「001.txt」に"c"を追記
コミットID：9526e7a62cfa426adcaf0abd164e9cf6410ed47c

Ｃ'：Ｃをcherry-pick
コミットID：fe8661427c7f57c06728b3eafcee58efed1f47f1

##コンクリフトが発生した手順
①「master」ブランチには001.txtというファイルがあります。<br/>

```text:001.txt
a
```

②「master」ブランチを元に「develop」ブランチ作成。

```
git checkout master
git branch develop
```

③「develop」ブランチに切り替えて001.txtに"b"を追記。

```
git checkout develop
```

```text:001.txt
a
b
```

④コミット、プッシュし「develop」ブランチのリモートリポジトリに変更内容を適用。

```
git add 001.txt
git commit -m "変更内容bを追記"
git push origin develop
```

⑤さらに001.txtに"c"を追加し、上記と同様にコミット、プッシュ。

```text:001.txt
a
b
c
```

```
git add 001.txt
git commit -m "変更内容cを追記"
git push origin develop
```

⑥「master」ブランチにCの内容を取り込みたいので「master」ブランチに切り替え「cherry-pick」を行う。

```
git checkout master
git cherry-pick 9526e7a62cfa426adcaf0abd164e9cf6410ed47c
```

##コンクリフトが発生した理由
「cherry-pick」はあるコミットの変更内容を取り込むコマンドの為、上記の様にCの変更履歴がBに依存する関係の場合はコンクリフトが発生する。
（ここが「merge」コマンドとは違う点。「merge」は変更履歴を含め取り込む。詳しくは「3wayマージ」で調べてみると分かると思います。）

#おまけ
複数のファイルでコンクリフトが発生した時に便利なコマンド。

```
git checkout --ours <ファイル名>
⇒マージ元（チェックアウトしているブランチ側）
git checkout --theirs <ファイル名>
⇒マージ先
```

半角スペースを空けることで複数のファイルを指定可能。