OmniAICreator/Qiita-1.07M huggingface dataset:
指定したポートを占有しているプロセスをKILLするシェル書いた

最近lsofでKILLすること増えて、lsofいちいちするのが面倒になったので。

https://stackoverflow.com/questions/9168392/shell-script-to-kill-the-process-listening-on-port-3000
の内容を引数指定にしました。

```bash
#!/bin/bash
# @see https://stackoverflow.com/questions/9168392/shell-script-to-kill-the-process-listening-on-port-3000
pid=$(lsof -i:$1 -t)
echo ${pid}
if [ -z "${pid}" ]; then
  echo "port: '$1' not found. quit."
  exit 1
fi  
kill -TERM $pid || kill -KILL $pid
```

これをパスの通ったところに（私は `~/bin` とかにパスを通しています） `killport` とか適当な名前で保存して755のpermissionとかすればいいよね。使う時は以下のように。lsofで前後確認するとちゃんとKILLされたのがわかる

```
$ lsof -i:3000 
COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ruby    70638  ms2sato    9u  IPv4 0xe754e6b893fe4a91      0t0  TCP *:hbci (LISTEN)
$ killport 3000
70638
$ lsof -i:3000 
$
```
carthage updateでgitのエラーが発生して処理が中断してしまうときの対応方法

情報が古くなっており、メンテナンスが難しいため、こちらのページはアーカイブさせていただきました。

古い情報でも閲覧を希望される場合は、編集履歴からご覧くださいませ。
git initで"Reinitialized existing Git repository in ..."とか出たのをエラーと勘違いした

gitのファッキン初心者なのでいまいち理解できていません。

ようやく形をつかめてきたような状況です……

なのでこんなしょーもないところでつまづきます。

# しょーもな

`laravel new XXXXX`でプロジェクトを作成しました。

githubで管理したかったので、適当に検索して見つけたハウツーを見ながら`git init`をしました。

```bash:
$ git init
Reinitialized existing Git repository in /Users/~~~~~/app/share/test1/XXXXX/.git/
```

あれ、返ってきたメッセージがちゃうやん、ってなりました。
慌ててメッセージで検索してもそれらしい情報が出てきません。

1分くらい慌ててから、よく読んだらそもそもこれ、
**エラーメッセージじゃなくて『すでにあるやつをもっかい初期化しましたよ』って書いてあるだけ**
ということに気付きました……。

なぜか「初期化に失敗しました」みたいなメッセージだと思いこんでしまいました。

gitだけじゃなくて英語もイマイチだということを自覚させられた平日の朝のニートでした。

# ちなみにReinitializedといっても
まっさらな状態に上書きされるわけではないみたいです。

- https://stackoverflow.com/questions/19397888/how-to-undo-misoperation-of-reinitialized-existing-git-repository

```bash:
mbp:nsna raging_alpaca$ git log
commit ~~~~~ (HEAD -> master)
Author: Raging Alpaca <~~~~~@~~~~~>
Date:   Wed May 9 10:14:27 2018 +0900

    first

mbp:nsna raging_alpaca$ git init
Reinitialized existing Git repository in /Users/~~~~~/app/share/test1/nsna/.git/

mbp:nsna raging_alpaca$ git log
commit ~~~~~ (HEAD -> master)
Author: Raging Alpaca <~~~~~@~~~~~>
Date:   Wed May 9 10:14:27 2018 +0900

    first
mbp:nsna raging_alpaca$ 
```

ほんとだ。
オブジェクト指向設計実践ガイド4章がめっちゃわかりやすかったのでメモ

## 前置き

この記事は[オブジェクト指向設計実践ガイド](https://www.amazon.co.jp/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E8%A8%AD%E8%A8%88%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-Ruby%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8B-%E9%80%B2%E5%8C%96%E3%81%97%E3%81%A4%E3%81%A5%E3%81%91%E3%82%8B%E6%9F%94%E8%BB%9F%E3%81%AA%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E8%82%B2%E3%81%A6%E6%96%B9-Sandi-Metz/dp/477418361X)を読んだ個人の感想メモです。
内容については、自分で考えた具体的な例を交えて書いてあります。内容に勘違いがありましたら、そっと教えていただけますと嬉しいです。

## オブジェクト指向設計実践ガイド4章「柔軟なインターフェースを作る」

オブジェクトは「何を望むのか」をメッセージとして伝えるべきであって、「どうやるのか」を知っておく必要はない。

（例）
たとえば、CustomerがBicycleをレンタルしたいとする。
このときに、CustomerはBicycleを用意してくれる、Mechanic(整備士)に何を伝えるべきだろうか？

もし、CustomerがBicycleについて詳しい場合

- 「ちゃんとパンクしてないか確認して！」
- 「ブレーキがちゃんと効くか確認して！」
- 「サドルがちゃんと固定されているか確認して！」
…

のように「どうやるのか」の具体的なメッセージをMechanicに送ることになる。

確かにこれで、Bicycleはレンタルできるかもしれないが、これには致命的な問題がある。

それはCustomerはレンタルできるBicycleの条件を常に知っていなければならないということ。
もし今後、Carもほしい、Airplainもほしい、、、となったときに、Customerはそれぞれのレンタルできる具体的なメッセージを持ち続けることになる。

極端な例だが、Bicycleに夜間のための反射板をつけていないことが違法になったとする。
このときCustomerはそのことを知らなかったが故に、警察に捕まってしまった、という事態になり兼ねない。

ではCustomerはどうすればよかったのか。
常にBicycle、Car、Airplainのレンタル条件について知り続ける？

ここで初めて「delegate(委譲)」という概念が生まれる。
そして、冒頭の「何を望むのか」をメッセージとして伝えるべきであって、「どうやるのか」を知っておく必要はない。」が繋がってくる。

つまり、CustomerはMechanicに対して「いい感じのBicycle用意してよ」と丸投げする。
CustomerはMechanicが”いい感じの”Bicycleを用意してくれると期待している。
当然、CustomerはMechanicがタイヤの圧を確認しているのか、とか、反射板のテストをしているか、とか知っていない。

これにより、CustomerはCar、Airplainに関してもそれぞれ「いい感じに用意してよ」という「何を望むか」のメッセージを送るだけで済むようになった。

もちろん、「いい感じ」はCustomerによって異なるので、レンタルしたい日時や予算感を教える（メソッドに引数を渡す）ことが必要になってくる。

（現実の仕事でも、予算感も締め切りも言わずに、いい感じにしておいてーってのはヤバイ仕事とかだと意外とよくある話かも...w）

というお話。

## まとめ

抽象化すると、
Mechanicに対して「どんなメッセージを送ればいいのか」 = 「Mechanicとのインターフェースは何が適切か」ということを考えることが大切であるということ。

本では「お客がレストランでメニューを見て注文して、出てきた料理を食べる」という事象に対して、「レストランでお客がレストランでメニューをみて注文したと思ったら、厨房に入ってきてスープを作り始めた」ってどう考えてもおかしいよねwっていう話が書いてあってめっちゃ納得した。
Android Studioがapkを作る時に使っているJavaのPathのメモ

windows版android studioが使っているjavaのpathが、どこからapkを作るかによって違うということに気づいたのでメモ
# Javaのpathの設定方法
## OSの環境変数
システムの環境変数にJAVA_HOMEを作ってPathに%JAVA_HOME%\binを追加するという一般的なアレ。
## android studio のJDK location
android studio の画面上部のタブの一番左の、File>Other Settings>Default Project Structure　から設定するJDK location

# どちらのPathのJavaが使われるか
## Build>Make ProjectやBuild>Build APK(s)やInstantラン時
android studio の画面上部のタブの、Build>Make ProjectやBuild>Build APK(s)や、その下の段にあるinstantラン(▶)やデバッグからapkを作るときは、android studio のJDK locationが使用されている。
## Terminalからgradlew assemble〇〇などした時
android studio の画面下部のタブの、Terminalから、gradlew assembleDebugなど、コマンドラインからAPKを作成したときはOSの環境変数で設定したPathのJavaが使用されている。
PostgreSQLの論理レプリケーションを両向きに指定すると無限に書き込まれる

以前行った[DockerをつかってCentOS7上でPostgreSQLの論理レプリケーションを試す](https://qiita.com/miyawa-tarou/items/5964d364aa6f5747d45c)では、
論理レプリケーションを試したが、もしデュアルマスタ的に両向きに行うとどうなるか試した。
結果はある意味当たり前だが、タイトルの通り無限にレプリケーションし続けた。

### 設定

基本的作業は記事のマスタ設定を両サーバーに行う
そして、テーブル作成から

```sql

# M/S共通
CREATE TABLE test_table (
    id              SERIAL,
    name            varchar(80)
);
CREATE ROLE test WITH LOGIN REPLICATION PASSWORD 'hogehoge';
GRANT ALL ON test_table TO test;

# M
ALTER SEQUENCE test_table_id_seq INCREMENT BY 2;
# S
ALTER SEQUENCE test_table_id_seq INCREMENT BY 2 RESTART WITH 2;

# M
CREATE PUBLICATION pub_srv1_test_table FOR TABLE test_table;
# S
CREATE PUBLICATION pub_srv2_test_table FOR TABLE test_table;

# M
CREATE SUBSCRIPTION sub_srv3_test_table CONNECTION 'dbname=testdb host=postgresql2 port=5432 user=test' PUBLICATION pub_srv2_test_table;
# S
CREATE SUBSCRIPTION sub_srv4_test_table CONNECTION 'dbname=testdb host=postgresql1 port=5432 user=test' PUBLICATION pub_srv1_test_table;
```

### 実行

こんな感じに設定して、1回INSERTしてみる。

```sql
Insert into test_table (name) values('aaa');
```


無限に増えていく

```sql

testdb=# select * from test_table;
 id | name
----+------
  1 | aaa
  1 | aaa
  1 | aaa
  1 | aaa
  1 | aaa
  1 | aaa
  1 | aaa
  1 | aaa
  1 | aaa
  1 | aaa
  1 | aaa
testdb=# select count(*) from test_table;
 count
-------
    88
(1 row)
testdb=# select count(*) from test_table;
 count
-------
    96
(1 row)
```
Rubyベンチマーク集


- 気になったものをどんどんベンチマークをとって比較していきます

## ベンチマークテンプレート
- ベンチマークのコードは共通なので、最初に書いておきます

```rb
require 'benchmark'

Benchmark.bmbm(10) do |r|
  r.report "test1" do
    # exec test1
  end
  r.report "test2" do
    99999999.times do |i|
      test2(i)
    end
  end
end
```

## 偶奇判定
### コード
- 先ずは奇数判定から

```rb
require 'benchmark'

def test1(n)
  n.odd?
end

def test2(n)
  n & 1 == 1
end

Benchmark.bmbm(10) do |r|
  r.report "test1" do
    99999999.times do |i|
      test1(i)
    end
  end
  r.report "test2" do
    99999999.times do |i|
      test2(i)
    end
  end
end
```

### 結果
- `odd?`の方が早い

```
Rehearsal ----------------------------------------------
test1        7.950000   0.010000   7.960000 (  7.984393)
test2        8.820000   0.020000   8.840000 (  8.868345)
------------------------------------ total: 16.800000sec

                 user     system      total        real
test1        7.810000   0.010000   7.820000 (  7.841257)
test2        8.770000   0.020000   8.790000 (  8.803263)
```

### コード
- お次は偶数

```
def test1(n)
  n.even?
end

def test2(n)
  n & 1 == 0
end
```

### 結果
- こちらもevenの方が早い

```
Rehearsal ----------------------------------------------
test1        8.240000   0.060000   8.300000 (  8.447544)
test2        9.810000   0.070000   9.880000 ( 10.163554)
------------------------------------ total: 18.180000sec

                 user     system      total        real
test1        8.190000   0.050000   8.240000 (  8.424226)
test2        9.430000   0.060000   9.490000 (  9.701474)
```
Python 文字列に使う『r"文字列"』『 u"文字列"』 ってなんて検索するの？

しょうもないお題ですが、ふと

```
r"文字列"
u"文字列"
```

の

『r』や『u』って何なんだ？と思いたち調べようとしました。

いや、これらが何か自体は知ってますが、何とググれば検索できるのだろうと。。。

結果、

```
r"文字列" ... raw文字列 / raw string literal
u"文字列" ... unicode文字列 / unicode string literal
```

などと検索すると良いと思われます。

言語仕様でいろんなものが簡素化して表現できるのはありがたいですが、
検索しようと思うと大変ですね。。。

JavaScript の 『&&』 の 正式な仕様を調べたくて検索しようとした時も困りました。。。

Reactなどで使われるイディオム

```
className={`foo ${bar && "piyo"}`}
```

の『&&』の使い方がわからず調べたかったのですが、まぁ、検索に引っ掛けれないこと引っ掛けれないこと。
【Laravel】ミドルウェアの考え方・作成方法・ファイルの場所

## はじめに
プライベートで独学でLaravelを勉強しています。
アウトプットした方が記憶定着に良い、との事なので備忘録もかねて、まとめます。
間違ってたら、ご指導いただくとありがたいです。
では参ります。

## Laravelミドルウェアの概念
Laravelのミドルウェアは、リクエストがコントローラのアクションに届く前に配置されるレイヤー層となる部分です。
MVCモデルは、特定のアドレスにアクセスがあると、Rootingを元に指定のコントローラのアクションが走りますよね？
ミドルウェアはその前後に割り込んで、指定の処理を実行出来ます。
コントローラの処理とは分離してます。

図にするとこんな感じです。アクションの前後にミドルウェアを仕込める。
<img width="843" alt="プレゼンテーション1.png" src="https://qiita-image-store.s3.amazonaws.com/0/182399/415a8545-f3ce-3309-dc31-5687ccb72f41.png">



## ミドルウェアの作成
手作業でも出来ますけど、Artisanで簡単に出来ます。
以下のコマンドで作成可能です。

```php:artisanのコマンド
php artisan make:middleware ミドルウェアの名前
```
<br>
例えば、HelloMiddlewareを作成した時は、こんな感じ

```php
php artisan make:middleware HelloMiddleware
```

## どこにファイル出来たのか？
app/Http/Middlewareに作成されます。
既にいくつかのミドルウェアが入っています。ここに作成したミドルウェアが追加されていきます。



### 参考
- PHPフレームワーク-Laravel入門-掌田津耶乃
dockerコンテナで稼働するredmineにプラグインを追加した

# はじめに
この記事ではUbuntu16.04上で、docker-composeでsameersbn/redmineからredmineイメージを起動しています。

# コンテナ内のプロセスへアクセス

まず、コンテナ内でプロセスが実行できるようにします。

`sudo docker ps`  

を実行して、redmineが稼働するプロセスを調べます。

```
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS                     NAMES
hogehoge        sameersbn/redmine:latest     "/sbin/entrypoint.sh…"   5 months ago        Up 12 days          80/tcp, 443/tcp           docker_redmine_1
```

CONTAINER ID か NAMES を確認します。

```
sudo docker exec -it docker_redmine_1 bash
```

と実行すると、コンテナ内のプロセスへアクセスできます。
今回はNAMES docker_redmine_1 と入力しましたが、CONTAINER ID を入力しても同じです。

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

今回は[redmine-slack](https://github.com/sciyoshi/redmine-slack)をインストールします。

まず、プロセスへアクセスした状態で、ディレクトリを移動します。redmine直下のpluginsへ移動します。

```ディレクトリ移動
/home/redmine/redmine# cd plugins/
```
次にgitリポジトリよりgit clone にてダウンロードします。

```
git clone https://github.com/sciyoshi/redmine-slack
```

その後

```
bundle exec rake redmine:plugins:migrate RAILS_ENV=production
```

を実行

`exit` でコンテナから抜けます。

その後

```
sudo docker restart docker_redmine_1
```

でdockerを再起動

後はredmineにログインして、管理→プラグインを確認すると、プラグインが追加されています。

# 追加：プラグインの設定画面がエラーになる

管理→プラグインからredmine-slackの設定をクリックすると404になります。
[この記事](https://qiita.com/truly109/items/9cdaf6edb7f4c6ff65ab)で回避
cordova build android でエラー

cordova build android でビルドすると急にエラーが出るようになった。

```
com.android.ide.common.process.ProcessException: Failed to execute aapt
```

調べてみると build.gradle ファイルを編集すればいいと書かれていたが、プラットフォーム追加の度に編集するのは面倒なので他の方法を探したら見つけた。
プラグインをインストールするだけで治りました。

```
cordova plugin add cordova-android-support-gradle-release
```

参考：
https://stackoverflow.com/questions/49183917/failed-to-execute-aapt-with-cordova
AIでLINEから自動文字起こししてくれる「文字おこし君」を作りました。

こんにちは、DAIです。[@never_be_a_pm](https://twitter.com/never_be_a_pm)

# 作ったもの

- LINEに画像を送信すると、自動で文字起こししてくれる「文字起こし君」を作りました。

![文字起こし君.gif](https://qiita-image-store.s3.amazonaws.com/0/134704/ede0b86f-86f7-8862-4d9b-09b657fbcaf3.gif)

# 開発背景

- **紙媒体の文字を手作業でPCに写すのいまだにやっているのは、21世紀を生きている人類としてはあきらかにおかしいと思ったため**です。
- 自身が学生時代の時、論文を作る際紙の文献を引用するのが非常に面倒くさかったので、LINEでスクショ→文字起こしまでできれば非常に楽かと思いました]
- Google Documentでもできると思うのですが、ITに疎いじいさんばあさんにはアクセシビリティが悪いので、誰でもできるようなLINEでできたらよいなと感じました。

# 反響

- 自分自身が問題意識を持っていた学生はもちろん、Webの編集者などに非常な大きな反響がありました。
- デモを載せたツイートは5万RTに到達しました。
- 各種メディア連載もされました。
    * [LINEで「画像内の文字起こし」が可能なAI登場！ 画像を送信するだけ超簡単](http://www.appps.jp/291352/)
    * [LINE『文字起こし君』画像を送信すると、AIが全部文字おこしして返してくれる。友達追加できます！](http://www.appps.jp/291352/)
    * [INEに画像を送信するとAIが全部文字起こしして返してくれる「文字おこし君」が誕生！「前からあったら！」「便利すぎる！」と大評判！](https://togetter.com/li/1221356)

# 現在の稼働状況

- **ユーザー数が9万人を超え、一日のリクエストがGoogle Apps Scriptの利用制限を余裕で超えてしまうので、現在利用できません**
- 利用したい方は下で紹介する記事を参考に作ってください！

![文字起こし君.PNG](https://qiita-image-store.s3.amazonaws.com/0/134704/2eca9e9c-8c75-ec4b-e56f-8959c808253f.png)


# 実装技術

- LINE Messaging API
- Google Apps Script
- Google Cloud Vision API
- LINE Messaging APIからGoogle Apps Scriptに画像を送信、その後LINEからGoogle Cloud Vision APIに画像を送信し、文字起こしされた結果を再度LINEに投げる処理をしています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/134704/10963dcf-60ef-24e7-ad0c-d3a9956cde50.png)


# 難易度

- 超絶低いです。Google製JavaScriptとも呼ばれる、Google Apps Scriptと、Web API、HTTPの利用方法がわかれば簡単に作れます

# 学んだこと

- Web API is 面白い
- スキルなくても面白いものは創れる！

# 作り方

- すでにPythonでの実装方法は、みかん3世さん(@mikan3rd)が以下の記事でまとめてあります。
    - [[python] LINEの文字起こし君を作ってみた](https://qiita.com/mikan3rd/items/f0b6ff57dbcedc79a22d)
- ただし、プログラミング初心者には少し難しいかもです
    - Pythonの環境構築が必要
    - Herokuも初心者にとっては難しい(コマンドラインが使えないとできない)
- 今回実装されているのは、基本的なJavaScriptさえかければ、非常に簡単に創れるようになっています。
    - サーバーレスなのでディプロイ不要
    - Google Apps Scriptなので環境構築一切不要
- ちょっとProgateあたりでJavaScript書けるようになった！みたいな人でも創れるので、自分で作ってみたい場合は、下記記事にチュートリアルとしてまとめています。興味がある人はぜひ読んでみてください。

[【AIプログラミング】LINEに画像を送ったら自動で文字起こししてくれる機械学習アプリを作ろう](https://note.mu/daikawai/n/n9e203dd4063a)
Safariだと3rd party cookieの制約（ITP）で、別ドメインへのAJAXコールでCookieが付与されないお話

# 概要

Javascriptで別ドメインへのAJAXコールを行う処理を実装していたところ、ChromeやFireFoxでは問題なく動作したが、SafariではCookieが送信されていないことに気づいたというお話（その際特にエラーも出ず、ただ単にCookieが送信されない）。

# 原因

[safariのITS対応](https://www.comix.co.jp/wp_blog/ad/860) なるものがあったらしく、
Safari11.0からはデフォルトで3rd party cookie（別ドメインに対し付与されるCookie）は禁止されるようです。
*ひでぇ…あんまりだ…*

（Chrome等別のブラウザでも、3rd party cookieは広告での利用が多くユーザへの利便性がないため禁止する方向に向かっているようで、例えばChromeでは設定を変更すれば禁止できるようです。今後は原則考慮に入れる必要がありそうです。）

[参考: Safariの新機能ITPと広告、Cookieについてのおさらい](https://qiita.com/tsubamechi/items/72bc6664ab80b8bef0b4)

# 構成

*※ ドメイン等一部の値は仮の値を入れています*

HTMLを返すWebサーバと、AJAXコールで呼び出す用のAPIサーバが別サーバになっており、ドメインも完全に別のものになっていた
* HTMLを返すWebサーバの中身はWordpress （ドメイン：www.service.com）
* APIサーバはHerokuでNodeJsのExpress （ドメイン：api.heroku.app）

つまりwww.service.comから取得したJavascript上で、api.heroku.appへリクエストを送信する。

# 対策

最終的にはAPIサーバのドメインを、api.service.com にすることで回避しました。
（挙動的を見る限りは、レジストラから取得したドメインservice.comのサブドメイン同士であれば、1st party cookieとして扱われるっぽいです）
【PHP】パスワードをハッシュ化するプログラム

##パスワードをハッシュ化するプログラム
今回は、[PHP逆引きレシピ](https://www.amazon.co.jp/PHP%E9%80%86%E5%BC%95%E3%81%8D%E3%83%AC%E3%82%B7%E3%83%94-%E7%AC%AC2%E7%89%88-PROGRAMMER%E2%80%99S-RECiPE-%E9%88%B4%E6%9C%A8/dp/4798119873/ref=sr_1_1?ie=UTF8&qid=1525907612&sr=8-1&keywords=PHP%E9%80%86%E5%BC%95%E3%81%8D%E3%83%AC%E3%82%B7%E3%83%94)を参考に、パスワードをハッシュ化するプログラムを作成します。

今回の記事を読めば、こんなものが作れます。↓
![ 2018-05-10 8.08.22.png](https://qiita-image-store.s3.amazonaws.com/0/254159/78fa302d-9ede-be36-f761-70ea1559273d.png)

パスワードのハッシュ化をすると、例えば
`japan`
というパスワードが
`$2y$10$mQj/zSQ.SgOW50oHI6GofeR.rrxljB1tkveLCvvyXF5BYNDMhSKG.`
このようなハッシュ関数に変換されます。
このようにハッシュ関数に変換できるプログラムを今回は作成します。

＊PHPの古いバージョン(5.5以前くらい)には対応していません。対応させるには別途プログラムを読み込む必要がありますが、今回は省略します。詳細はPHP逆引きレシピを読んでみてください
### １．エスケープ処理をするプログラムを作成する
パスワードのハッシュ化をするプログラムを作成する前に、HTMLのエスケープ処理をする関数を作ります。
HTMLのエスケープ処理とは、特殊文字をブラウザに表示するために行うものです。

```php:h.php
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>HTMLでのエスケープ処理をする関数</title>
</head>
<body>
<?php 

//HTMLでのエスケープ処理をする関数
function h($var) {
	// is_array() -> $varが配列かどうかを調べる
	// $varが配列だったら・・・
	if (is_array($var)) {
		// array_map() -> 配列の各要素に対して指定した関数を実行する
		// array_map('コールバック関数名',配列)
		return array_map('h', ($var));
	// $varが配列じゃなかったら・・・
	} else {
		// フォームなどからのユーザーのデータをブラウザに表示する場合は、
		// 原則すべてのデータにhtmlspecialchars関数を使用する。
		// ENT_QUOTES -> クオートを変換する
		return htmlspecialchars($var, ENT_QUOTES, 'UTF-8');
	}
}

?>
</body>
</html>
```

###２．ハッシュ化するプログラムを作成する
ここから本題のプログラムです↓

```php:hash_program.php
<?php 

//エスケープ処理をする関数を指定する
require_once 'h.php';

if (isset($_POST['submit'])) {
	$password = $_POST['password'];

	// ハッシュ処理の計算コストを指定。ソルトは自動生成とする
	// ハッシュ処理の計算コストとは、
	// 連想配列：costという引き出しの中に、10を格納する
	$options = array('cost' => 10);

	//  ハッシュ化方式にPASSWORD_DEFAULTを指定し、パスワードをハッシュ化する
	// password_hash -> パスワードハッシュを作る
	// $password -> ユーザーのパスワード
	// PASSWORD_DEFAULT -> パスワードのハッシュに使うアルゴリズム
	// $options -> オプションを含む連想配列
	$hash = password_hash($password, PASSWORD_DEFAULT, $options);
}

 ?>

 <!DOCTYPE html>
 <html lang="ja">
 <head>
 	<meta charset="UTF-8">
 	<title>ハッシュ化済みパスワードを取得するスクリプト</title>
 </head>
 <body>
<?php 

// $hashが入力されたら・・・
if (isset($hash)) {
	echo '生パスワード：'.h($password).'<br>';
	echo 'ハッシュ化済みパスワード：'.h($hash).'<br>';
}

// パスワードがハッシュにマッチするか調べる
// $password -> ユーザーのパスワード
// $hash -> password_hash()が作ったハッシュ
$auth = password_verify($password, $hash);

//もし$authがtrueだったら・・・
if ($auth) {
	echo "yay!!!パスワードがハッシュにマッチしています！";
} else {
	echo "パスワードがハッシュにマッチしていません";
}

 ?>
 <hr>

 <form action="password_hash.php" method="post">
 	<label for="password">ハッシュ化したいパスワード文字列：</label>
 	<input type="text" name="password" id="password" value="">
 	<input type="submit" name="submit" value="ハッシュ化">
 </form>
 </body>
 </html>
```

以上です。

###参考文献

[PHP逆引きレシピ](https://www.amazon.co.jp/PHP%E9%80%86%E5%BC%95%E3%81%8D%E3%83%AC%E3%82%B7%E3%83%94-%E7%AC%AC2%E7%89%88-PROGRAMMER%E2%80%99S-RECiPE-%E9%88%B4%E6%9C%A8/dp/4798119873/ref=sr_1_1?ie=UTF8&qid=1525907612&sr=8-1&keywords=PHP%E9%80%86%E5%BC%95%E3%81%8D%E3%83%AC%E3%82%B7%E3%83%94)
Qiitaの様なサービス作成中 ローカル環境構築 連載(1)

## 基本情報

[次に作りたいQiita、dev.toの様なサービスについて](http://alphabrend.hatenablog.com/entry/2018/05/07/090803) で書いたサービスを開発中です。

アルファバージョンで公開中です。 [Crieit](https://crieit.net)

## ローカル環境構築

とりあえず最初の1歩としてローカル環境を作ります。ちなみに下記の構成で開発を行います。

* PHP7.2
* Laravel5.6
* MySQL5.7 (どこかで8にしたい)
* Vue.js
* Bootstrap Material Design

### Docker

ローカル環境はdocker-composeを使います。

```yml:docker-composer.yml
version: '2'
volumes:
  mysql_data:
    driver: 'local'
services:
  mysql:
    image: mysql:5.7
    volumes:
      - mysql_data:/var/lib/mysql
    ports:
      - 3307:3306
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: "true"
      MYSQL_DATABASE: dbname

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=mysql
      - PMA_USER=root
      - PMA_PASSWORD=
    ports:
      - 8001:80

  app:
    image: dala00/laravel:7.2
    volumes:
      - .:/var/www/app
    working_dir: /var/www/app
    ports:
      - "8000:80"
    tty: true
    stdin_open: true
```

これで`docker-compose up -d`するだけ。プロジェクトがあればlocalhost:8000でアクセスできるようになります。

ちなみにLaradockは複雑化しているという情報をどこかで見たのと、準備が面倒そうだったので使っていません。Laravelのイメージは適当に作ったものをDockerHubに登録しています。(yarnは入れ忘れてるのでPCにインストールされてるのを使ってます）

```docker:Dockerfile
FROM php:7.2-apache

RUN apt-get update && apt-get install -y git zlib1g-dev libxml2-dev
RUN curl -sS https://getcomposer.org/installer | php
RUN mv composer.phar /usr/local/bin/composer
RUN a2enmod rewrite
RUN sed -ri -e 's!/var/www/html!/var/www/app/public!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!/var/www/app/public!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
RUN docker-php-ext-install pdo_mysql mbstring zip xml
WORKDIR /var/www/app
```

### Laravelインストール

公式のマニュアル通りです。

```sh
composer global require "laravel/installer"
laravel new qiita
```

docker-compose upしてあればもうサーバーは動いているのでこれでlocalhost:8000で閲覧できると思います。

### Bootstrap Material Design導入

Bootstrap Material Designを導入します。これはBootstrapでMaterial Designを実現するために拡張されたものです。Bootstrapのカラムなどもそのまま使えます。

Laravelは元々yarn.lockが入っているのでyarnでインストールします。(バージョンは適宜置き換え）

```sh
yarn add bootstrap-material-design@4.1.1
```

Laravelには元々Bootstrapの初期化処理が入っているので、そこも修正しておきます。(作ったプロジェクトのbootstrap.jsを読み込んでいるところもあり紛らわしいので注意）

```javascript:resources/assets/js/bootstrap.js
    // require('bootstrap'); をおきかえ
    require('bootstrap-material-design');
```

```scss:resources/assets/sass/app.scss
// @import '~bootstrap/scss/bootstrap'; を置き換え
@import '~bootstrap-material-design/scss/bootstrap-material-design';
```

あとはBootstrap Material Designのjsの初期化を入れておきます。

```js:resources/assets/js/app.js
const app = new Vue({
    el: '#app',

    mounted() {
      $('body').bootstrapMaterialDesign();
    }
});
```

これで[Bootstrap Material Designのドキュメント](https://fezvrasta.github.io/bootstrap-material-design/docs/4.0/getting-started/introduction/)の「Material Design」もしくは「Bootstrap Components」を参考にしてhtmlを追加してみると表示されるようになっていると思います。

ちなみにビルドも必要なのでまだビルドしてない場合は下記を実行しておきます。jsやscssファイルを更新すると自動的にブラウザに反映されます。（テンプレート上でapp.js, app.cssを読み込む場合はurl関数などではなくmix関数で読み込むようにしておく必要があります）

```sh
yarn run hot
```


## 次回

多分Laravel Socialiteを使ってむちゃくちゃ簡単にソーシャルログイン実装
もしくはフルボトルの非ベストマッチパターン考察
Windows10のバージョン1709(Creators Update)にアップデートできない問題の解決法

Windows10のWindowsUpdateで、バージョン1709(Creators Update)に何度やっても失敗する時の解決法です。

##駄目だった対処法
下記対処（トラブルシューティング）を行いましたが、アップデートできませんでした。
 [Windows updateができない･失敗をくりかえす時の一般的な対処方法](https://freesoft.tvbok.com/tips/pc/windows_update_2.html)

##解決した対処法
下記サイトにアクセスして、「今すぐアップデート」※をクリックし、ダウンロードされたWindowsアシスタントを実行。
後は、表示される項目に従って進めていくだけで、自動でWindowsUpdateが実行されます。
[Windows10のダウンロード](https://www.microsoft.com/ja-jp/software-download/windows10)

※Windows10以外のPCでアクセスすると、「今すぐアップデート」のボタンは表示されないようです。

##結果
WindowsUpdateは無事終了しましたが、本対処を行ったのが2018/05/09であり、2018/04/30にはバージョン1803(April 2018 Update)が提供されており、1803へのアップデートとなりました。
The Bash in Tokyo

<p>今年も WWDC (Worldwide Developers Conference) の季節となりました。</p>

<p>WWDCについて詳しくない方もいらっしゃると思いますので説明しますと、Appleが毎年春ごろに一週間かけて開催される開発者向けイベントで、今年は6/4(月)〜8(金)に開催となります。そして、WWDC期間中の木曜日の午後にはBashと呼ばれる野外パーティが開催されています。</p>

<p>WWDCでは、開発者向けにMacやiPhoneの次期OSと、その新機能をプロダクトに組み込むための手法が発表されるのと、Appleのエンジニアに直接疑問をぶつけられるということで、開発者にとって関心が高いイベントですが、近年はiPhoneアプリケーション開発者の増加によって人気が高いイベントとなり、すぐにチケットがソールドアウトとなってしまいます。<br />
今回も参加を希望されて、残念ながら抽選で外れた方もいらっしゃると思います。</p>

<p>そこで、MOXSSG （Mac OS X Server勉強会）というグループでは、WWDCのチケットが買えず、日本残留組となった方々と『The Bash in Tokyo』というイベントを開催していました。
今回、このイベントをより幅広い方が参加できるように、MOSAとMOXSSG、Cocoa勉強会 関東と合同で『The Bash in Tokyo』を開催することにいたしました。</p>

<p>本家と違って、会場も屋内でクールなバンドもきません。食べ物も飲み物も基本的に参加者の持ち込みとなります。
でも、WWDCについて語り合いたいという共通の目的がある方々が集まります。WWDCをつまみにビールでも飲みながら語らいましょう。</p>

# 参加条件

<ui>
<li>アルコール提供イベントの為、20歳以上とさせて頂きます。</li>
<li>イベントの様子の写真は撮影しますのでご了承ください。（SNS等で公開予定）</li>
<li>コンサルタントやエンジニア、ライターなど、Appleの最新技術に興味がある方。</li>
<li>飲食の持ち込みをお願いします。例えば、缶ビール1セットやワイン、ピザなどです。</li>
</ul>

# イベント概要

<ui>
<li>WWDCセッション動画を皆で視聴します。</li>
<li>WWDCで発表された気になるトピックを希望者が発表します。</li>
<li>今回のWWDCについて、皆でディスカッションします</li>
</ul>

# 当日のタイムスケジュール（予定）

<pre><code>17:00 受付
* WWDCセッション動画（Keynote）の視聴
18:00 乾杯
18:00 キーノート（テクノロジーライター 大谷 和利）
18:30
* WWDCセッション動画（リクエスト または State of the Union）の視聴
* 発表数本
* ディスカッション
21:00 終了
22:00までに解散
</code></pre>

# 申し込み

<ui>
<li><a href="https://cocoa-kanto.connpass.com/event/85554/">https://cocoa-kanto.connpass.com/event/85554/</a></li>
</ul>

<p>※各グループのメンバーが定員オーバで申し込めないという状況を避けるため、グループ毎に申し込みページを用意しています。
　Cocoa勉強会は上記となります。</p>

【関連情報】
<a href="https://cocoa-kanto.connpass.com/event/85554/">The Bash in Tokyo</a><br />
<a href="https://note.mu/mosa_media/m/me339a1d6e3f2">Application Engineer Journal "猛者"</a><br />
<a href="https://cocoa-kanto.connpass.com/">BUKURO.swift</a><br />
<a href="https://www.facebook.com/groups/cocoa.kanto/">Cocoa勉強会 関東</a><br />
<a href="https://mosa.connpass.com/">MOSA</a><br />
<a href="http://www.bitz.co.jp/weblog/">Cocoa練習帳</a><br />
<a href="https://qiita.com/m_yukio>Qiita</a><br />
rails consoleでupdateができない理由を知りたい時（rollbackされる）

以下を使って、エラーの内容を見ましょう。

```
インスタンス.errors.full_messages
(例)user.errors.full_messages
```

## 起きたこと
rails console上で名前だけを更新しようとして更新できなかった。

```console

更新がrollback(巻き戻し)される
>> user.update(name: "Kohei Kishimoto")
   (0.1ms)  begin transaction
  User Exists (0.3ms)  SELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) AND "users"."id" != ? LIMIT ?  [["email", "example@rai
lstutorial.org"], ["id", 1], ["LIMIT", 1]]
   (0.1ms)  rollback transaction
=> false

エラーメッセージを確認
パスワード入れろやコラ、と言われている
>> user.errors.full_messages
=> ["Password can't be blank", "Password is too short (minimum is 6 characters)"]

```

```console

パスワード入れて更新する
>> user.update(name: "koheikishimoto", password: "1234567890", password_confirmation: "1234567890")
   (0.1ms)  begin transaction
  User Exists (0.2ms)  SELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) AND "users"."id" != ? LIMIT ?  [["email", "example@rai
lstutorial.org"], ["id", 1], ["LIMIT", 1]]
  User Update (1.9ms)  UPDATE "users" SET "name" = ?, "updated_at" = ?, "password_digest" = ? WHERE "users"."id" = ?  [["name", "koheikishimoto"],
["updated_at", "2018-05-08 20:08:42.795109"], ["password_digest", "$2a$10$wD0rVfl8RiRUx2EfXMc6n.cfD/gTm/rbo.n6zxxZkdd/Y9rqEe5/G"], ["id", 1]]
   (1.6ms)  commit transaction

更新できた。
=> true
```
【速報】Google I/O 2018 Keynote

サンフランシスコで開催中のイベント「Google I/O 2018」を、yahooさんのLODGEで夜中2時から生中継で観たので共有！

去年のI/Oで「モバイルファースト」から「AIファースト」になって、どういうこと？って感じでしたが、今回Googleが本気でAIに取り組んでる感が伝わりました。
 

#ヘルスケア

ヘルスケアの分野が、最もAIを使った解決を促しているというお話で、人間は表面的なことしか見れないのに対して、AIは年齢、性別、タバコ、BMIなどを認識して患者を観ているというのが、革命でした。

 

#音声認識

2人の声を認識して、別の声として認識している。この精度もすごかったです。

 

#Gmail

Gmailで文字を打つ中、勝手にAIが予想して文面を作ってくれる。例えば、「いつも」だけ打てば、「いつもお世話になっております。」みたいに学習してくれ、自分専用にカスタマイズできるっぽい。すごい。

 

#カメラ

人を認識するだけでなく、明るさを自動調節してくれて、机の上の書類を書類の部分だけPDF化してくれたり。簡単にバックグラウンドを白黒にできるし。白黒写真に色をつけてくれる。つかってみたい。

 

#音声認識

30言語、80カ国に対応。hey google 〇〇に対する質問も、即答してくれる。ナチュラルな発音に（英語は6種類の声？）1つの文脈に2つの質問があった場合、2つの質問に答えてくれる。子供の雑談にも、しっかり付き合ってくれる。感情も認識してる！？

 

#音声とデバイスの融合

「レシピ見せて」と言えば、デバイスで料理動画が流れたり、「温度を調整して」と言えば、温度調節の画面になる。アマゾンみたいに買い物ができたり、運転しながらGoogle Mapを操作できる。

 

#Google News

自分にとってのトップ5のニュースをAIが認識して出してくれる。リアルタイムで全ての情報を見ることができたり（twitter, poltico, CNNなど）、タイムラインも見ることができる（昨日、一ヶ月前、半年前、、、）。全員が同じ信頼できる情報を見ることができるって、素敵。

 

#アンドロイドの携帯

２つの情報が表示されていて、イヤホンをつけると自動的に音声の予測に変わったり。googleで映画のタイトルを入れると、チケットが買える。hawaiiと入れれば、ハワイで撮った写真が出てくる。カスタマイズできる。2段階にスワイプすることで、一つの画面で全てができるように（全てのアプリも確認できる）。スワイプ画面で、文字の選択ができる。ローテーションボタンを押さないと、横画面にならないようになる。ダッシュボードで何時間アプリを使っているかとか、メールとかテレビとかグラフ化することができる。寝る時間のときは、白黒になって目に優しくなる。
 

#Google Map
220カ国に対応してるって、すげえ。どのお店が自分にとって良いか、Rateだけではわからない。でも、個人によってmatchしているかわかる（本当かな？笑）興味あるお店を何個かお気に入りして、友達にシェアして、投票したり。現在地で方向を出せてもよくわからないけど、現在地をマップで表示しつつ、同じ画面でストリートマップに案内付きで見れる機能が融合（この辺りで鳥肌がたった）。アシスタントで、ストリートビューに狐とかも出せるっぽい。
 
#Googleレンズ
ビジュアルポジショニングしてくれる。レンズが文字を認識してくれて、例えばレストランの文字も認識して、その料理の写真を見せてくれる！レンズが商品を認識してくれ、コーディネートもしてくれ、その場で買える。ポスターをレンズに通したら、そのトレーラーのYouTubeが流れる。
 
#自動運転
WAYMOでの自動運転は、SFではなく、現実。どの業界の車も、警察も、みんな自動運転に。たとえ青信号でも、常に気をつけてくれている。雪の中でも、しっかりと全てのオブジェクトを確認できている。
第2話 フィボナッチ数列

この記事は[仮面ライダービルドの数式](https://qiita.com/izmktr/items/e26a624e79bce3edccc9)の第2話です。

```math
\begin{align}
F_{-n}&=(-1)^{n+1} F_{n}\\
F_{-3}&=2
\end{align}
```
この式はフィボナッチ数に関する式になります。フィボナッチ数は次の式で表される数式となります。

```math
F_{n+2}=F_{n}+F_{n+1}
```

最初の方だけ値を見てみます。

|$n$|1|2|3|4|5|6|7|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|$F_n$|1|1|2|3|5|8|13|
このように、前の2つの数を足していくのがフィボナッチ数です。
冒頭の式は「負のフィボナッチ数」に関する式です。例えば、F0を計算してみましょう。

```math
\begin{align}
F_{2}&=F_{0}+F_{1}&\\
F_{0}&=F_{1}-F_{2}&\\
&=1-1&=0
\end{align}
```
このように、フィボナッチ数は負の方向にも定義することができます。

|$n$|-6|-5|-4|-3|-2|-1|0|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|$F_n$|-8|5|-3|2|-1|1|0|

正の表と比較すると、絶対値が同じで符号が交互に入れ替わることがわかります。まとめると次の式になります。
nが奇数なら　$F_{-n}=F_n$
nが偶数なら　$F_{-n}=-F_n$
これを一つの式で表したものが冒頭の式です。
rubyで例外が発生したらslackに投稿するだけのgemを作った

# raise_to_slack

https://rubygems.org/gems/raise_to_slack
https://github.com/skuroki/raise_to_slack

ちょっとしたbotとかを作って動かす時に例えばsentryとかに登録したりとかするのが大げさで面倒に感じる事があるので、slackさえ使えれば例外が起きたことを通知として受け取れるといいんじゃないか、と思って作りました。

## セールスポイント

* 準備が楽
    * …にしたつもりだったけど、slackのBot User OAuth Access Tokenを取得するまでは結局慣れてないと大変ではある気がする
    * ↑ができれば、環境変数2つ設定して、処理をブロックに包んで`RaiseToSlack.run`に渡すだけ
* 読むのが楽
    * 1ファイル40行くらい（0.1.0時点）読めば全部わかる
* 他のgemに依存していない
    * APIアクセスはnet/http, uri, jsonで頑張った
Objective-CからSwiftへの書き換え作業、型、ポインタ、配列Array、辞書Dictionary

よく使うものだけをピックアップしました。
C言語の単純型とSwiftの型の相関関係

|C言語の単純型  |Swiftの型  |
|---|---|
|Bool  |Bool  |
|short|int16|
|int  |int32|
|long|Int|
|long long  |Int64  |
|float  |Float  |
|double  |Double  |

Objective-Cのポインタ型とSwiftの型


|種類  |C言語の型  |Swiftの型  |
|---|---|---|
|ポインタ  |const T *  |UnsafePointer<T>  |
|  |T *  |UnsafeMutablePointer<T>  |
|  |const void *  |UnsafeRawPointer  |
||void *|UnsafeMutableRawPointer|
|クラスCのインスタンス  |C * const *  |UnsafePointer<C>  |
|  |C * __strong  |UnsafeMutablePointer<C>  |
|  |C **  |AutoreleasingUnsafeMutablePointer<C>  |
|関数|T (*func)(U)|@convention(c)(U) -> T|
|  |T (*func)(void)  |@convention(c)() -> T  |
|ブロック  |T (^block)(U)  |@convention(block)(U) -> T |


Array から NSArray への変換方法

```swift

let intList:[Int] = [1,2,3,4]
let cArray = intList as NSArray
```

NSArray から Array への変換方法

```swift

let ns1: NSArray = [100, "sample", 200]
let ns2: NSArray = [10, 20, 30]

if let ar1 = ns1 as? [Any] {
    print(type(of: ar1))
}

if let ar2 = ns2 as? [Int] {
    print(type(of: ar2))
}

```

配列arrayから文字列だけを取り出したい場合の便利な方法

```swift

let strList = array.filter{ $0 is String }
```

Swift のDictionaryはそのままNSDictionaryに変換可能。
NSDictionaryが
複数の型のキーを含まなければならない場合は AnyHashable型のキー
値が複数の型の場合は Any型の値
をもつ辞書を作れば変換可能


```swift

let d:[AnyHashable: Any] = [AnyHashable(0): "Zero",
                            AnyHashable("II"): 2]
let nsDic = d as NSDictionary
```

詳細は「詳解Swift」を参考にして書きました
Docker Jenkinsでssh-slaveを使う(Kitematic)

Kitematicでネットワークの設定ができるようになっていたので、Docker上にJenkins＋ssh-slave(ノード、エージェント)環境を構築してみた。
もっとも、非Docker環境での構築を行ったことはないので非Docker環境以外で通用する内容もあるかも。

#環境について
Docker 17.12.0-ce-win47
Kitematic 0.17.2

#使用したDockerのイメージ
jenkins
https://hub.docker.com/_/jenkins/
jenkinsci/ssh-slave
https://hub.docker.com/r/jenkinsci/ssh-slave/

#手順
## Jenkinsコンテナの設定
Kitematicの「＋NEW」からjenkinsを選択し「create」
Setting - Networkタブで「bridge」をチェックしておく。
networkは「bridge」以外のものを作成して使ってもOK。docker networkコマンドで作成できるはず。


#Jenkinsの起動、初期設定
（割愛）

##sshのキーペアの作成
Jenkinsコンテナのコンソールを開き、キーペアを作成する。

```
$ ssh-keygen  -t rsa -b 4096

Generating public/private rsa key pair.
Enter file in which to save the key (/var/jenkins_home/.ssh/id_rsa):[Enter or 任意のパス]
Enter passphrase (empty for no passphrase):[秘密鍵のパスワード]
Enter same passphrase again:[秘密鍵のパスワード]
Your identification has been saved in /var/jenkins_home/.ssh/id_rsa.
Your public key has been saved in /var/jenkins_home/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:XXXXXXXXXXXXXXXXXXXXXXXX jenkins@XXXXXXXXXXXX
The key's randomart image is:
```

/var/jenkins_home/.ssh/id_rsa.pub
の内容を控えておく。

#ssh‐slaveコンテナの設定
Kitematicの「＋NEW」からjenkinsを選択し「create」
Setting - Networkタブで「bridge」をチェックしておく
Setting - GeneralタブでEnvironment Variablesに追加。[^1]
JENKINS_SLAVE_SSH_PUBKEY=（控えておいたid_rsa.pubの内容）

[^1]: https://hub.docker.com/r/jenkinsci/ssh-slave/ のHow to use this image with Docker Plugin参照
laravelプロジェクトを作成しGAEに展開する

以下サイトに沿ってやっています。
[公式Installation](https://laravel.com/docs/5.6/installation#installation)
[Run Laravel on Google App Engine Flexible Environment](https://cloud.google.com/community/tutorials/run-laravel-on-appengine-flexible)

### 前提  
- php 7.1.3以上  
phpbrewなどを利用する。
- composerがインストール済み  
ライブラリ依存を整理するツール。欲しいライブラリAを取ってきたらさらにライブラリBが必要で... みたいな煩雑さを任せられる。
- gcpのプロジェクトを持っていて、gcloudコマンドとか使える。

### laravelプロジェクトを作成する（方法１）  

- laravelコマンドのインストール  

```
composer global require "laravel/installer"
```

- パスを通す  
.bashrcやconfig.fishに以下を追記  

```
# bash
export PATH=$PATH:~/.composer/vendor/bin/
# fish
set -x PATH ~/.composer/vendor/bin/ $PATH
```

- laravelプロジェクト作成  

```
laravel new blog
```

### laravelプロジェクトを作成する（方法２）

```
composer create-project --prefer-dist laravel/laravel blog
```

### local環境を構築してブラウザにアクセスしてみる

```
cd blog
composer install
# composerでlaravelプロジェクトをインストールしていない場合はここで(php artisan key:generate)
cp -p .env.example .env
php artisan serve
```
http://localhost:8000
にアクセスし、Laravelページが表示されれば成功。

### GAEに展開する

1. app.yamlファイルを作成。  
以下をapp.yamlとしてlaravelプロジェクトのルートディレクトリに置く。ここではblog以下。

```
runtime: php
env: flex

runtime_config:
  document_root: public

# Ensure we skip ".env", which is only for local development
skip_files:
  - .env

env_variables:
  # Put production environment variables here.
  APP_LOG: errorlog
  APP_KEY: YOUR_APP_KEY
  STORAGE_DIR: /tmp
```

2. YOUR_APP_KEYの置き換え  

```
php artisan key:generate --show
```
で取得できるキーをapp.yamlのYOUR_APP_KEYと置き換える。

3. composer.jsonに追記する  
blog以下のcomposer.jsonのscriptsに以下を追記。

```
"post-install-cmd": [
    "chmod -R 755 bootstrap\/cache",
    "php artisan cache:clear"
]
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/149698/934925b5-3b4c-0ec7-4f64-e47c3f139d7f.png)

4. 展開してアクセス

```
gcloud app deploy
```
展開が完了すると、
http://YOUR_PROJECT_ID.appspot.com
みたいなurlが表示されると思うのでアクセスし、laravelページが表示されていれば成功。
C言語の知識に囚われたC#コードを改善する 第ニ弾

# 関連記事一覧

[第一弾](https://qiita.com/gaya_K/items/7b10e7ce0404351f21f8)
第二弾（本記事）

# 直したいポイント
## 配列の呪縛 その3

こんなふうに配列を使っている場合もありました。

```cs
string[] keys = new string[]
{
  "zero",
  "one",
  "two",
};
int[] values = new int[] { 0, 1, 2 };

public int Hoge(string key)
{
  var index = keys.IndexOf(key); // for を駆使する場合もある。
  // エラー判定は省略
  return values[index];
}
```

上のコードをクラス or 構造体を使った場合はこうなります。

```cs
class KeyValue
{
   public string Key { get; set; }
   public int Value { get; set; }
}

KeyValue[] KeyValueArray = new KeyValue[]
{
    new KeyValue { Key = "zero", Value = 0 },
    new KeyValue { Key = "one",  Value = 1 },
    new KeyValue { Key = "two",  Value = 2 },
}

public int Hoge(string key)
{
    foreach (var item in KeyValueArray)
    {
        if (item.Key == key)
        {
            return item.Value;
        }
    }
    // エラー処理は省略
}
```

上記二つのコードは関連のある keys 配列と values 配列を変換や検索に用いる方法です。

前者は keys と values の同じインデックスの値が結びついているのは **単なる暗黙の了解** にすぎず、修正時にインデックスがズレて意図しない結果になる場合もがあります。

後者は結びつきが強化されましたが、以下の点に注意が必要です。

- Key の値に重複があった場合を考慮する必要がある。
- 検索結果が配列の末尾付近にあるほど処理の実行が遅くなる。

しかし、実はこういった機能は **標準で用意されているのです！**

```csharp
Dictionary<string, int> dict = new Dictionary<string, int>
{
  ["zero"] = 0,
  ["one"]  = 1,
  ["two"]  = 2,
};

public int Hoge(string key)
{
  // dict[key] もできるが、値がない時は例外になる。
  if (dict.TryGetValue(key, out var value))
  {
    return value;
  }
  // エラー時の処理は省略
}
```

key と value の関連が明確になり、判定処理も簡単になりました。
そして、Dictionary はハッシュ値を使って要素を検索するため、 **要素数が多くなっても高速** です。

ちなみに Dictionary を foreach にかけると、 KeyValuePair\<TKey, TValue\> という要素が帰ります。

```csharp
var dict = new Dictionary<string, int>();
foreach (KeyValuePair<string, int> kvp in dict)
{
    // 何か処理
}
```

<br/>
<br/>
---
他にも項目を挙げようとしましたが、間違って投稿してしまったため、第三段に先送りします。
owncloudとかgitbucketとか動かしているサーバでcertbot

# certbot について

certbot の使い方は，こちらがとても良くまとまっている．
私も参考にさせていただいた．

[Let's encrypt運用のベストプラクティス \- Qiita](https://qiita.com/tkykmw/items/9b6ba55bb2a6a5d90963)

# 課題

ただし私の場合は，上の記事では省略されている以下の場合に該当するサーバが私の場合は多かったので，メモっておく．

> certbot自体をWebサーバとして機能させる、standaloneプラグインもありますが、利用するケースは限られるはずです。動作確認でも、実際の運用でも、webrootプラグインを使うほうが簡単でしょう。

例えば，表題の owncloud とか gitbucket とか，document root にテキトーにファイルを置いても持っていってくれない認証つきサービスなどを動作させている場合は，webrootプラグインで動かせないんで，頑張らないといけない．

私の運用しているサーバの場合，過半数がこっちだったりして．

# 手順

## 初回

初回の取得は，大人しく手で止めて取得する．
また，私の常用する debian (old stable) では，certbot が古いんで [certbot/certbot](https://github.com/certbot/certbot) をcloneしている．

さらに，変数 EMAIL にはドメインマスターのメールアドレスを，DOMAIN には FQDN を指定してあるものとする．
ちなみに -m オプションによるメールアドレスの指定はなくても良いかも．

```sh
git clone https://github.com/certbot/certbot.git
sudo service nginx stop
sudo certbot/certbot-auto -m $EMAIL --agree-tos --standalone -d $DOMAIN
```

設定は上の記事と同じだけど，一応再掲しておくと

```conf
    ssl_certificate /etc/letsencrypt/live/DOMAIN/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/DOMAIN/privkey.pem;
```

忘れないよう，サーバを上げておく．

```sh
sudo service nginx start
```

## 2回目以降

実はすげー簡単なんだけど，webrootプラグインの場合と違って事前に --pre-hook で80番と443番のポートを見ているプロセスを停止しておかないといけない点だけ注意．
当たり前だけど．

で，nginxの場合はこんな感じ．

```sh:letsencrypt-update.sh
#!/bin/sh
  
certbot/certbot-auto renew -q --pre-hook 'service nginx stop' --post-hook 'service nginx start'
```

こいつをroot権限でcrontabでdailyくらいで実行するように指定しておけば良い．
すぐに実行しても不都合はあんましないので，試しに手でも実行しておいた方が良い．
例えばパーミッションに実行権限つけ忘れてたりとかに気付けるから．
AWS Certified Security - Specialty受験記

2018年4月23日に、新規のAWS認定試験としてAWS Certified Security - Specialtyが追加されました。
2018年4月29日に受験して取得できましたので、受けてみてわかったことを記録します。

概要・サンプル問題等は以下が参考になるかと思います。
https://dev.classmethod.jp/cloud/aws/scs-spring-2018-sample-questions/

# 受験してわかったこと
## 受験料が値上げした
公式サイトを確認すると受験料は$300となっています。
https://aws.amazon.com/jp/certification/certified-security-specialty/

他の試験を受験した際は同様の表記でも税込み32400円でしたが、
実際に申し込むと、34992円（受験料：32400円、消費税：2592円）請求されました。

## 合格ラインの設定が変更になった
これまでのAWS認定試験は、合格ラインを公表しておらず、「65%程度とれば受かる」という都市伝説がありました。

AWS Certified Security - Specialty合格後、認定のポータルサイトから以下のようなスコアレポートがダウンロードできます。

以下2点が明確に記載されています。
- 正答率のパーセンテージではなく、スコアを100〜1000で換算する
- スコアが750を超えれば合格

![scs.png](https://qiita-image-store.s3.amazonaws.com/0/99748/d15b835b-31a1-99e4-b3f3-eb0c1cde14ba.png)

## 銀座の受験会場はトイレに行けた
最近、PSIの試験会場として銀座の歌舞伎座の会場が追加され、初めて本会場を利用しました。
https://cbt-s.com/kabukiza-tc/

170分の試験で一番の難関はトイレに行かずに解くことでしたが、本会場では途中でトイレに行くことが認められました。
トイレが近い人はオススメです。

# 最後に
試験問題については記述できませんが、公式の試験ガイドとサンプル問題は役に立ちました。
私は公式の試験ガイドで、どの出題分野がどのサービスと紐づくかを分解して対策範囲を絞りました。
短い期間しかありませんでしたが、概ね効果が出た気がします。
「ibtool exited with code 255」と「The "IBTool" task failed unexpectedly.」について


今回はかなり短いです。

Xamarinの為にVS for Macの更新及びXcodeの更新をしました。
Xcodeの更新まではよかったのですが、VS for MacでiOSビルドをした時にタイトルのエラーが出ました。

```
ibtool exited with code 255
The "IBTool" task failed unexpectedly.
```
何だろうと思って調べたら、英語しか出なかった為備忘録として残しておきます。

# 解決方法

1.更新したXcodeを起動。
2.「install component~」っていうダイアログが出ると思われるので、installする。
3.installし終わったら、Xcodeを閉じます。
4.再びVS for Macを起動し、ビルドする。

おそらくこの手順でエラーが解消されます。

#まとめ
どうやらXcodeのinstallがまだ終わってなかったのが原因のようでした。
今まで出てきた事がなかったエラーだった為、びっくりしましたが難しい問題ではなかったので良かったです。

引き続きXamarinが楽しめそうです。
iPhone上でデザインチェックできるツールが神がかっている

# その名も「Hyperion-iOS」
https://github.com/willowtreeapps/Hyperion-iOS

## できること

### View Inspector
テキストのサイズやカラー、フォントなどの状態をタップするだけで確認することができます
![image](https://camo.githubusercontent.com/ec23fbb49d169c85a5d881e35be0c16902c652bf/68747470733a2f2f6d656469612e67697068792e636f6d2f6d656469612f6c34456f4e4f494c72354f6676677973772f67697068792e676966)

### Measurements
タップした箇所のパーツの位置を確認することができます。

PSD上で確認していた作業がいらないレベルで使いやすいです！
![タイトル](https://d3sw39zdfkajdx.cloudfront.net/art_img/38af4885-cfd9-49ff-acf3-0583e38ea576png)

### Zoom
ピンチイン、ピンチアウトで拡大縮小が自由自在！

###  Slow Animations
アプリ内のすべてのアニメーションを通常の速度の75％、50％または25％にスローダウンして確認することができます！
![image3](https://camo.githubusercontent.com/5d18c81486e741052e51c384495b48ddecbfb8da/68747470733a2f2f6d656469612e67697068792e636f6d2f6d656469612f323646655a634e463944627138394d42692f67697068792e676966)

## 導入

### Pods
```rb:Podfile
use_frameworks!
pod "HyperioniOS/Core", :configurations => ['Debug']
#"Configurations => Debug" ensures it is only included in debug builds. Add any configurations you would like Hyperion to be included in.
pod 'HyperioniOS/AttributesInspector', :configurations => ['Debug'] # Optional plugin
pod 'HyperioniOS/Measurements', :configurations => ['Debug'] # Optional plugin
pod 'HyperioniOS/SlowAnimations', :configurations => ['Debug'] # Optional plugin
```

```
$ pod install
```
おしまい
特にコード側でやることはないです。

デバッグモードだけ動くようになっているので安心ですね。
RSpecでエラーが起きたあとの状態をテストするときの問題点と回避案

例外が起きたあとのテストに関してあまり情報がなく、事例もなかったので
広く皆様の意見を聞きたい意図も含めて記事に起こしました。

## TL;DR

エラー（正確にはStandardError）が発生する機能に関して、エラー発生後の状態をテストしたいがエラーが発生した時点でRSpecが止まってしまう。
そのため、例外の内容をチェックしないのであれば、rescueしたあとに本来やりたい作業を行うのが一番無難な回避策

## 実コードを交えてた問題点の解説

### テスト対象とするサンプルクラス

今回は以下のサンプルクラスに対してのrspecとして例を書いて行きます。

```ruby:テスト対象のサンプルクラス
class Calculate
  def initialize
    # わかりやすい初期値をいれる
    @result = -9999
  end

  # 10を引数で割る
  def ten_division(number)
    @result = 10 / number
    @result
  end

  def last_result
    @result
  end
end
```


### やりたいこと

`ten_division` の引数に0を指定した場合に `last_result`の戻り値 は初期値の `-9999` であることを確認したい。

### 発生する問題点

何も考えずにそのまま書くと以下のようなコード

```ruby:RSpecのテストコード例
context "0を指定した場合" do
  let(:obj) { Calculate.new }
  it "last_resultで-9999が戻ってくる" do
    obj.ten_division(0)
    expect(obj.last_result).to eq(-9999)
  end
end
```

ただこの場合、Exceptionがあがって途中でspecが止まってしまう。

```text:RSpec実行時のエラー例
  1) 0を指定した場合 last_resultで-9999が戻ってくる
     Failure/Error: @result = 10 / number
     
     ZeroDivisionError:
       divided by 0
```

このため後続の `expect(obj.last_result).to eq(-9999)` が実行されずにエラーでRSpecが終了してしまう


### 回避案

エラーが起きるアクションに関してrescueして、その後期待される要素の取得をして確認をする。

コードで表すと以下の通り

```ruby:rescueで拾う例
context "0を指定した場合" do
  let(:obj) { Calculate.new }
  it "last_resultで-9999が戻ってくる" do
    begin
      obj.ten_division(0)
    rescue
    end
    expect(obj.last_result).to eq(-9999)
  end
end
```

一応ワンライナーでも書ける


```ruby:rescueで拾う例(ワンライナー)
context "0を指定した場合" do
  let(:obj) { Calculate.new }
  it "last_resultで-9999が戻ってくる" do
    obj.ten_division(0) rescue
    expect(obj.last_result).to eq(-9999)
  end
end
```


## 各種関連リンク

### サンプルコード
[exception後の挙動を確かめるRSpec](https://gist.github.com/shinkufencer/2cdf26489792666b892c3407db6c6d17)
※ 本ページでは紹介していない、errorそのもののテストに関しても記載しています。

### 参考サイト
* [RSpec での例外処理について](https://gist.github.com/quanon/c147c28c5ff0b401579ec9e4e1706db0)
* [RSpecでexpectとraise\_errorを使ったときのエラー \- Qiita](https://qiita.com/shiro615/items/4db568f123b50413f89d)
* [Rubyで独自例外を定義するときはStandardErrorを継承する \- Hack Your Design\!](https://blog.toshimaru.net/ruby-standard-error/)

### 編集後記

一応この記事を書いた経緯的なものは以下に。
[Errorが起きた後の状態を調べるrspecの書き方が全然見当たらないので書いた \- コード日進月歩](http://shinkufencer.hateblo.jp/entry/2018/05/08/235500)
acts_as_followerを使ってフォロー/フォロワー機能を実装

#前説
フォロー、フォロワー機能を実装しました。
イメージとしてはデータベースのテーブル関係とはどうするんだろうとかと、ハードル高そうに感じていました。
しかしgemを用いると結構すぐに実装できました。

#実装
- 非同期でフォロー、フォロワー機能を実装

#コード
以下のgemを導入します。

```Gemfile
gem 'acts_as_follower'
```

```
  follow_users POST   /users/:id/follow(.:format)                  users#follow 
unfollow_users POST   /users/:id/unfollow(.:format)                users#unfollow
```
導入部に関しては[こちら](https://qiita.com/kurkuru/items/ad25569f64e74efdac56)を参考にして頂けた方がわかりやすいかと思います。

気になっていたデータベースとつなぐmodelの部分。


```ruby:model/follow.rb
class Follow < ActiveRecord::Base

  extend ActsAsFollower::FollowerLib
  extend ActsAsFollower::FollowScopes

  # NOTE: Follows belong to the "followable" interface, and also to followers
  belongs_to :followable, :polymorphic => true
  belongs_to :follower,   :polymorphic => true

  def block!
    self.update_attribute(:blocked, true)
  end

end
```

ここで知らないデータベース関連がでてきました。

```
polymorphic => true
```

followerとfollowableの二つの情報があるのに対し、用意されているテーブルは一つだけ。
つまり、フォローもフォロワーも親クラスから見た操作や情報がほとんど同じである為、一つのテーブルにまとめてしまおうというものらしい。
https://shirusu-ni-tarazu.hatenablog.jp/entry/2012/11/04/173742
↑参考記事

```ruby:model/user.rb
class User < ApplicationRecord
  acts_as_followable # フォロワー機能
  acts_as_follower   # フォロー機能
end

```

```ruby:cotroller/user_controller.rb
def follow
    @user = User.find(params[:id])
    #ログイン中のユーザーで対象のユーザー(@user)をフォローする
    current_user.follow(@user)
end

def unfollow
    @user = User.find(params[:id])
    #ログイン中のユーザーで対象のユーザー(@user)をフォロー解除する
    current_user.stop_following(@user)
end
```

```html:user/show.html.erb
<li id="user-<%= @user.id %>" class="collection-item">
    <%= render 'users/follow', user: @user %>
</li>
```

```html:user/_follow.html.erb
#任意のユーザーのマイページにて
#マイページのユーザーが現在ログインしているユーザーでない時->フォロー/フォロワーボタンを設置
<% if user.id != current_user.id %>
  <li class="collection-item">
    #現在のユーザーが対象のユーザーをフォローしてない時->「フォローするボタン」を設置
    <% unless current_user.following?(user) %>
      <div class="action">
         <%= link_to 'フォローする' ,follow_users_path,method: :post, class: "btn waves-effect waves-light" ,remote: true %>
      </div>
    #現在のユーザーが対象のユーザーをフォローしてる時->「フォロー解除ボタン」を設置
    <% else %>
      <div class="action">
         <%= link_to 'フォローを解除する' ,unfollow_users_path, method: :post,class: "btn waves-effect waves-light",remote: true %>
      </div>
    <% end %>
  </li>
<% end %>
```

```javascript:follow.js.erb
$("#user-<%= @user.id %>").html("<%= j(render partial: 'users/follow', locals: { user: @user }) %>")
```

```javascript:unfollow.js.erb
$("#user-<%= @user.id %>").html("<%= j(render partial: 'users/follow', locals: { user: @user }) %>")
```

#結果

<img width="485" alt="スクリーンショット 2018-05-08 23.32.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/253129/eda56f6b-b694-cf08-9919-476d4f1951ac.png">

フォローするでしょ

#終わりに
感じたこととしては[いいね機能](https://qiita.com/networkyohan69/items/40cf567880557148d8f4)の実装と近い感じがしました。

#今後の実装
- フォロワーの数を数えてランキングにもしたい
- フォローしているユーザーによるタイムラインの実装とか
今日からはじめる単体テストとリファクタリング

## 序文
僕の身の回りでは単体テストのコードが書かれていないコードベースをよく見かけます。そしてそのようなコードベースはリファクタリングを拒絶し、またリリースに大変な労力を要する巨大な怪物と成り果てていきます。

納期や面倒くささに圧され怪物が日々生み出されていますが、健全で継続的なソフトウェア開発にとって単体テストの自動化は非常に強力なツールです。

TDD(テスト駆動開発)に代表されるようにテストファーストという考え方は非常に多くの恩恵をもたらします。リファクタリングの信頼性を高め、ソフトウェアの発展を望む殊勝な開発者のための精神安定剤となり得ます。

テストコードのないプロジェクトは多くの場合、参加している開発者が「テストを書くべきだとは聞くけれど、テストコードを書いたことがない。書き方がわからない。そもそもよくわからない。」という霧中にいます。

しかし、その霧は実はメガネの曇りです。拭き取ればすぐに視界良好になるのだとわかります。テストコードは手の届くところにあるのだとわかります。

モダンな言語やフレームワークであればテストフレームワークは大抵の場合用意されています。自分が利用しているものについて調べてみてください。今回はPHPについて単体テストとリファクタリングについて見ていきます。

## テスト対象

まず、以下の要件を満たす関数を考えます。
文字列の後ろ3文字が`lish`で終わっているかどうかを判定できる。

例えば正規表現による文字列マッチを使って実装してみます。

```func.php
<?php
/*
 * 文字列が"lish"で終わっているかをチェックする。
 *
 * @param string str 対象の文字列
 * @return bool
 */
function is_end_with_lish($target_str) {
    return preg_match('/lish$/', $target_str) === 1;
}
```

## テストを書く

この関数に対するテストは、例えば簡単なものとして以下のものが思いつきます。

|#|テスト項目|入力値|結果|
|:--:|---|---|:--:|
|1|lishで終わる|english|true|
|2|lishで終わらない|good|false|
|3|4文字以下|ish|false|
|4|大文字のLISHで終わる|SINGLISH|false|
|5|マルチバイト文字|ｅｎｇｌｉｓｈ|false|
|6|空文字|''|false|
|7|null|null|false|

まずは#1のテストに対応するテストコードを書いてみます。

```test.php
<?php

include("./func.php");

// #1
echo (is_end_with_lish("english")) ? "success." : "failed.";
```

これだけでテストは自動化されました。
このコードをターミナルで実行すると即座にテストを実行できます。

他のテストも追加します。

```test.php
<?php

include("./func.php");

// #1
echo (is_end_with_lish("english")) ? "success." : "failed.";

// #2
echo (!is_end_with_lish("good")) ? "success." : "failed.";

// #3
echo (!is_end_with_lish("ish")) ? "success." : "failed.";

// #4
echo (!is_end_with_lish("SINGLISH")) ? "success." : "failed.";

// #5
echo (!is_end_with_lish("ｅｎｇｌｉｓｈ")) ? "success." : "failed.";

// #6
echo (!is_end_with_lish("")) ? "success." : "failed.";

// #7
echo (!is_end_with_lish(null)) ? "success." : "failed.";
```

これを実行します。

```
php test.php
```

`success.`が7つ並んだ結果が得られるかと思います。

## リファクタリングをする

ここでふと気づきます。今回のケースでは正規表現よりも文字列の切り出し(`substr`等)のほうが実行効率がいいのではないだろうか。
割愛しますが実際に調べてみるとsubstrを利用した実装の方が処理速度が1.5倍ほど早いです。

`is_end_with_lish`関数を変更してみます。リファクタリングを行うわけです。

```func.php
<?php
/*
 * 文字列が"lish"で終わっているかをチェックする。
 *
 * @param string str 対象の文字列
 * @return bool
 */
function is_end_with_lish($target_str) {
    return substr($target_str, -4) === "lish";
}
```

変更した状態で再度テストを実行してみます。
すると先ほどと同様にすべて`success.`となるかと思います。

このことから、リファクタリング後にも単体テストがカバーしている範囲に限りですが
挙動に変更がないことがわかります。

このようにテストを書くことは仕様を考えることを強制し、またリファクタリングを自信をもって行うための強力なツールになりえます。

## 帰結

フレームワークを使わなくてはいけないということではありませんが、PHPではPHPUnitやPHPSpecなどの強力なテストフレームワークが存在します。他の言語もほとんどの場合フレームワークが存在しています。これらを利用するのがベターでしょう。
しかし敷居が高いと感じるのならば、自分でまずは書いてみるのも一つの手です。

とにかくここで伝えたかったのはテストを書くのは特殊な技能を要するものでもなんでもなく、誰もが今日から始められるということです。
（必ずinjectを使う制約のもとで）Rubyで配列からハッシュへ変換する

# 【前置き】
某所で勉強させて頂いた為、結果のアウトプットをば。届けこの思い！
IDE無しでテキストにちょちょっと書くだけだとちょっとした事でも時間かかっちゃいますよね？はい

# 【本題】
配列の値は決まってて、**関数のinjectを使いつつハッシュをリターンせよ** って命題。
別言語からRubyに触って理解してたけどじゃあ実際にブロック使いましょうとなった時に結構困ったりする、
実際困った、慣れない端末、慣れない言語どうしようどうしましょう。
詳しい値はさておきじゃあガチでするにはどうしましょうかってのを覚え書き。

さくっと試したかったので環境はAWSで、結論から述べる。
https://github.com/lunalice/RubyChallenge/tree/master/ruby_book/lib

```ruby:arry_to_hash.rb
require "minitest/autorun"

def tohash(array)
    array.each_slice(2).inject({}) {|hash, (key, value)| hash[key]=value;hash}
end

class ArrayToHashTest < Minitest::Test
    def test_array_to_hash
        assert_equal ({:a=>1, :b=>4}), tohash([:a,1,:b,4])
    end
end
```

メインはclass ArrayToHashTestでハッシュと関数呼び出し結果を比較している。
初期目がちかちかしてわかり辛かったが関数に渡しているのは配列である。（ハッシュじゃないよー

tohashで配列をarrayで受け取り、
each_slice(2)で配列を2個づつブロック化します。
inject({})はブロック内で前回の処理結果を引き継いで渡すというもの、
()内は初期化なので以下になる。

1回目　{}と　　　　　：a,1
2回目　{:a=>1}と　　:b,4
etc

Rubyは最後に出力した結果を返すという特性の為、return文を書かなくてもよい。
その為、hash[key]=value;hash}を見た時にRuby知識0だとhashで何やってんの？ってなる。実際にはハッシュに値を詰めて次のループに送っているだけ、後は配列増やしたいだけ増やせばいい感じ。試してないけど奇数の場合でも相方がnilになるんじゃないかなぁ、なって欲しい所。あと思い出しながら手打ちしたけどassert_equalのハッシュの指定で()を付けてなくておかしな解釈されてて若干焦りました。エラーログみつつそういやハッシュは何か括らないといけないんだよなぁと知識だけあったので試して解決。ちなみにinject指定がなければ関数呼び出しでなくHash[*配列]で一発で終わりそう。

# 【最後に】
見ておられないと思いますが、某所の方に届けばいいなぁ。
何かとかゆい所に手が届かない感じの回答ばかりしていた為、凄いもやもやしたのでこれでスッキリ。調べる事と時間があれば何とかなりそうな内容だったので尚更・・・

明日ちょっと私用でscala書いたのでgitcommitするつもり。
JAVA有料化で一個人として書く事はなくなるのかなぁと感じていて、有償化って事はnotオープン系になるのかしら。javascriptが熱かったりscalaだったりpythonだったり・・・やっぱりWEB系の移り変わりの激しさは目を見張るものがある。しかも言語独自のフレームワークも合わさり最強に見える。ひろーくひろーく行かないとですね。

scalaがJVMで動作するのも相まって有料化の煽り食らいそうな気がしなくもない。外国でお勧めなのがpythonかjavascriptらしい。もともとフロントエンド専用機だったjavascriptがライブラリーやフレームワークでどこにでも出没し、手軽に始める事が出来て個人的に結構注目してます。
AWSも無料期間あるしでサーバー立ててそこでhtml+cssとか慣れておこう。