OmniAICreator/Qiita-1.07M huggingface dataset:
laravel で redis を使おうぜ

#predis をインスコ

```

composer require predis/predis

```

#database.php

```

    'redis' => [

        'client' => 'predis',
        'default' => [
            'host' => env('REDIS_HOST'),
            'password' => env('REDIS_PASSWORD'),
            'port' => env('REDIS_PORT'),
            'database' => env('REDIS_DB'),
        ],

        'cache' => [
            'host' => env('REDIS_HOST'),
            'password' => env('REDIS_PASSWORD'),
            'port' => env('REDIS_PORT'),
            'database' => env('REDIS_DB'),
        ],

    ],
```

# env にも同様に設定


```

CACHE_DRIVER=redis
REDIS_HOST=133.130.103.167
REDIS_PASSWORD=
REDIS_PORT=6379
REDIS_DB=2
REDIS_READ_WRITE_TIMEOUT=60

```


# キャッシュクリア

```

php artisan config:clear
php artisan config:cache

```

# 使い方

```

use Illuminate\Support\Facades\Redis;


class HogeController extends Controller
{
    public function test()
    {

//        文字列を挿入
        $data = 'ほげまんちょ';
        Redis::command('SET', [3, $data]);//キー3に $data を入れる
        $res = Redis::command('GET', [3]);//キー3から読み出す
        print_r($res);//ほげまんちょ


//        インクリメント
        $incr = Redis::command('GET',[7]);
        $incr++;
        Redis::command('SET',[7,$incr]);

        print_r($incr);//17
        die;

    }


```
16日目。中級編は難しかった！がんばった！

16日目。
HTML&CSSの中級編にチャレンジしました。
結構手間取ったし、Chromeの検証を丸写ししながら、ようやっとできました。

###トップを作ろう。
最初に一気にコーディングしたらバックグラウンドイメージが細長くなってしまった。
何回みてもどこがどうしてこうなるか分からない。。。
一旦リセットして、画面を見ながら一行ずつ丁寧にコーディング。こんどはうまくいった。（45分）

###ヘッダーを作ろう
上から順番にコーディングしていくんだと思い込んでいたので、ヘッダーがコンテンツの下に。しばらく悩んできがつきました。これ、コンテンツの上に書かなきゃだめじゃん！（10分）

###レッスン一覧部分を作ろう
Lesson-wrapperで囲むと800pxくらいの幅で白抜きされたエリアができて解除できず。
すんごい悩んで何回かやり直して・・・。ヘッダー部のコンテナの中にレッスン部を書いていたのでした。ボタン押して凹むやつは丸写しで・・・(43分）

###フッターを作ろう
ここはさっくりできました。
（10分）

###完成！
結構大変でした・・・
http://appdays.herokuapp.com/Day16/
aws-sdk ruby v2でCloudWatchLogsのログストリームを取得する

### 背景
Railsでログのフォーマッタとしてlogrageを使用しているのですが、クライアント側で参照する必要があるため。

### 呼び出し方

- 初期化

```
client = Aws::CloudWatchLogs::Client.new(
  region: region_name,
  credentials: credentials
)
```

- `get_log_events`でストリームオブジェクトを呼び出す

```
resp = client.get_log_events({
  log_group_name: "ロググループ名",
  log_stream_name: "ログストリーム名"
}

resp.events #=> Array
resp.events[0].timestamp #=> Integer
resp.events[0].message #=> String
resp.events[0].ingestion_time #=> Integer
```

### 参照
https://docs.aws.amazon.com/sdkforruby/api/Aws/CloudWatchLogs/Client.html#get_log_events-instance_method
memcached に保存されている key や value の情報を見る

どんなキーが入ってるか確認することがあるので忘れないようメモ。
基本的に僕はこの3つしか使いません。

```
$ memcached-tool localhost:11211
$ echo 'stats cachedump [slab] [limit]' | nc localhost 11211
$ echo 'get [key]' | nc localhost 11211
```

上から順に

- どの slab にどれくらい cache されてるかとか見る
- slab 内の key name や 有効期限を見る
- key に保存されている値を見る

### どの slab にどれくらい cache されてるかとか見る

```
$ memcached-tool localhost:11211
  #  Item_Size  Max_age   Pages   Count   Full?  Evicted Evict_Time OOM
  1      96B       367s       1       2      no        0        0    0
  3     152B         0s       1       0      no        0        0    0
  4     192B         0s       1       0      no        0        0    0
  5     240B         0s       1       0      no        0        0    0
  6     304B         0s       1       0      no        0        0    0
  7     384B         0s       1       0      no        0        0    0
 18     4.4K         0s       1       0      no        0        0    0
 19     5.5K         0s       1       0      no        0        0    0
 27    33.1K         0s       1       0      no        0        0    0
```

Count 列を見ると slab#1 に2個だけ item が保存されていることがわかります。
他の slab は領域は確保しているが item は入っていない（expire したか delete された）状態です。
このコマンドの詳細な見方は別の記事やドキュメントに譲ります。


### slab 内の key name や 有効期限を見る

slab#1 に存在する item を 5件出力

```
$ echo 'stats cachedump 1 5' | nc localhost 11211
ITEM foo [15 b; 1551662258 s]
ITEM hoge [4 b; 0 s]
END
```

key ・バイト数・有効期限（UNIXTIME）が item ごとに出力されます。
新しく set した順に出力されてるようです。


### key に保存されている値を見る

```
$ echo 'get foo' | nc localhost 11211
VALUE foo 0 15
0123456789abcde
END
```

"0123456789abcde" が保存されていました。

### （おまけ）今回のデータ
忘れそうなのでメモ。
set key [flag] [expire] [byte]

- flag: 0 でいい
- expire: 秒数で指定。 0 ならずっと生きる
- byte: 2行目で入力する value はこの byte じゃないと `CLIENT_ERROR bad data chunk` が出るので注意

```
$ nc -c localhost 11211
set hoge 0 0 4[Enter]                                                                                                                                                                             
fuga[Enter]
STORED
set foo 0 1000 15[Enter]
0123456789abcde[Enter]
STORED
```

改行コードは CRLF にしないといけないので注意。
僕の手元の環境では c オプションで変えられました。

```
$ man nc
...
-c      Send CRLF as line-ending
...
```

### 参考
後で自分で見返す時用の memcached の挙動についてメモ。

- 最初のコマンドの理解にすごく役立つ：[memcachedのメモリストレージを理解する](http://gihyo.jp/dev/feature/01/memcached/0002?page=1)
- （この記事とはほぼ関係ないが読んでて面白かった）cache の消去メカニズムについて：[gihyo.jp](http://gihyo.jp/dev/feature/01/memcached/0003), [memcached.org](https://memcached.org/blog/modern-lru/)
PKMG クラウドセキュリティ サーベイ（@Oracle Cloud Security Day）

#前置き
Oracle Cloud Security Dayと題したセミナーにおける、PKMG社のクラウドセキュリティについてのサーベイに関するセッションまとめ（自分用メモ）

#サーベイから見える課題（グローバル）
* クラウドガバナンスの強化
 * シャドーITの管理（CASB）
* セキュリティインシデントの検知（※最大の課題）
 * 利用中クラウドサービスの可視化不十分（一度許可したあとの見直しなど）
 * セキュリティイベントデータを充分活用できていない→機械学習の利用検討
* 運用の自動化
 * パッチ適用管理の自動化

#クラウドサービス制限　検討の方向性

* クラウドサービス管理
 * ログ分析
 * 脆弱性、設定内容の分析、パッチ適用（SecOps）

* アクセス制御
 * ログイン認証
 * リスクベース認証

* エンドポイント管理
 * マルウェア侵入対策
 * 不審な挙動検知
 * BYOD制御
AndroidStudioでToolbarにVersion Controlが表示されないときの小技

AndroidStudioでEnable Version Control Integrationからバージョンコントロールを追加しても下部のToolbarにVersion Controlが表示されないときの小技

Windowsでは再起動しないと表示されないし、また再起動しても表示されないときもあるので困った・・・
ショートカット検索で出なかったのでメモ

・Windows
**<font color="forestgreen">Alt + 9</font>**

・Mac
**<font color="forestgreen">command + 9</font>**


![vc.jpg](https://qiita-image-store.s3.amazonaws.com/0/252283/ff064854-9a09-0d0e-4beb-a8ca684e94bd.jpeg)
【Vuex】ざっくり理解、Vuexって何？VuexとAPIの関係を図解してみた

サーバーから持ってきたデータを、Vuexを使って状態管理！
超ざっくりの説明なので、サラッと読めます（説明用に、サーバーサイドはLaravelを使用していますが、ご自分が使うサーバーサイド言語に置き換えてお読みください）。

【説明用技術】
Vue
Laravel

【対象の方】
Vueを使用している、または、使用してみたい方
Vuexを使ってみようと思っている方
Vuexをざっくり理解したい方

早速ざっくり行ってみましょう！

#Vuexとは何か？

そもそもVueって何？という方は、こちらをご覧ください=>[Vue公式ページ](https://jp.vuejs.org/index.html)

Vuexとは、Vueアプリケーションで使用する状態管理ライブラリです。
>Vuex は Vue.js アプリケーションのための 状態管理パターン + ライブラリです。 これは予測可能な方法によってのみ状態の変異を行うというルールを保証し、アプリケーション内の全てのコンポーネントのための集中型のストアとして機能します。

引用元：[Vuex公式ページ](https://vuex.vuejs.org/ja/)

#Vuex図解
よく見る図です。Vuexでは、アプリケーションの状態を一方方向で変更していくことで（単方向データフローというらしい）、信頼できる唯一の情報源としてのステートを保持・共有していきます。ざっくりな流れとしては、

![VuexExplain1.png](https://qiita-image-store.s3.amazonaws.com/0/309730/ba40302f-482a-f548-87c4-e117fbc306b4.png)

①Vue Componentから、Vuexで定義したアクションを呼び出す（**Dispatch** する）
②DispatchされたアクションはAPIを通じて、サーバー側で何らかの処理をする
③サーバー側で返却されたデータをミューテーションへ送る（**Commit** する）
④ミューテーションがステートを変更する（**Mutate** する）
⑤ミューテートされたステートを、Vue Component側に描画する（**Render** する）


#VuexとAPI図解
以下の図は、上述したものを少しだけ詳しくしたものです。もう一度ざっくり説明すると、
![VuexExplain2.png](https://qiita-image-store.s3.amazonaws.com/0/309730/4487fd90-bfc9-9f95-15d0-9e8964541a88.png)
①ユーザーのアクションによって、Vue Componentから、Vuexで定義したアクションを呼び出す（**Dispatch** する）

②まずDispatchされたアクションは、APIにリクエストを投げます。そしてサーバーサイド側で定義したロジックによって何らかの処理が実行されます。ここで注意するポイントは、「アクションは必ず **非同期処理** 」ということです。

③サーバー側で返却されたデータ（基本的にはJSONでリターンする）をミューテーションへ送る（**Commit** する）

④ミューテーションがステートを変更する（**Mutate** する）。ここで注意するポイントは、「ミューテーションは必ず **同期処理** 」ということです。

⑤ミューテートされたステートを、Vue Component側に描画する（**Render** する）

#ざっくり
ざっくりすぎでしょうか。笑 少しでも理解につながれば幸いです。

Vueは公式ドキュメントがしっかりしているので、分からないことがあればどんどん見に行くことをおすすめします。

参考にしたサイト・リンク・書籍なども以下に記載しましたので、ぜひ！

#参考にしたいリンク集
[【サイト】Vue公式](https://jp.vuejs.org/index.html)
[【サイト】Vuex公式](https://vuex.vuejs.org/ja/)
[【記事】CodeGrid：これから始めるVue.js 2.0](https://app.codegrid.net/entry/2016-vue-1)
[【書籍】Vue.js入門 基礎から実践アプリケーション開発まで](https://www.amazon.co.jp/dp/4297100916/ref=asc_df_42971009162544791/?tag=jpgo-22&creative=9303&creativeASIN=4297100916&linkCode=df0&hvadid=295678107984&hvpos=1o1&hvnetw=g&hvrand=6329305317803736385&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1028853&hvtargid=pla-529052961492&th=1&psc=1)
[【書籍】基礎から学ぶ Vue.js](https://www.amazon.co.jp/dp/4863542453/ref=asc_df_48635424532544791/?tag=jpgo-22&creative=9303&creativeASIN=4863542453&linkCode=df0&hvadid=295706574430&hvpos=1o2&hvnetw=g&hvrand=6329305317803736385&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1028853&hvtargid=pla-524581061219&th=1&psc=1)
[【サイト】基礎から学ぶ Vue.js](https://cr-vue.mio3io.com/)
[【Udemy】Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)](https://www.udemy.com/vuejs-2-the-complete-guide/)
VisualStudio2017 で .NET 3.5 のテストをテストエクスプローラから実行できるのは 15.8 迄

# この件は何で起きたのか
昨年の VisualStudio2017 のアップデートの 15.9.2 を適用したら MSTest のテストをテストエクスプローラから実施できなくなった。
MSTest のコマンドで実施するしか手が無くなって駆動開発が死ぬ。つらい。
という話です。

# ソースは？
[.NET Framework 3.5 のMSTest のテストが VisualStudio 2017 15.9 のテストエクスプローラから実行できない-MSTest test of .NET Framework 3.5 can not be run from Test Explorer of VisualStudio 2017 15.9](https://developercommunity.visualstudio.com/content/problem/393188/net-framework-35-のmstest-のテストか-visualstudio-2017-1.html?childToView=474002#comment-474002)
を参照のこと。

このアップデートで死ぬのは次の様な環境を構築している人です。

- .NET のバージョンにより出力を切り分けるタイプのライブラリで、新しいバージョンでその切り分けられて出力したクラスにアクセスできない場合。
- 前述のライブラリを .NET 3.5.x 以下のプロジェクトに使用している場合。

具体的には [Theraot.Core](https://github.com/theraot/Theraot) みたいな TaskBridge 系のライブラリのうち、.NET 4.0 以降では切り分けてTaskクラスを出力しないタイプを .NET 3.5.x 以下のプロジェクトに使用している場合です。

#具体的な症例
> .NET Framework 3.5 環境下で MSTest のプロジェクトを作成し、 VisualStudio 2017 のテストエクスプローラ上から テストの項目を右クリックより実行する。
VisualStudio 2017 15.8 上からでは実行することができるが、 15.9 上だと次のエラーが発生する様で実行することができない。
> Microsoft.VisualStudio.TestPlatform.ObjectModel.TestPlatformException: Framework35 はサポートされていません。.Net Framework 3.5 を対象とするプロジェクトでは、Framework40 を使用して CLR 4.0 の "互換モード" でテストを実行してください。

つまり、.NET 3.5 でコンパイルすると テストエクスプローラからテストできないよってエラーである。
これの問題は、 VisualStudio2017 15.8 ではテストが実施出来たということで、アップデートにより .NET 3.5 のテストを 実施することができなくなったのである。

#確認方法
[Net35TestSample](https://github.com/juner/Net35TestSample) をcloneしてテストエクスプローラに表示されるテストを実行してみてください。できないです。

#で何が言いたかったというと
誰か .NET 3.5に依存したプロジェクトを .NET 4.0 で実行する方法知りませんか？
牛乳卵問題に学ぶ、`要望` と `要件定義` と `設計` と `実装` の違い

# はじめに
有名なプログラマージョーク

> プログラマの夫に「買い物にいって牛乳を1つ買ってきて。卵があったら6つお願い」と言ったら、夫は牛乳を6パック買ってきた。


プログラマーを笑う自虐ジョークとして使われがちですが、
良い題材なのでこれを元に`要望` と `要件定義` と `設計` と `実装` の違いを纏めてみましょう。

下記、それぞれのフェーズの原理原則論を記載します。

# 各フェーズの原理原則

## 1. 要望
顧客(妻)の要望 を書き出す：顧客の仕事

+ 買い物に行って牛乳を1つ買ってきて、卵があったら6つお願い。


## 2. 要件定義1（ダイジェスト）
顧客の要望から曖昧な点を除いて復唱する：PMの仕事

上記だとプログラマーの夫は牛乳を6本買ってきました。夫は妻に、要望をより具体的な形で復唱する必要があります。
ここでは、卵を6つ買ってくるという事を確認することで事故を防ぐことができます。

+ 牛乳を1本買ってくる
+ 卵があったら卵を6個買ってくる


## 3. 要件定義2（詳細）
顧客の要望をより具体化して復唱する：PM(プロジェクトマネージャー) SE(システムエンジニア)の仕事

プログラマーの夫は賢いので、先程の要件定義1(ダイジェスト)だけで妻の望みの結果を出すことができます。
しかし、ミッションクリティカルなお使いで一つでも間違ったら死を意味する夫婦関係の場合、以下のように詳細な定義を与えてやり、妻に確認を取る必要があります。

+ 牛乳1本の容量は1Lであるとする
+ 牛乳とは品目で牛乳となっているものを示し、低脂肪乳などの乳飲料を含まない
+ 購入する牛乳の乳脂肪分は○%以上である
+ 卵とは鶏卵の生卵のことを示し、うずらの卵等、他の動物の卵を含まない
+ 牛乳があったら1本買ってくる
+ 卵が6個以上あったら6個買ってくる
+ 卵が5個以下しか無かったらあるだけ買ってくる
+ 卵の購入最小単位が定められている場合、最小購入単位の倍数で6個を超える最小の数だけ購入する
+ 牛乳の値段がある価格より高い場合は牛乳を購入しない
+ 卵の値段がある価格より高い場合は卵を購入しない
+ 牛乳の消費期限がある期間より短い場合は牛乳を購入しない
+ 卵の消費期限がある期間より短い場合は卵を購入しない
+ 合計金額が予算オーバーの場合は牛乳だけを購入する
+ (牛乳が無いとできない料理を想定している場合)牛乳の購入条件を満たさない場合は卵も購入しない
+ 牛乳の購入に至らなかった場合も、販売店のはしごはしなくても良いものとする

## 4. 設計
要件定義を元に具体化する：SE(システムエンジニア)の仕事

夫がより賢い場合、自分でお使いに行かずに、ロボットに指示を的確に伝えることでお使いを実施しようとします。
このとき、ロボットによりわかりやすい言葉で上記の要件定義を書き換えます。これを設計といいます。
この設計段階で何らかの不足事項が発見された場合には、要件定義を見直します。
多くの場合はこの設計は妻には確認する必要がありません。

+ 前提条件
 + 牛乳の購入に至らなかった場合も、販売店のはしごはしなくても良いものとする

+ 牛乳の定義
 + 1本の容量は1Lであるとする
 + 品目で牛乳となっているものを示し、低脂肪乳などの乳飲料を含まない

+ 卵の定義
 + 鶏卵のことである
 + 鶏卵の中でも生卵であること

+ 牛乳の購入条件
 + 賞味期限がある一定期間以上であること
 + 乳脂肪分は○%以上である
 + 値段が一定基準以下であること
 + 値段が総予算を超えていないこと
 + 店舗に1本以上の在庫があること

+ 牛乳の購入本数
 + 最大で1本

+ 卵の購入条件
 + 賞味期限がある一定期間以上であること
 + 値段が一定基準以下であること
 + 店舗に1個以上の在庫があること
 + (牛乳が無いとできない料理を想定している場合)牛乳の購入条件を満たしていること
 + 牛乳、卵の合計金額が総予算を超えていないこと

+ 卵の購入個数
 + 卵の購入最小単位が定められている場合、最小購入単位の倍数で6個を超える最小の数だけ購入する
 + ただし、卵の在庫が少ない場合は購入可能な個数だけを購入する


## 5. 実装
設計を元に実行可能な手順書に翻訳する PG(プログラマー)の仕事

ロボットが日本語の解釈実行をできない場合、ロボットに分かる言葉に翻訳する必要があります。
これが実装であり、プログラミングですが、本質は翻訳作業です。
さらにこのプログラムが正しく実装されたことを確認するテストコードのプログラミングもこのフェーズに含まれます。

## まとめると以下の通りです。

+ 1. 要望：顧客の仕事
+ 2. 要件定義1（ダイジェスト）：PM(プロジェクトマネージャー)の仕事
+ 3. 要件定義2（詳細）：PM(プロジェクトマネージャー)SE(システムエンジニア)の仕事
+ 4. 設計：SE(システムエンジニア)の仕事
+ 5. 実装：PG(プログラマー)の仕事


# 実際の現場
ここまで書いたのは理想論であり、実際の現場では異なっています。
典型的なのは以下のパターンです。

+ 1. 要望：顧客の仕事
+ 2. 要件定義1（ダイジェスト）：PM(プロジェクトマネージャー)SE(システムエンジニア)の仕事
+ 3. 要件定義2（詳細）：PG(プログラマー)の仕事
+ 4. 設計：PG(プログラマー)の仕事
+ 5. 実装：PG(プログラマー)の仕事

ほぼ全部PGのお仕事！！

つまり、実装はできないけど設計はできると言う自称PMやSEは実際は設計どころか、要件定義2の詳細化すらやっておらず、PG以下に丸投げをしている現場が数多くあります。
（※個人の観測範囲および感想であり、所属会社を代表する意見ではありません。）

もちろん、細部の設計に囚われすぎると全体の仕事ができなくなるのはわかりますが、その状態でプログラマーは `5. 実装` のフェーズだけやってるただの翻訳者だなんて言うのは恥ずかしいのでやめましょう。

# 最後に
* 買い物に行って牛乳を1つ買ってきて、卵があったら6つお願い。

という一見なんでもない要望をなぜエンジニアは難しく考えてそのシステム化に莫大な工数を計上するのかという問題に関して少しでも相互理解となれば幸いです。
その答えはエンジニアは顧客の要望にきちんと向き合ってちゃんと考えているからです。
Firebase で　静的サイトを無料で公開するやり方

#はじめに
Win10Pro で実行
firebaseを使うには　自端末にnode.jsをインストールする必要があります

#node.jsをインストールし、firebase CLIをインストール
https://qiita.com/Masayuki-M/items/840a997a824e18f576d8

```cmd
npm install -g firebase-tools
```

# firebase上でプロジェクトを作成
![image.png](https://qiita-image-store.s3.amazonaws.com/0/314964/d49dc457-fb26-e7f6-eb9b-1aa160b8782a.png)


# 日本、ロケーション asia-notheast1（東京） を選ぶ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/314964/b4b47134-052e-9083-5fda-1431f7a3dc05.png)

#ホスティングのやり方　コマンド
```
cd MySite
firebase list
・・・制作したプロジェクトのプロジェクトＩＤが表示される
firebase init --project=[該当のプロジェクトid]
firebase deploy
```

#無料で公開できます
https://mydotinstallpane-627d6.firebaseapp.com/

![a250.JPG](https://qiita-image-store.s3.amazonaws.com/0/314964/1442f421-30ee-5f76-7059-d6422877c2e6.jpeg)
GitHub にソースを公開する方法

#動作環境
Win10Pro

#Gitをインストール
https://qiita.com/toshi-click/items/dcf3dd48fdc74c91b409

#gitHub上でリポジトリを作成します
![a239.JPG](https://qiita-image-store.s3.amazonaws.com/0/314964/f0280c6d-815c-0756-9aec-0608d82133ad.jpeg)


#自端末の制作フォルダへ移動　以下を入力してリモートリポジトリを更新

```cmd
git init
git add .
git commit -m "first commit"
git remote add origin https://github.com/[ユーザー名]/[リポジトリ名].git
git push -u origin master
```

#最初にgit pushでこの画面が出ますのでユーザー／パスワードを登録する（以後はでない）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/314964/f9ca47b2-bb59-66a7-bf9d-65a4486a7e7e.png)

#公開できます
https://github.com/hossypost01/HtmlPortfolio
![a240.JPG](https://qiita-image-store.s3.amazonaws.com/0/314964/4072c4b6-15a0-91d2-9895-9fa327706d9d.jpeg)
ソースコード解析の環境構築 - Botpress詳解(2)

やりたい事はBotpressを動かしながらモジュール構成やデータ構造について見ていく事です。
そのため、今回は開発環境のセットアップをおこないます。

使用するBotpressのバージョンは最新である11.9.5です。
構築の方法についてはbotpressのREADME.mdに記載のある「Quick Start」に沿って進めます。




##botpressソースコードのチェックアウト

まずは、ソースコードのダウンロードです。githubにあるのでクローンして、v11.9.5をチェックアウトします。

```
git clone https://github.com/botpress/botpress
cd botpress
git checkout -b v11.9.5
```

ダウンロードと使用するバージョンへの切り替えができたので、環境の構築に進みます。


##事前準備
REDMEに下記の記載があるので、node.jsのv10.11とパッケージマネージャーのyarnが必要なようです。
現在node.jsのv10系は最新がv10.16.0のようですので、こちらとyarnをインストールしてみます。
(node.jsの最新版であるv12系でためしてみましたが、エラー表示があったのでv10系ですすめます)

> Prerequisites: Node 10.11 (you can use nvm) and Yarn.

```
$ nvm install v10.16.0
$ npm install yarn
```

yarnはv1.16.0がインストールされました。



##パッケージのインストール

> Run yarn to fetch node packages.

yarnを実行してパッケージを取得します。

```
$ yarn
```

##ビルド

> Run yarn build to build the core, the UI and the modules.

yarn buildを実行してbotpressのコア部分,UIとモジュールをビルドします。
これは2〜3分ほど時間がかかりました。

```
$ yarn build
```

ビルドが成功すると下記のように「Done」が表示されるはずです。
<img width="425" alt="yarn start — 169×81 2019-07-01 01-09-57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356515/60b906e0-d69a-44ca-cb07-873a631fd4d1.png">


## サーバーの起動

> 3. Run yarn start to start the server.

yarn startを実行してサーバーを起動します。

```
$ yarn start
```

下記の画面のように```Launcher BotPress is ready```の表示がでていればサーバーが起動しています。
<img width="950" alt="yarn start — 169×81 2019-07-01 01-11-53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356515/65dd622f-cf0a-51d7-55f8-1b121e617ec7.png">


ブラウザで```http://localhost:3003/```を開いて下記のようにBotpress Admin Panelが表示されれば完了です。
<img width="813" alt="Botpress Admin Panel 2019-07-01 01-15-31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356515/e7652549-e966-103b-1b47-db2acf626662.png">


##次回
ソースからビルドして動かせる準備が整ったたので、次回から具体的に気になる箇所のソースを追ってみたいと思います。

----
###We're hiring!
AIチャットボットを開発しています。
ご興味ある方は<a href="https://www.wantedly.com/projects/266837">Wantedlyページ</a>からお気軽にご連絡ください！
php-master-changes 2019-03-03

今日はビルドツールの修正、ext/hash で常時 TLS キャッシュを有効化する修正があった！

# 2019-03-03
## kadler: Fix shared module generation on AIX bug [#77676](https://bugs.php.net/bug.php?id=77676)
- https://github.com/php/php-src/commit/700f876a1ae5957bda027b36b1fdf3ffdbe57f6f
- [7.2~]
- AIX で拡張をビルドした際、make test に失敗する問題の修正

## petk: Update NEWS
- https://github.com/php/php-src/commit/637713c1a442931ca2528292cd6ff54fcaed951c
- [7.2~]
- ↑の NEWS の修正

## weltling: Heedlessly enable thread LS cache for ext/hash.
- https://github.com/php/php-src/commit/8cd345acb1064ffe695e69217333ed2b83de45c3
- [7.4~]
- ext/hash で、常時 [TLS キャッシュを有効にする](https://github.com/php/php-src/blob/20addf88e4363d58deeebfa24c591049fe900657/Zend/zend.h#L56)よう修正

## petk: Remove AC_PROG_CC_C_O
- https://github.com/php/php-src/commit/6bb657fc348dba9f55e2d2fed601e3722a590fea
- [7.4~]
- ビルドツールで、使われていない m4 マクロ AC_PROG_CC_C_O の指定を削除
- コンパイラが -c と -o をサポートしているかのチェック用らしい……

## petk: Remove outdated hack for AIX 4
- https://github.com/php/php-src/commit/d6dac94ab14400ce715608c05bec9a94e724c373
- [7.4~]
- ビルドツールで、現在サポートしていない AIX 4 用の記述を削除
【メモ】楽に最新の無料アセットをチェックする魔法の言葉？

# はじめに

…いや、「魔法の言葉」なんていうぐらい大層なものじゃないのですが、この言葉で無料アセット探しがだいぶ楽になりました。簡単なので共有しちゃいます。

# 魔法の言葉

ブラウザ版アセットストアで以下のURLを叩くと、無料アセットが更新順に100個単位でリストアップされます

```
https://assetstore.unity.com/search?k=price%3A0&order_by=updated&q=price%3A0&rows=100
```

あとは、ブックマークするだけです

# 魔法の言葉にするコツ

コツは２つ

## タブブラウザ奨励

アセットの詳細を見るときは新しくタブを開けば、あとは見たら閉じるだけです。便利！

## こまめにチェック

新しいアセットはほぼ毎日追加されるので、1日1回はチェックする習慣をつけると追加アセットがてんこ盛りになるのを防げます…マイアセットの量が莫大になりますが（ただ、DLしなければストレージへの負担は小さいです）

老婆心ながら、**リロードの頻度は適切に！**　せめて1日1回ぐらいにしてアセットストアの負荷を減らしましょう！

# 使用上の注意

リストアップのソートは「アップデート順」です。そのため、新規追加のアセットもバージョンアップ更新も一緒に出てきます。新しいタブで開くと登録済みの場合は「**このアセットは○月○日に購入しました(ｏｒダウンロードしました）**」と出てきますので、そのときはタブを閉じます。
情報処理安全確保支援士 平成28年度春 午後1 問3

下記の問題集を参考させていただいでおります。
[午後(I・II)に集中！情報処理安全確保支援士精選17問](https://www.amazon.co.jp/%E5%8D%88%E5%BE%8C-I%E3%83%BBII-%E3%81%AB%E9%9B%86%E4%B8%AD%EF%BC%81%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E5%AE%89%E5%85%A8%E7%A2%BA%E4%BF%9D%E6%94%AF%E6%8F%B4%E5%A3%AB%E7%B2%BE%E9%81%B817%E5%95%8F-%E6%9E%97%E7%A7%80%E6%A8%B9-ebook/dp/B07B7LHCVN/ref=sr_1_21?s=books&ie=UTF8&qid=1551168594&sr=1-21&keywords=%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E5%AE%89%E5%85%A8%E7%A2%BA%E4%BF%9D%E6%94%AF%E6%8F%B4%E5%A3%AB)

#設問1
**(1) a：Sサーバ**
**(2) b：試験用Webサーバ**
図2よりSアプリ内に、SサーバのFQDNが組み込まれている。と説明があります。
SアプリでDNSサーバ(今回は省略されています)にSサーバのFQDNを問い合わせ、SサーバのIPアドレスを名前解決します。
試験環境での同様にSサーバのFQDNを名前解決する必要があります。しかし、そのまま利用すればSサーバのIPアドレスに名前解決されてしまうため、試験用DNSサーバのAレコードを**試験用WebサーバのIPアドレス**に変換する必要があります。

**(3) 試験の実施よりも前の日時**
「有効期間の終了」に何を設定するのか解答する問題です。
表2項番2は有効期間内でないことを検出するための試験です。
そのため、有効期間外では必ずサーバ証明書が利用できないようになっているか確認するため、試験開始日には有効期限が終わっている必要があります。
ここで**時間**と解答したら正解になるのかは微妙です。おそらく部分点かと思います。

**(4) Sアプリがサーバ認証エラー画面を表示する**
サーバ証明書に何かしら不備がある場合、サーバの認証は成功せず通信が行えません。(もしくは、警告の表示)
図2の4つ目を確認すると「Sサーバを認証できなかった場合はサーバ認証エラー画面を表示する」とあります。
これをほぼそのまま使えば解答できそうです。
また、Sサーバと通信できない(ネットワーク構成がおかしい、サーバが落ちている等々)わけではないため通信エラー画面は表示されません。

#設問2
**(1) e：1,2,3,4**
発行者の検証に不備があり商用認証局を利用していても、攻撃者が用意したプライベート認証局でも検証が行われない状況です。
そのため、発行者とコモンネームどちらか(もしくは両方)に不備があっても表3項番1～4全ての攻撃が成功してしまいます。

**　　f：3**
発行者の検証に不備があるため、攻撃者が発行しても検知できません。
さらに、コモンネームにはSサーバのFQDNが登録されるため、攻撃が正しい動作として許可されるため攻撃が成功します。

**　　g：1**
次は逆に発行者の検証に不備がない場合です。
これはスマホ対応の認証局の利用有無を検証できます。
しかし、コモンネーム検証に不備があるため、正しい認証局を利用していても攻撃者のFQDNが登録されてしまっていた場合攻撃が成功してしまいます。

**(2) SSID,暗号化方式と事前共有鍵に、公衆無線LANで使用されているものを設定する。**
無線LAN接続の方法を理解しておく必要があります。
スタバでもマックでもどこでも良いのですが、公衆無線LANを提供しているところでは大体SSIDとパスワードの張り紙が貼ってあり、それをスマホで入力すればそのお店のWi-Fiに接続できますよね。
中身を見ていくと設定されているのはSSID、暗号化方式(WEPやWPA、WPA2)と事前共有鍵(ネスぺではよくパスフレーズとも耳にしましたが、パスワードのこと)です。攻撃者はその設定をあたかもスタバの無線LANであるかのように偽装することで、利用ユーザを自身のネットワークに接続させます。
Windows Server 2016をなるべくCUIで日本語化する

#■初めに
Azure等でWindows Server 2016を準備した場合、初期状態は言語設定が英語になっています。GUIでポチポチ設定変更してもよいのですが、CUIでサクッと出来ないかとやってみました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201787/0839cd85-f0e3-7ed5-5d7c-846e26611e52.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201787/4feb84e1-cd48-8609-eae2-25e49727ce6e.png)




#■結論
再起動を何回か挟む　＋　一部GUIでしか設定できない　ので、サクッとは無理
でも、なるべくCUIでやってみる

#■手順
①Powershellで各種設定＋リブート
②Powershellで各種設定＋リブート
③GUIで一部設定＋リブート

#■手順①Powershellで各種設定＋リブート
日本語言語パックのダウンロードを行います。
最下行のコマンドがリブートのコマンドです。

```powershell:Powershell
$LpUrl = "http://download.windowsupdate.com/c/msdownload/update/software/updt/2016/09/"
$LpFile = "lp_9a666295ebc1052c4c5ffbfa18368dfddebcd69a.cab"
$LpTemp = "C:\LpTemp.cab"
Set-WinUserLanguageList -LanguageList ja-JP,en-US -Force
Start-BitsTransfer -Source $LpUrl$LpFile -Destination $LpTemp -Priority High
Add-WindowsPackage -PackagePath $LpTemp -Online
Set-WinDefaultInputMethodOverride -InputTip "0411:00000411"
Set-WinLanguageBarOption -UseLegacySwitchMode -UseLegacyLanguageBar
Remove-Item $LpTemp -Force
Restart-Computer
```


#■手順②Powershellで各種設定＋リブート
日本語設定や地域設定を行います。
最下行のコマンドがリブートのコマンドです。

```powershell:Powershell
Set-WinUILanguageOverride -Language ja-JP
Set-WinCultureFromLanguageListOptOut -OptOut $False
Set-WinHomeLocation -GeoId 0x7A
Set-WinSystemLocale -SystemLocale ja-JP
Set-TimeZone -Id "Tokyo Standard Time"
Restart-Computer
```

＃なお、手順①と②のコマンドを一気にやっても、言語設定は変更されませんでした。
　どうやらリブートを挟まないといけないようです。

#■手順③GUIで一部設定＋リブート
「ようこそ画面とシステムアカウント」の設定を日本語化します。ここのみGUIです。

③-1　「コントロールパネル」を起動
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201787/dc850651-fa93-a325-5e34-e12059e0e6d0.png)

③-2　「時計、言語、および地域」をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201787/11f16d05-556d-7ca7-7c72-eee959d6cd28.png)

③-3　「地域」をクリック　
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201787/cf8a2b4c-ccf3-ffc0-6fb8-dce2fe7f7c2e.png)

③-4　「管理」タブの「設定のコピー(C)...」をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201787/0e0a5960-cc68-d060-1c7f-11f094062f04.png)

③-5　「ようこそ画面とシステム アカウント(W)」を選択し、「OK」をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201787/6ec47ff2-5f02-14e9-8b0d-9c4e5a01036d.png)

③-6　「今すぐ再起動」をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201787/f8c9f04c-2f4b-cfd6-097f-e3acfcb53332.png)


これで完了です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201787/289227c3-b096-4666-e8f6-ca33e30f4316.png)



#■参考
Azure IaaS 上に作成した Windows Server 2016 仮想マシンの UI を日本語化する
https://kogelog.com/2016/10/18/20161018-01/

英語版 Windows Server 2016 のGUIの表示を日本語に変更する (Windows Server Tips)
https://www.ipentec.com/document/windows-change-gui-language-in-windows-server-2016

Windows Server 2012 R2英語版の日本語表示
http://blog.serverworks.co.jp/tech/2016/06/20/windows-server-2012-r2-japanese-localization/
Microsoft AzureへはPingが使えない？PSPingを使いましょう。帯域試験もどうぞ。

#■はじめに
Ping、知らない人の方が少ないコマンドだと(私は)思いますが、Microsoft AzureへはPingが利用できません。
理由としては、Azure側でICMP通信が遮断されることにあります。

よって、TCP/UDPのポート通信を利用した**Microsoft謹製ツールのPSPing**を利用してみました。
帯域確認オプションもあり、簡易スループット測定もやってみました。

>**クラウド サービスに ping を実行することはできますか。**
>いいえ、通常の "ping"/ICMP プロトコルは使用できません。 ICMP プロトコルは、Azure Load Balancer を通過することを許可されません。
>
https://docs.microsoft.com/ja-jp/azure/cloud-services/cloud-services-connectivity-and-networking-faq

#■前提
①Windows実行を前提としています。今回はWindows Server 2016にて実施しています。
②TCP/UDP通信にて疎通を行うため、対向サーバのポートが解放および起動されていないと通信できないため注意が必要です。
③確認は、同一のAzure仮想NWに存在する、VM(A)からVM(B)へ行っています。

#■実行
手順①　PSPingツールをダウンロードします。

>PsPing v2.1
https://docs.microsoft.com/en-us/sysinternals/downloads/psping

<br>
手順②　適当なディレクトリに解凍します。今回は C:\ 直下に解凍します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201787/ff54bf79-6742-544b-4498-d77d6549fbda.png)

<br>
手順③　コマンドプロンプト(管理者)を起動し、以下コマンドを利用します。
＃ポートは、リモートデスクトップ用の3389ポートあたりだと大体開いているかと思います。

```powershell:管理者：コマンドプロンプト
C:\PSTools> C:\PSTools\PSPing.exe <IPアドレス>:<ポート番号>
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201787/1704531a-a3ee-b308-8d8c-130e93f907af.png)



#■その他
最初に書いた通り、本ツールはTCP/UDP向けのPingであるため、TCPポートおよびUDPポートの開閉状態の確認が出来ます。

・TCPポートへの確認(IPアドレス:192.168.0.1、TCPポート:80)

```powershell:管理者：コマンドプロンプト
C:\PSTools> C:\PSTools\PSPing.exe 192.168.0.1:80
```

・UDPポートへの確認(IPアドレス:192.168.0.1、UDPポート:33434)

```powershell:管理者：コマンドプロンプト
C:\PSTools> C:\PSTools\PSPing.exe -u 192.168.0.1:80
```
<br>
また、帯域幅調査用のコマンドもあり、簡易なスループット調査も可能です。

・帯域幅の確認(IPアドレス:192.168.0.1、TCPポート:80、ブロック長:1MByte、1000回試行)

```powershell:管理者：コマンドプロンプト
C:\PSTools> C:\PSTools\PSPing -b -l 1m -n 1000 192.168.100.1:80
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201787/5e8a4b4e-4c80-ff48-d38a-f48c202a4ec7.png)

結果として、｢Average = 89.55 MB/s｣ ≒
 ｢716.4 Mbps｣という値が得られました。

＃やりすぎは予期しないNW輻輳を招きますので、ご利用は計画的に。

詳細コマンドオプションは以下公式を参考ください。
>PsPing v2.1
https://docs.microsoft.com/en-us/sysinternals/downloads/psping


#■出典/参考
Azure Cloud Services の接続とネットワークの問題についてよくあるご質問 (FAQ)
https://docs.microsoft.com/ja-jp/azure/cloud-services/cloud-services-connectivity-and-networking-faq

PsPing v2.1
https://docs.microsoft.com/en-us/sysinternals/downloads/psping

Azure仮想マシンへの接続確認でPingの応答が無い！そんなときはPspingを使おう！
https://pig-log.com/howto-psping/

Azure仮想マシンの接続テストには、ICMPの代わりにPort Pinを使おう
https://sqlazure.jp/b/windows-azure/1918/
Swift：macOS用のグローバルショートカット登録ライブラリ作った（CocoaPods公開）

# 概要
著者はmacOS用のユーティリティアプリばかり作っているのですが，グローバルショートカットを使いたくなる場面によく遭遇します．これまでは[Magnet](https://github.com/Clipy/Magnet)や[HotKey](https://github.com/soffes/HotKey)という既存のライブラリを使わせて頂いてきたのですが，JISキーボードへの対応や修飾キーの扱いなど使い勝手がよくない場面があったので，自作することにしました．

# SpiceKey
HotKeyのHotというところから連想してSpiceKeyという名前にしました．MITライセンスにてGitHubにオープンソースとして公開し，CocoaPodsでもインストールできるようにしました．
GitHubのリンク：[SpiceKey](https://github.com/Kyome22/SpiceKey)

## デモ
プロジェクトの中にデモアプリが入っています．二つのショートカットを登録して，ショートカットの挙動をラベルで確認できるものです．ショートカット登録用のテキストボックスの実装方法の参考にもなるかもしれません．

![DemoApp.png](https://qiita-image-store.s3.amazonaws.com/0/67153/fb7719bb-f1c8-07f8-24cf-926dcdd6355a.png)

# ~~今後~~
~~目処は立っているので，長押しやダブルタップによるショートカット発動にも対応したいと思っています．~~

# 追記（2019/6/1）
バージョン1.5にて，修飾キーの長押しと，キーボードの左右の修飾キー同時押しによるショートカットにも対応しました．
ダブルタップはあまり利便性を感じなかったので実装してません．
embulk 0.9.0 で embulk gem がリリースされなくなった件について

embulk >= 0.9.0 から embulk gem が個別に[リリースされなくなりました](https://github.com/embulk/embulk/issues/628)。

では、jruby プラグインから Embulk なライブラリを使うにはどうすれば良いかというと、embulk.jar に同梱されている embulk gem を使う形になります。

これによってどういう影響があるかというと、主には以下の２つに影響が出ているので、それについて記載します。

* embulk run -b
* jruby プラグインのテストの書き方

# embulk run -b /path/to/Gemfile

embulk >= 0.9 で `embulk run -b` を使いたい場合は、Gemfile に

```rb:Gemfile
gem 'embulk'
```

を書いておく必要があります。embulk < 0.9.0 では必要ありませんでした。

`bundler` は Gemfile.lock に書かれているものだけをロード対象にするので、`gem 'embulk'` を書いておかないと、embulk.jar に同梱されている embulk.gem でも無視されてしまいます。0.8.x 以前で書かなくて良かったのは、embulk 側でごにょごにょしてくれていたから(という認識)ですが、それは行わなくなったので、ユーザ側でケアする必要があります。

Gemfile.lock を作る際には、embulk.jar に同梱されている embulk gem を指定したいので、最終的に使いたい embulk と手元の embulk のバージョンを合わせて

```
$ embulk bundle update
```

として Gemfile.lock を作る必要があります。Gemfile.lock を覗いて、


```
    embulk (0.9.15-java)
      bundler (>= 1.10.6)
      liquid (~> 4.0.0)
      msgpack (~> 1.1.0)
```

のように embulk --version と同じバージョンの embulk gem が記載されていればOKです。

```
$ embulk run -b /path/to/Gemfile ...
```

のように `-b` オプションを指定して実行すれば Gemfile を指定して embulk を実行できます。


# jruby プラグインの単体テストを流す

embulk は `embulk bundle exec` の利用をサポートしていないので、`bundle exec rake test` でテストを実行できるようにするには手間が必要です。


embulk を .jar 拡張子付きでダウンロードしておきます。(.jar がついてないと jruby から require できません)

```
$ curl -o embulk.jar --create-dirs -L "http://dl.embulk.org/embulk-0.9.15.jar"
$ chmod a+x ./embulk.jar
```

Gemfile.lock を作る際には、embulk.jar に同梱されている embulk gem を指定したいので `./embulk.jar bundle` で依存 gem をインストールします。

```
$ ./embulk.jar bundle install --path vendor/bundle
```

embulk.jar に同梱されている jruby と bundler のバージョンを調べておきます。 See also [embulk 同梱の jruby のバージョンを調べる](https://qiita.com/sonots/items/bdff8605967b5a4505f5)

```
$ echo JRUBY_VERSION | ./embulk.jar irb
2019-08-10 00:59:11.866 +0900: Embulk v0.9.17
Switch to inspect mode.
JRUBY_VERSION
"9.1.15.0"
```

```
$ echo "require 'bundler'; Bundler::VERSION" | ./embulk.jar irb
2019-08-10 01:59:10.460 +0900: Embulk v0.9.17
Switch to inspect mode.
require 'bundler'; Bundler::VERSION
"1.17.3"
```

同じバージョンの jruby を rbenv なりを使ってインストールします。bundler もインストールします。embulk は `embulk bundle exec` の利用をサポートしていないので、`bundle exec` 実行できるように同じバージョンの jruby と bundler をインストールして誤魔化そうという作戦です。

```
$ rbenv install jruby-9.1.15.0
$ rbenv local jruby-9.1.15.0
$ gem install bundler -v 1.17.3
```


`bundle exec` で実行する際には、bundler が Gemfile の gem をロードする前に、`embulk.jar` を require する必要があります。これは `RUBYOPT` 環境変数ないし、ruby の `-r` オプションを利用して実現できます。

さらに以前はテストを書く時に使っていた `Embulk.setup` が embulk gem >= 0.9.0 では消去されたので、代わりに `embulk/java/bootstrap` を require します。

こんなかんじになると思います。

```shell-session
$ bundle exec ruby -r ./embulk.jar -r embulk -r embulk/java/bootstrap -e "puts Embulk"
```

```shell-session
$ bundle exec env RUBYOPT="-r ./embulk.jar -r embulk -r embulk/java/bootstrap" rake test
```


embulk-output-bigquery で実際にやっている設定はこちら[pull/88](https://github.com/embulk/embulk-output-bigquery/pull/88) です。
AsRefトレイトについて


例えば新規ファイルを作成する関数は`&str`も`&Path`も引数にとることができる。

```rust
std::fs::File::create("/var/tmp/hoge");
std::fs::File::create(&std::path::Path("/var/tmp/fuga"));
```
何故ならこの関数の引数の型は`&str`でも`&Path`でもなく、`AsRef<Path>`を実装するような型`P`であり、

```rust:fs.rs
fn create<P: AsRef<Path>>(path: P) -> io::Result<File>
```
`path`モジュールで`str`や`Path`に対して`AsRef<Path>`が実装されているので、

```rust:path.rs
impl AsRef<Path> for Path {
    fn as_ref(&self) -> &Path {
        self
    }
}

impl AsRef<Path> for str {
    fn as_ref(&self) -> &Path {
        Path::new(self)
    }
}
```
`as_ref`メソッドで`&Path`を取り出すことができる。

```rust
fn create<P: AsRef<Path>>(path: P) -> io::Result<File> {
    let p: &Path = path.as_ref();
    ...
}
```
pip で cabocha-python をいれる

[以前のWindows で pip で mecab-python をいれる](https://qiita.com/yukinoi/items/990b6933d9f21ba0fb43)記事でWindowsでNLPやる人の需要が少しあるのがわかったので、今回は[cabocha-pythonをPyPIに登録しました](https://pypi.org/project/cabocha-python/)。

```
pip install cabocha-python
```
で入れられます。

ただしMeCabと違ってCaboChaをWindowsの64bit版Pythonに対応させるのは難しいので、Windowsは32bit版Pythonのみ対応しています。

あとはついでにMacやLinuxでも入れられるようにしました。これまでMacやLinuxでcabocha-pythonを入れるには下記pipコマンドで一度git cloneして入れなければいけないため時間がかかるので、上記の`pip install cabocha-python`の方がはやくインストールできます。

```
pip install git+https://github.com/taku910/cabocha.git#subdirectory=python
```

PythonでCaboChaを使いたいときはぜひお使いください。
git add を取り消す

## はじめてのgit add を取り消す
git init 直後のgit addを取り消したい場合。

```shell:全てのファイルを取り消し
git rm --cached -r .
```
```shell:特定のファイルのみ取り消し
git rm --cached -r file_name
```

## 2回目以降のgit add を取り消す

```shell:全てのファイルを取り消し
git reset HEAD
```
```shell:特定のファイルのみ取り消し
git reset HEAD file_name
```
Reactで親componentのeventを子componentが読み込まない時に確認すること

## はじめに
`React`で[チャットシステム](https://react-chat-b0e8a.firebaseapp.com/)を作成中、子componentが親componentのイベントを読み込まない事態に遭遇した。
その際に行った対処法を記録しておく。

## 行ったこと
**`this.props.~`の`~`に記入している内容を変えた**
**具体的には、`this.props.onNameChange` → `this.props.onClick`**

### Before

```jsx:App.js
import React,{Component} from 'react'
import firebase from 'firebase/app'
import { firebaseApp,firebaseDB } from '../firebase/firebase'
import LogoutStateForm from './LogoutStateForm'

const messagesRef = firebaseDB.ref('messages')

class App extends Component {
  constructor(props){
    super(props)
    this.onNameChange = this.onNameChange.bind(this)
    this.onTextChange = this.onTextChange.bind(this)
    this.state = {
      user: null,
      user_name: "",
      text: ""
    }
  }
  componentDidMount(){
    firebase.auth().onAuthStateChanged(user => {
      this.setState({ user })
    })
  }
  onNameChange(e) {
    if (e.target.name == 'user_name') {
      this.setState({
        user_name: e.target.value
      }),
      console.log(this.state.user_name);
    }
  }
  onTextChange(e) {
    if (e.target.name == 'text') {
      this.setState({
        text: e.target.value
      }),
      console.log(this.state.text);
    }
  }
  render(){
    return(
      <div id='Form'>
        {this.state.user ?
          <LogoutStateForm onClick={this.onNameChange} />:
          null
        }
        //In order to switch display depending on login availability
        <textarea name='text' onChange={this.onTextChange}  placeholder='メッセージ'/>
      </div>
    )
  }
}

export default App
```

```jsx:LogoutStateForm.js
import React,{Component} from 'react'
import firebase from 'firebase/app'

class LogoutStateForm extends Component {
  constructor(props){
    super(props)
  }
  login() {
    const provider = new firebase.auth.GoogleAuthProvider()
    firebase.auth().signInWithPopup(provider)
  }
  componentDidMount(){
    firebase.auth().onAuthStateChanged(user => {
      this.setState({ user })
    })
  }
  render(){
    return(
      <div className='logout'>
        <input name='user_name' onChange={this.props.onNameChange} placeholder='名前'/>
        <button onClick={this.login}>Goggle Login</button>
      </div>
    )
  }
}

export default LogoutStateForm
```

### After
`App.js`に変更はなし

```jsx:LogoutStateForm.js

import React,{Component} from 'react'
import firebase from 'firebase/app'

class LogoutStateForm extends Component {
  constructor(props){
    super(props)
  }
  login() {
    const provider = new firebase.auth.GoogleAuthProvider()
    firebase.auth().signInWithPopup(provider)
  }
  componentDidMount(){
    firebase.auth().onAuthStateChanged(user => {
      this.setState({ user })
    })
  }
  render(){
    return(
      <div className='logout'>
        <input name='user_name' onChange={this.props.onChange} placeholder='名前'/>
        <button onClick={this.login}>Goggle Login</button>
      </div>
    )
  }
}

export default LogoutStateForm
```


## 参考資料
[Child component does not load event of parent component in React](https://stackoverflow.com/questions/54939332/child-component-does-not-load-event-of-parent-component-in-react)
ラズパイに構築したWireGuardにmacOS、iOSからVPN接続してみた

macOSに[`WireGuard`クライアントアプリが登場](https://jp.techcrunch.com/2019/02/19/2019-02-18-vpn-protocol-wireguard-now-has-an-official-macos-app/)したので、raspi3にをサーバにしてmacOS(mojave)、iOSアプリから`WireGuard`を使用してVPN接続してみた。


# 結果
- raspi3のraspbian(stretch)では`WireGuard`を問題なく導入できた。
- iOS、macOSの`WireGuard`クライアントアプリから問題なく接続できた。
- でもハマりポイントがあった

以下に検証した結果を書いていきます。

# WireGuardとは
[詳細はこちら](https://ja.vpnmentor.com/blog/wireguard%E3%81%AF%E6%9C%AA%E6%9D%A5%E3%81%AEvpn%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB%EF%BC%9F%E3%80%80%E5%B9%B4%E5%AE%89%E5%85%A8%E6%80%A7%E3%81%AE%E6%9C%80%E6%96%B0%E6%83%85%E5%A0%B1/)

特徴としては

- 新しいオープンソースのVPNプロトコル(あくまでプロトコルでありOpenVPN等のソフトウェアではない)であり、実態はカーネルモジュール
- `OpenVPN`より高速で通信量が少ないらしい
- `OpenSSL`に依存していないため導入がシンプル
- まだ開発途上で安定していない？
- 使用できるプロトコルはUDPのみでTCPは使えない

ということらしい。

# サーバ側
raspberrypi3(raspbian strech)にansibleでインストールしセットアップ。[Playbook](https://github.com/dkuji/raspi-k8s-cluster/tree/master/roles/wireguard)を公開しているので詳細はこちらを参照。




ポイントとしては

- カーネルモジュールとしてインストールしているので最後に`reboot`する必要がある。  
起動後に`lsmod`で見えていれば多分大丈夫。

```bash
root@raspi3-wireguard:~# lsmod | grep -i wireguard
wireguard             151552  0
ip6_udp_tunnel         16384  1 wireguard
udp_tunnel             16384  1 wireguard
ipv6                  425984  25 wireguard
```

- Listenポートを53にしてFreeWifiでも接続できるようにしている。
- `templates/wg0.conf`の`Publickey`は後述するmacOS、iOSアプリで生成した公開鍵を記述する。
- `peer`のAllowdIPsに後述するクライアントIPを指定する必要がある。
`0.0.0.0/0`でanyで許可もできるが、今回の検証ではクライアントIPを`/32`で指定しないとインターネットに出られなかった。
最初`0.0.0.0/0`で指定していて結構ハマッた。

ぐらいでしょうか。

`OpenVPN`みたいに`openssl`で証明書を作らなくていいのでとても楽。`HeartBleed`のような重大な脆弱性の影響も受けないし導入、運用は`OpenVPN`より簡単かなと思った。



# クライアント(macOSアプリ)
- AppStoreからインストール。今回使用したバージョンは`0.0.20190207 (3)`
- 鍵ペアを生成し、Publickeyはサーバ側で指定。
- `Peer`の`Publickey`にサーバで生成した`Publickey`を指定。
- `Peer`の`Endpoint`にサーバのグローバルIPと`Listen`ポートを指定。IPは名前でも問題ないのでDDNSで指定することも可。
- `Interface`の`Addresses`はサーバ側のインタフェースのIPレンジ内を指定

<img width="912" alt="screenshot 2019-02-24 23.24.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/250010/d0e7598b-a371-f600-823f-c97c700981ed.png">

あとは`Status: Inactive`のチェックを入れると`WireGuard`サーバに接続できる。


# クライアント(iOSアプリ)
- AppStoreからインストール。今回使用したバージョンは`0.0.20190207 (3)`
- `Create from scratch`から鍵ペアを生成しmacOSアプリと同様にサーバ情報を入力。


<img width="375" alt="IMG_7717.png" src="https://qiita-image-store.s3.amazonaws.com/0/250010/0e265cb4-7767-2b08-a869-ce58d1688324.png">

<img width="375" alt="IMG_7718.png" src="https://qiita-image-store.s3.amazonaws.com/0/250010/415f6eff-da7e-b863-8e73-c6056dced8d0.png">


# おわりに
- いくつか詰まるところがあったがとりあえずmacOS、iOSでVPNで接続したいという目的を達成することができた。
- サーバ側でトラブルシューティングが辛かった。(ログが全く出せないので切り分けが非常に大変)
今回詰まったときに行った調査としては
  - tcpdumpで`wg0`インタフェースにパケットがきているか
  - `wg0`にパケットがきているなら`iptables`で`wg0`インタフェースのin,out,natでパケットが処理されているか
  
 ぐらいしか確認できなかった気がする。


- これで`OpenVPN`と`Wireguard`でVPNできる様になったので、両方を使いながら使用感を見ていきたい。またそのうち速度比較がしたい。
Rubyの破壊的メソッドで[!]が付いていないものまとめ

Rubyにおける破壊的メソッドの中で、メソッドの最後に[!]が付いていないものをまとめてみました。それと簡単な説明を書いておきました。間違いや抜けがあれば教えてください！

#Stringクラス
###insert
```ruby
str.insert(index, other_str)
```
文字列の中でindexの位置に別の文字列other_strを挿入
###replace
```ruby
str.replace "bar"
```
self の内容を other の内容で置き換えます。
###concat
```ruby
str.concat(other_str)
```
<<の別名です。文字列strの末尾に別の文字列other_strを加えます
###［］=
```ruby
str[index]=other_str
```
strのindex番号を指定して文字を置き換える。

#Arrayクラス
###push
```ruby
array.push(obj, ...)
```
配列の末尾に引数を要素として追加する
###concat
```ruby
array.concat(other_array)
```
配列arrayの末尾に引数の配列other_arrayを結合する
###insert
```ruby
array.insert(index, obj, ...)
```
引数indexで指定した位置に引数objを要素として挿入する。第２引数以降に複数の引数を並べると、複数の要素を順に挿入する。
###shift
```ruby
array.shift
```
配列の最初の要素を削除する。
###unshift
```ruby
array.unshift(obj, ...)
```
引数objを配列の先頭に要素として追加する。引数を複数指定すると、それぞれ先頭から順に追加する。
###[]=
```ruby
array[index] = obj
```
[]内で指定した位置の要素を右辺で置き換える。
###fill
```ruby
array.fill(obj)
```
配列の全ての要素を引数objで置き換える。
###replace
```ruby
array.replace(other_array)
```
配列の内容を引数other_arrayで置き換える。
###delete_at
```ruby
array.delete_at(index)
```
配列から引数indexの位置を削除する
###delete_if
```ruby
array.delete_if {|item| block }
```
要素の数だけ繰り返しブロックを実行し、ブロックの戻り値が真になった要素を削除する。
###delete
```ruby
array.delete(obj)
```
配列から引数objと同じ要素を探して、全て削除する。
###clear
```ruby
array.clear
```
要素を全て削除し、配列を空にする。
###pop
```ruby
array.pop
```
配列の末尾の要素を削除する。

#Hashクラス
###［］=
```ruby
hash[key] = val
```
ハッシュにkeyとvalのペアを追加する。keyがすでにあれば、そのkeyの値をvalで上書きする。
###delete
```ruby
hash.delete(key)
```
ハッシュから引数keyと同じキーを探して、キーと値を削除する。
###delete_if
```ruby
hash.delete_if {|key, val| block }
```
繰り返しブロックを実行し、ブロックの戻り値が真になったキーと値を削除する。
###replace
```ruby
hash.replace(other)
```
ハッシュの内容をotherの内容に置き換える。
###shift
```ruby
hash.shift
```
ハッシュからキーと値を１組削除する。
###update
```ruby
hash.update(other_hash)
```
merge!の別名。レシーバhashの内容に引数other_hashの内容を加える。
###clear
```ruby
hash.clear
```
キーと値を全て削除する。

##参考
https://ref.xaio.jp/ruby
http://web-tenna.com/ruby-destruction-method/
ArduinoにRFID無線モジュール（MFRC522）を繋いでRFIDタグ認識する

# 目的
MFRC522 RFID IC カード リーダーを使用して何かを制御するための前準備です。

# 準備
[Arduino nano 互換品](https://www.amazon.co.jp/gp/product/B013QV27WI/ref=ppx_yo_dt_b_asin_title_o02_s02?ie=UTF8&psc=1)
[MFRC522 RFID IC カード リーダー](https://www.amazon.co.jp/gp/product/B01FYTE7KU/ref=ppx_yo_dt_b_asin_title_o09_s01?ie=UTF8&psc=1)

# 回路図
MFRC522 Reader/PCD <---> Arduino Nano v3
下記の通り接続します。
RST    <--->  D9
SDA(SS)      <---> D10
MOSI         <---> D11
MISO         <---> D12
SCK          <---> D13

# コード
MFRC522 RFID IC カード リーダーのライブラリを入手し、
DumpInfoサンプルコードをビルドして使用します。

```
#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN         9          // Configurable, see typical pin layout above
#define SS_PIN          10         // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance

void setup() {
	Serial.begin(115200);		// Initialize serial communications with the PC
	while (!Serial);		// Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
	SPI.begin();			// Init SPI bus
	mfrc522.PCD_Init();		// Init MFRC522
	mfrc522.PCD_DumpVersionToSerial();	// Show details of PCD - MFRC522 Card Reader details
	Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}

void loop() {
	// Look for new cards
	if ( ! mfrc522.PICC_IsNewCardPresent()) {
		return;
	}

	// Select one of the cards
	if ( ! mfrc522.PICC_ReadCardSerial()) {
		return;
	}

	// Dump debug info about the card; PICC_HaltA() is automatically called
	mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
}
```

# テスト
MFRC522 RFID IC カード リーダーにタグを近づけた際にIDなどを読み取ることができればOKです。
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">use MFRC522 RFIDモジュール <a href="https://t.co/2FJHGNtYxA">pic.twitter.com/2FJHGNtYxA</a></p>&mdash; st (@st17890027) <a href="https://twitter.com/st17890027/status/1102234452153921536?ref_src=twsrc%5Etfw">March 3, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

# 参考
・[組み込みエンジニアでなくても週末にArduinoを使って遊ぶ](https://qiita.com/seigot/items/958d3f2817a4bdac8754)
Vagrant ubuntu/trusty64にRuby on Rails の環境を構築 mysqlの場合

CakePHPでは、centosに環境構築してたのですが、今回Railsの環境を作るに当たってubuntuを使用してみようと思ってやってみました！

こちらの記事を参考にしました↓ありがとうございます！
https://qiita.com/yamagh/items/61e540765fa4d2152dc4

#boxにubuntu/trusty64追加する
```terminal:terminal
$ vagrant box add ubuntu/trusty64
```
しばらくたつと...成功っぽい
<img width="567" alt="スクリーンショット 2019-02-22 1.38.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/353812/f453126c-aaa9-e6ae-ad2d-152e15c7703d.png">
boxに追加されているか確認

```terminal:terminal
$ vagrant box list
centos64        (virtualbox, 0)
ubuntu/trusty64 (virtualbox, 20190206.0.0)
```
追加されてる！
#仮想マシンを立ち上げる
```terminal:terminal
$ mkdir rails
$ cd rails
$ vagrant init ubuntu/trusty64
$ vagrant up
$ vagrant ssh
```
#初期設定
###開発用ツールなど必要そうなものをインストールする
```terminal:vagrant@localhost
$ sudo apt-get update
$ sudo apt upgrade
$ sudo apt-get install language-pack-ja
$ sudo update-locale LANG=ja_JP.UTF-8
$ sudo apt-get install sqlite3 libsqlite3-dev

#googlechromeのインストール
#UbuntuにGoogle Chromeリポジトリを追加する。
$ sudo sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
#Googleの署名鍵をダウンロード、登録し、パッケージマネージャがGoogle Chromeの完全性を検証できるようにする。
$ sudo wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
$ sudo apt-get update
$ sudo apt-get install google-chrome-stable

$ sudo apt-get install ruby-dev ntp
$ sudo apt-get install libssl-dev libreadline-dev zlib1g-dev libmagic-dev libappindicator1
$ sudo apt-get install mysql-server
$ sudo apt-get install libmysqlclient-dev npm awscli graphicsmagick redis-server nodejs-legacy
```
###rbenvのインストール
```terminal:vagrant@localhost
$ sudo apt-get install git
$ git clone git://github.com/sstephenson/rbenv.git .rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
$ exec $SHELL
```
###ruby-builderのインストール
```terminal:vagrant@localhost
$ mkdir -p ~/.rbenv/plugins
$ cd ~/.rbenv/plugins
$ git clone git://github.com/sstephenson/ruby-build.git
```
###rubyのインストール(今回はruby2.4.3)
```terminal:vagrant@localhost
$ rbenv install 2.4.3
$ rbenv global 2.4.3
$ rbenv rehash
$ echo 'gem: --no-rdoc --no-ri' > ~/.gemrc
$ gem install bundler
$ rbenv rehash
```
###railsをインストール(今回はrails5.0.1)
```terminal:vagrant@localhost
$ gem install rails --version="~> 5.0.1"
```

###プロジェクト作成
```terminal:vagrant@localhost
$ rails new アプリケーション名 -d mysql
$ bundle install
$ vi database.yml //パスワードを追加する
$ rake db:create
$ rails s
```
できた〜〜
![スクリーンショット 2019-03-04 1.05.55.png](https://qiita-image-store.s3.amazonaws.com/0/353812/271cf68a-9f63-6a88-d081-e07b504a4809.png)

正直よくわかってない状態でやってますので、もっとこうやった方がいいなどたくさんんのご指摘のコメント待ってます！
Vue-CLI3でbuildすると画面が真っ白になる

# はじめに
Vue.js + S3 でWebサイトを公開する方法がよく出ていますね。

- [Vue + AWS(S3 + CF) でシンプルにPWAアプリを公開する](https://qiita.com/matatabi3/items/2bde12a38dc7be2b663e)
- [CFNとvue-cliでさくっとS3にSPAをホスティングするためのメモ](https://qiita.com/Yarimizu14/items/4d04120f6884c135222c)

どのサイトも
「Vue.jsで作ったファイルをS3にデプロイするだけ。めっちゃ簡単！」
なトーンで書かれていますが、たしかに簡単です。

ただ、Vue-CLIのバージョンが新しかったせいか
**buildしてできたデプロイファイルを開くと、ブランクページ（画面が真っ白）に…なぜ…？**
となって2時間くらい詰まったのでメモを残しておきます。

# 前提
- vue v3.4.1
- npm v5.6.0 
- node v8.10.0

# Vue-CLIの使い方
[Vue CLI（公式マニュアル）](https://cli.vuejs.org/) を見るのが一番です。
英語が読めないとキツいかもしれませんが、
**各種ブログの情報はどんどん古くなっている**ので、結局、公式ブログで調べるのが一番早いです。

ちなみに、Vue.jsについては日本語公式マニュアルもあるのですが、
Vue CLIは日本語マニュアルがないんですよね…。

- [Vue.js（日本語マニュアル）](https://jp.vuejs.org/)

あと、以下も英語ですが、この動画で概念からサンプルアプリの作成まで全て説明してくれています。
とてもわかりやすかったです。
しかも公式だから多分常にメンテされるんじゃないのかな？

- [Vue Mastery](https://www.vuemastery.com/courses/real-world-vue-js/real-world-intro)

# [参考]実際に使ったコマンド
アプリの作成
`vue create my-app`

ローカルでのアプリの実行
`vue run serve`

デプロイ資源の作成
`vue run build`

S3へのデプロイ
公式では以下を使用することを推奨しているようです。

- [vue-cli-plugin-s3-deploy(GitHub)](https://github.com/multiplegeorges/vue-cli-plugin-s3-deploy)

が、私は以下のサイトのgulpを使った方法でやりました。

- [gulpでS3へファイルアップロード](https://hacknote.jp/archives/43241/)

公式推奨の方がcloudfrontのキャッシュクリアとかやってくれそうなので細かいところに手が届きそうですが、単純にデプロイできるかを確認するだけであればこれで十分でした。
今度、公式推奨の方法も試してみようかな。

# 詰まったところ…

ようやく本記事のメイン。
`vue run build` をすると、`./dist`ディレクトリにデプロイ用ファイルが作られるのですが、
`index.html`をそのファイルを開いてみると、真っ白なブランクページが表示されてしまいます…

開発者ツールを見る限り、
原因は、buildで作成された`index.html`に定義されているJSやCSSのパスが
`./js/xxxx.js`ではなく
`/js/xxxx.js`になってしまいパスが通っていない模様。

日本語で調べてみるも意外と同じ事象で悩んでいる人が少ない。なんでだ…。

# 解決策
最終的に役に立ったのは以下の投稿でした。（これもまた英語）
- [Add baseUrl option in vue-cli-service build command #1623（GitHub）](https://github.com/vuejs/vue-cli/issues/1623)

vue.config.js を作成して以下を定義するだけ。

```vue.config.js

module.exports = {
    baseUrl: './'
}
```


ちなみに、CLI2系では baseurl を使って指定していましたが、
CLI3.3からは`publicPath`が推奨されています。
baseUrlで実行してみるとWarningが出ます。


`WARN  "baseUrl" option in vue.config.js is deprecated now, please use "publicPath" instead.`

[公式サイト](https://cli.vuejs.org/config/#vue-config-js) にも書かれていますね。

>**baseUrl**
>Deprecated since Vue CLI 3.3, please use `publicPath` instead.

（訳：`baseUrl`はCLI3.3から非推奨だから、`publicPath`使ってね）

2019年以降の記事でもbaseUrlで解決するよ、って書かれてたりします。
Vue-CLI、けっこう頻繁に更新されているんですね。

以上、Vue-CLI3で詰まった点でした。
【Mac】herokuにpushしようとすると、SQlite3のエラーが出た時の話

#問題
- herokuにpushする時に `SQlite3はherokuでは使えないから、本番環境ではPostgresqlを使うような設定に変更してね` と言われた
- `git push heroku master`と打つと、下記のような感じのエラーが吐き出される 

```
remote:  !     Failed to install gems via Bundler.
remote:  !     Detected sqlite3 gem which is not supported on Heroku:
remote:  !     https://devcenter.heroku.com/articles/sqlite3
```

#対応
- エラー文の中に下記のような、特定のディレクトリーやファイルにPermissionがないというエラーが出た時は、`sudo chown -R <ディレクトリー名やファイル名>`でオーナーを自分に変えたり、`chown u+w <ディレクトリー名やファイル名>`で書き込み権限を与えたりすると対応できる。

```
Permission denied @ dir_s_mkdir - /Users/{Username}/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/extensions/x86_64-darwin-18/2.5.0-static/
```

- 下のように、このgemをinstallしてみて！といったエラー文を確認して、gem installしようとした際にも、上記のようなパーミッションのエラーが吐き出されることがあるので、その時は上記の対応を取ると、解決に近く。
 - 自分の場合は大体がパーミッション関係の問題だった

```
remote:        An error occurred while installing sqlite3 (1.3.13), and Bundler cannot
remote:        continue.
remote:        Make sure that `gem install sqlite3 -v '1.3.13'` succeeds before bundling.
```

- 上記で色々試しても、まだエラーが出るようであれば、bundle installする際に `--without production` のコマンドをつけてみる
  - これはSQlite3を本番環境で使うから、開発環境には関係ないよ。特にローカル環境での作業には本番（prod）の話は関係しないからinstallしません！程度に勝手に解釈している（正しい理解がある人に是非突っ込んでいただきたい....！）

```
bundle install --without production
```
AWS Batchが"Runnable"で止まった時に確認すること

やらかしたケアレスミスのメモ。

##原因
コンピューティング環境のインスタンスロールに、ECRから`git pull`するための権限が付与されていなかった。
つまり、インスタンスを立ち上げた後、`git pull ECR_ARN`をするとエラーが発生してしまい、処理が先に進んでいなかったようだ。このため、Jobを処理できない→Runnableで処理が止まる、といったことのようだ

AIMロールを付与することで、この問題は解決した。
「そういえばEC2で`git pull`するとエラーが起きたんだよなー・・・・あれ、待てよ？」と思ってやってみたら当たりだった。気になったらまずはやってみるのが吉

以下は勘違いだった。上記の対策を行ったところ、以下の環境でも正常に動作したため削除する
## ~~コンピューティング環境が0になっている~~
~~コンピューティング環境の入力の際、「必要なvCPU」の欄に、ケチって"1"を入力した。その後、EC2インスタンスが作成されないので何かおかしいと思ってコンピューティング環境を確認したところ、「必要なvCPU」が0にされていた~~

~~- 更新前~~
![image.png](https://qiita-image-store.s3.amazonaws.com/0/251426/c4d205fd-4672-8690-fdad-8849324f56c4.png)


~~- 更新後~~
![image.png](https://qiita-image-store.s3.amazonaws.com/0/251426/b0da4219-5fcf-f937-994e-9ed29c6d6915.png)

~~これではEC2インスタンスが作成されないため、実行できるはずがない。~~
~~なんとなく察してはいたが、vCPUは2の乗数でなければならず、2の乗数以外の数字が入力されると、入力した数字以下の2の乗数に自動で修正されるようだ~~

~~###例~~
~~- 入力：3~~
   ~~ - 修正後：2~~
~~- 入力：5~~
   ~~- 修正後：4~~


なおこの後、最大vCPUが初期値で256になっている罠を見落とし、とてつもなくリッチなインスタンスが立ち上げられるのを見てめちゃくちゃ焦った