OmniAICreator/Qiita-1.07M huggingface dataset:
SORACOM Airのメタデータでautossh

この記事は、[IoTLT Advent Calendar 2016](http://qiita.com/advent-calendar/2016/iotlt) の11日目の記事です。
※1日遅れの投稿になってしまってすみません…。

突然ですがみなさん、設置したIoTデバイスのメンテナンスにお困りではありませんか？
Linux搭載でSSHできればあとから何とでもなるので安心ですが、
都合良くグローバルIPを割り当てられないケースも多々あると思います。

今回、お仕事でOpenBlocks IoT+SORACOM Airを遠隔地に設置してメンテナンスが必要な案件に関わったので、
その際につくった簡単なシェルスクリプトをご紹介します。

# soracom_autossh

[GitHub](https://github.com/tomoya0x00/soracom_autossh)で公開しています。

クラスメソッド様の[Soracom Airで繋がったデバイスにリモートからSSHする](http://dev.classmethod.jp/etc/remote-port-forward-with-soracom-and-autossh/)を参考に、
記事の最後で言及されている「Soracom Air のユーザーデータでリモートサーバ情報を連携」を（データ構造は違いますが）実現しています。

使用方法は[README](https://github.com/tomoya0x00/soracom_autossh/blob/master/README.md)をご参照下さい。

## やっていること

SORACOM Airのメタデータサービスでは、SIMの情報(Subscriber情報)とユーザデータ(任意の文字列を設定できる)が取得できます。
soracom_autosshでは、ユーザデータで「どのSIMが」「どのサーバに」「どの秘密鍵」でSSHポートフォワードするかという情報を持たせておきます。

ユーザデータのデータ構造は下記の通りです。
{SSHでログインしたいLinuxデバイスのSORACOM Air IMSI}は、imsis配下に複数指定可能です。

```json
{
  "ssh":{
    "imsis":{
      "{SSHでログインしたいLinuxデバイスのSORACOM Air IMSI}":{
        "portForwardParam":"{任意のポート番号}:localhost:22 {リモートサーバのユーザー名}@{リモートサーバのグローバルIPアドレス}",
        "privateKey":"{リモートサーバのSSH秘密鍵}"
      }
    }
  }
}
```

まず、SIMの情報を取得してユーザデータと照らし合わせ、
自分が接続すべきSSH情報がユーザデータにあるかどうか調べます。

```bash:soracom_autossh.sh
# 自分のIMSIと該当するSSH情報を取得
IMSI=`curl -s http://metadata.soracom.io/v1/subscriber | jq .imsi`
if [ $? -ne 0 ]; then
  echo "failed to get own imsi"
  exit 1
fi

SSH_INFO=`curl -s http://metadata.soracom.io/v1/userdata | jq -r .ssh.imsis[${IMSI}]`
if [ $? -ne 0 ]; then
  echo "failed to get userdata"
  exit 1
fi
```

自分が接続すべきSSH情報が存在し、かつ前回取得した内容と異なる場合のみ、
秘密鍵をユーザデータからファイルに書き出し、autosshを起動します。

```bash:soracom_autossh.sh
if [ "$SSH_INFO" != "null" ]; then
  # 自分のSSH情報があれば、前回取得したSSH情報との差分チェック
  if diff -q $SSH_INFO_FILE $SSH_INFO_FILE_OLD > /dev/null 2>&1; then
    # do nothing
    echo "do nothing" 
  else
    # 前回取得したSSH情報との差分があれば、秘密鍵を書き出してautossh開始

    # autosshが起動済みなら終了
    exit_autossh
    delete_privatekey
    
    echo $SSH_INFO | jq -r .privateKey > $SSH_PRIVATEKEY_FILE
    chmod 600 $SSH_PRIVATEKEY_FILE
    AUTOSSH_PIDFILE=$AUTOSSH_PIDFILE \
                   autossh -M 0 -o StrictHostKeyChecking=no \
                   -o UserKnownHostsFile=/dev/null \
                   -o ServerAliveInterval=60 \
                   -o ServerAliveCountMax=3 \
                   -o ExitOnForwardFailure=yes \
                   -i $SSH_PRIVATEKEY_FILE \
                   -N \
                   -f \
                   -R `echo $SSH_INFO | jq -r .portForwardParam` &
    echo "started autossh"
  fi
else
  # 自分のSSH情報が無い場合、autosshが起動済みなら終了
  exit_autossh
  delete_privatekey
fi
```

soracom_autossh.shはcronなどでの定期実行を想定しており、
もし自分が接続すべきSSH情報が無い場合、起動したautosshを終了するようになっています。

## 実際の運用例

あらかじめsoracom_autossh.shをcronで5分間隔起動するようにしておき、通常時はユーザデータを空にします。
メンテナンスの必要性があるときだけSSHポートフォワード先となるAWS EC2のインスタンスを立ち上げ、
ユーザデータにメンテナンスしたいIoTデバイスとSSH情報を書いておき、IoTデバイスがSSHポートフォワードしてくるのを待ちます。

# 最後に

これでいつでもSSHできるので、何かあったときでも安心ですね。（トラブル起きないのが一番ですが…）
try-with-resources 構文に catch(Exception e) とか catch(IOException e) は必須じゃない

`close()`呼び出しを保証するtry-with-resources構文
--
Java6以前では以下のようにtry-finallyを使って書いていたclose()処理

```Java
Closeable r = null;
try {
  // リソースを確保
  r = getResource();
  // リソースを使用
  r.use();
} finally {
  if (r != null) r.close();
}
```

ですが、Java7からは以下のような書き方で大変スマートになっています。

```Java
// リソースを確保
try (Closeable r = getResource()) {
  // リソースを使用
  r.use();
}
```

ご存じ、try-with-resources構文です。

`Closeable.close()`は`IOException`を投げる
--
さて上記のコード片ですが、実際のプログラミングをしてみるとある重要な点が省略されていることに気付きます。そう、`IOException`が投げ出されるのを処理していないのです。特にtry-with-resources構文を使った後者のコード、`getResource()`も`use()`も`IOException`を投げないとしても全体としては`IOException`を投げます。なぜなら、糖衣構文で見えていないけれども`close()`呼び出しがあるから。`close()`が`IOException`を投げるのでそれを処理する必要があるのです。

つまり後者は実際には、

```Java
// リソースを確保
try (Closeable r = getResource()) {
  // リソースを使用
  r.use();
} catch (IOException e) {
  // 適切な処理
}
```

という形でなくてはいけないのです。もしくは`throws IOException`を付けてさらに上位へ投げるか。どちらにしろ、もともとの触れ込みから期待していたよりも若干ノイズの多いコードになります。
と、ここまではtry-with-resources構文を一度でも使ったことのある方ならすでにお気付きのことかと思います。

`IOException`を投げない`close()`を書いたっていい
--
さてここからが本題。
`catch`も`throws`も使うことなく、次のような単純なコードを成立させることもできるんですよというお話。

```Java
// リソースを確保
try (MyResource r = getResource()) {
  // リソースを使用
  r.use();
}
```

`close()`が必ず成功するような`Closeable`/`AutoCloseable`クラスというのはありえるわけです。で、そういうクラスを自作する際に`Closeable`を実装しつつ

```Java
public class MyResource implements Closeable {
  public void close() {
    // 必ず成功するクローズ処理
  }
}
```

と、`throws IOException`なしの`close()`を書くわけです。`throws IOException`なしでもインターフェース実装は成立しています。そして、このクラスをリソースとするならば

```Java
// リソースを確保
try (MyResource r = getResource()) {
  // リソースを使用
  r.use();
}
```

は検査例外を吐かないものとなります。

気が付いてみれば当たり前のことなのですが、IDEを使っていると最初から`throws IOException`が自動的に記述されてしまうため、不要なのに付けっぱなしになり結果として不要な`catch`を強要されてしまうこと、まれによくありそうなので注意喚起まで。
IE11でsvgを含むページを印刷するとクラッシュする件の対応

IE11でsvgを含むページを印刷しようとするとクラッシュ**することが**あります。
※IEでsvgがクラッシュする条件は多々あります。

改ページ付近でsvgでスプライトしていたりすると、あるページでは大丈夫なのにあるページではクラッシュする
（```mshtml.dll``` でエラーコード ``` 0xc0000005 ``` （アクセスバイオレーション）で落ちている）

ぐぐると

```scss
@media print{
  svg {
    display: none !important
  }
}
```

なんてカッコイイ解決かIEのバグだね、という情報くらいしか出てこないですが

```scss
svg {
  overflow: hidden;
}
```

としてあげると直るかもしれません。

## 発生条件と推察

自分が確認した限りは下記の現象が起こりました。

+ 同じSVGを使用していてもクラッシュしないページがある
+ A4印刷でクラッシュしていても、A3印刷だったらクラッシュしないことがある
+ SVGのコンテンツをブロック上部に持っていけばクラッシュしないことがある
+ SVGより上部にいるDOMを削除するとクラッシュしないことがある
+ SVG要素自体を非表示にするとクラッシュしない
+ コンテンツが長いページは発生率が高いが、長いページでもクラッシュしないページはある
+ クラッシュレポートをWindowsのイベントビューアーで確認すると```mshtml.dll``` でエラーコード ``` 0xc0000005 ```が発生している

```svg``` は ```use```で読み込んでおりスプライトで特定のアイコンだけを出すという利用方法です。（``` use xlink:href='foo#icon1' ``` という指定）

発生条件から

1. useで読み込んでいるのでsvgの読込分のメモリの確保が足りておらず違反？
2. ページをまたぐようなsvgが存在する時に、超過して書込む等の違反？

と思い適当にデバッグしてたら

+ ``` page-break-before:always ```等のcssを当てると大丈夫だった所もクラッシュする

現象が確認できたことから改ページ周りが非常に怪しいと思い適当にcssいじってたら回避策見つかりました。
100円ロボット部　テレプレゼンスロボット（テレイグジスタンスロボット）

# 100円ロボット部とは
ロボットを作るのに10万円から100万円かかる、そんな常識をぶち壊した100円グッズでロボットを作る部活です！
中国では2元店、ヨーロッパでは1ユーロショップ、アメリカでは１ドルショップがあるので、世界中のどこでも低価格でロボットが作れる世界を目指します。
http://100robo.net/

# テレプレゼンス（テレイグジスタンス）ロボットとは
遠く離れた場所からロボットを操作することで、そこに自分の存在感を提示する。それがテレプレゼンスロボットです。
日本語では、遠隔存在感や遠隔臨場感といい、遠隔での会議への参加や、病院から結婚式に参加したりといったような分野で導入が始まっています。

# 用意するもの
Studuino
電池ボックス(Studuino電力供給用)
乾電池
サーボモーター3つ（SG90が安くておすすめ※ただし壊れやすいので注意）
[「秋月電子　SG90」](http://akizukidenshi.com/catalog/g/gM-08761/)
[「ebey SG90」](http://www.ebay.com/sch/i.html?_from=R40&_trksid=p2050601.m570.l1313.TR0.TRC0.H0.XSG90.TRS0&_nkw=SG90&_sacat=0)
100円ショップで買った適当な材料

# 開発環境
Mac book
Windows

##Step.1
100円ショップにあるグッズで胴体、腕、顔を作ります。
今回は、100円ショップにあったMDFの木材(厚さ4mm)を使ってこのようなロボットを作ってみました。
![haco001.jpg](https://qiita-image-store.s3.amazonaws.com/0/145134/76bec4e5-c9f3-b144-5dda-ddb9df1a1327.jpeg)
中の構成はこのようになっております。
![haco002.jpg](https://qiita-image-store.s3.amazonaws.com/0/145134/6111a528-9acb-236f-0ca3-1c339410efd8.jpeg)
コーポレートサイトをS3+Lambdaに移行してコストカット

このエントリは [Classi Advent Calendar 2016](http://qiita.com/advent-calendar/2016/classi) の13日目です。

Classiでサーバサイドアプリケーションを担当している @kyottyy です。

今回は、弊社の[コーポレートサイト](https://classi.jp)をAWSに移行することで
ランニングコストを節約した話をします。

# 移行前
クラウドのIaaSサービス上にLinuxインスタンスを立てて、
一般的な構成のWebアプリケーションを構築していました。

この時のランニングコストが `数十万 / 月` です。

# 移行後
静的資産をS3のwebsite hosting + CloudFront経由で公開し、
動的処理（お問い合わせ部分）をLambdaで実現しています。

移行後のランニングコストは `数万 / 月` で、1/10以上のコスト削減を実現できました。

![Untitled.png](https://qiita-image-store.s3.amazonaws.com/0/79239/b10f39ac-5c87-4b14-06e7-732e384f0c96.png)

# Lambda
AWSのサービスを使うことで簡単にサーバレスアーキテクチャを採用できますが、
Lambda周りでいくつかポイントがあったので紹介します。

## functionの管理
今回はgolangで実装するため [apex](http://apex.run/) を採用しました。

結果としてデプロイやfunctionの管理が非常に楽になり、
複数人での開発もスムーズに行えました。

## パフォーマンス
個々のパフォーマンス計測が難しいため、ユーザから見える箇所を
2-tier（js -> S3）とし、体感速度を高速にしています。
（全体としても数sで処理が完走する）

性能検証は現在も課題であり、最適な方法を模索中です。

## Lambda on VPC
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/vpc.html

ドキュメントで注意されているように、ENI（=subnetで割り当て可能なIP数）が不足すると
CloudWatchにログが記録されず、音もなく失敗する可能性があります。

今回はLambdaの実行状況をDynamoDBに格納することで
エラー検知 + べき等性を担保しています。

# 最後に
[Classiではエンジニアを募集しています。](https://www.wantedly.com/companies/classi/projects)
日本の教育に興味のある方は是非お越しください！
HTTParty 0.14から、空配列の送り方が変わっている

## 概要
HTTParty 0.13.x => 0.14.0 に上げたときに、空配列のエンコード方法が変わっていて、それが原因で挙動が変わっていた。

## 詳細
`HTTParty.post(anUrl, body: { a: 1, b: []}`

でリクエストを送った時、まずデフォルトでContent-typeがapplication/x-www-url-formencodedになっていて、Bodyが次のようになっていた。

HTTParty 0.13.x: `a=1`
HTTParty 0.14.0: `a=1&b[]=`

次に受け取る側の解釈ですが、

`a=1`の場合、rackの層では`{ a: 1 }`というhashになり、例えばGrapeなどでbをArrayとみなすように設定していれば、`{ a: 1, b: [] }`に最終的に変換される。
`a=1&b[]=`の場合、rackの層では`{ a: 1, b: [nil] }`というhashになり、例えばGrapeでbをArrayと定義していたとしても、そのままになります。

## 該当issue
https://github.com/jnunemaker/httparty/issues/469
https://github.com/jnunemaker/httparty/pull/477

## とりあえず対策
HTTPartyのバージョンを0.13.xで固定する。

## 根本対策

軽くapplication/x-www-url-formencodedの仕様についても調べてみたんですが、どう解釈するのが正しいのか、どこのせいなのかよくわかりませんでした。

が、 `b[]=` という投げ方は `[nil]` に解釈されるのが普通なきがする。

POSTのときはapplication/jsonで送るのが良いという話もありますが、GETだとそうもいかないので。。
Windows7 をクリーンインストールしたら  WindowsUpdate が終わらなくなった


初回だから検索に時間かかってるんだろうと思ったけど、丸2日以上「更新プログラムを確認しています」が出たままなので、さすがにこれはないだろうと対応せざるを得なくなった。
検索してみると結構あるあるらしい。
仕方ないので色々試そうと思ったけど、ブラウザが初期バンドルの IE8 だったため、 Microsoft のサイトすら見れないという地獄。
IE9 とか IE11 にしようとしてもブラウザが対応してないだのリンク切れだの…。

## WindowsUpdateClient を最新にすればいいらしい

### 最新版は KB3161647
最新版は [KB3161647](https://support.microsoft.com/ja-jp/kb/3161647) に入っているらしいので、ページを見に行く。

### KB3161608 に含まれてるよ
という [リンク](http://support.microsoft.com/kb/3161608) が貼られているので、従う。

### KB3172605 に含まれてるよ
またかよどこのアンテナサイトだよと思いつつ、 [リンク](https://support.microsoft.com/ja-jp/kb/3172605) を追いかける。
ページをスクロールするとちょうど真ん中くらいに「パッケージのダウンロード」のリンクが現れる。
早速ダウンロードしてきてインストールしてみる。

### 対応していません
仏の顔も三度までっていうけど、キリスト教徒なんで切れてもいいですかね？右の頬を差し出せ？なんのことですかね。

仕方ないのでさっきのページをよく読んでみる。
ダウンロードの下あたりにこんな記述が。

> 必要条件
> この更新プログラムを適用するには、 Windows 7 または Windows Server 2008 R2 Service Pack 1および2015年 4 月のサービス スタックが Windows 7 および Windows Server 2008 R2 の更新をインストールしてください。

なるほど。

### KB976932 と KB3020369 が必要だよ
引用したあたりの文章がリンクになっていたので、そのまま踏みつけると、上の方は [KB976932](https://support.microsoft.com/ja-jp/kb/976932) に、下の方は [KB 3020369](https://support.microsoft.com/ja-jp/kb/3020369) に、それぞれ飛ばされる。

KB976932 は SP1 の案内で、またリンク巡りをさせられることになるけど、今回は最初から SP1 が適応されていたのでスキップ。

KB3020369 のページも少し下にスクロールすると「パッケージのダウンロード」のリンクが出てくる。

## 今度は手動アップデートが終わらない
先ほどダウンロードしたファイルをインストールして起動すると、更新のための情報を集め出すのだが、いつまでたっても終わらない。
理由を検索すると、 Windows がすでに起動させているアップデートクライアントが悪さをしているそうだ。

### クライアントを停止させる
手段はいくつかあるらしい。

1. コマンドラインから管理者権限で `net stop wuauserv` と発行
2. タスクマネージャから wuauserv を探してサービスの停止をする。
3. コンピュータの管理のサービスから　Windows Update を停止させる

2番目が無難ではなかろうか。

### 気を取り直してインストール
無事に KB3020369 がインストールでき、その後続けて KB3172605 のインストールに成功する。
そしてお待ちかねの WindowsUpdate を実行してみる…！

### そこには元気に走り回る WindowsUpdate ちゃんの姿が！
![WindowsUpdate.png](https://qiita-image-store.s3.amazonaws.com/0/71497/ea55beb9-d392-3dfa-32db-37200a3a880e.png "WindowsUpdate.png")

## 教訓
新しい OS 買お？

## 参考
[Windows7のWindows Updateが終わらない、遅い、進まない問題の解決方法](http://freesoft.tvbok.com/tips/windows_update/not_proceed_update.html)
[KB3161647](https://support.microsoft.com/ja-jp/kb/3161647)
jQueryのreplaceで特定の文字列を置換する方法

要素を指定してeachの中の関数でreplace()を使う
http://www.webantena.net/javascriptjquery/jquery-replace/
↓こっちのがわかりやすい
http://www.webopixel.net/javascript/195.html

複数の場合はこんな感じで.replace()をつなげる

```
<script src="./jquery.min.js"></script>
<script>
 $(document).ready(function(){
 $('.replace').each(function(){
    var txt = $(this).html();
    $(this).html(txt
    .replace(/A/g,'B')
    .replace(/C/g,'D')
    .replace(/E/g,'F')
   );
  });
 });
</script>
```
microsoft bot frameworkとLUISを初めて使っときにつまずいたポイントとか、わかりにくかったところ

# この記事で伝えたいこと
- わかりにくかったところと、どう対処したかを記述していきます。
- マニュアルなど、ちゃんと読んでればわかるけど、なんとなくササっと使ってみたい人向けです。
- これから使ってみる人の参考になれば幸いです。

# 構築時の内容
以下３つのサービスを使って、[AI Chatbot]を作成しました。

- 言語理解AIのAPI：　LUIS (https://azure.microsoft.com/ja-jp/services/cognitive-services/language-understanding-intelligent-service/)
- Botパッケージ：　Microsoft Bot Framework (https://dev.botframework.com/)
- Botの置き場所のaPaaS：　Azure Web Apps (https://azure.microsoft.com/ja-jp/services/app-service/web/)
- 実装言語: Node.js


構築の全体像。たぶん他の方がやっている構成とほとんど一緒だと思います。
![Infra.png](https://qiita-image-store.s3.amazonaws.com/0/67206/3467a18d-b256-3b67-1092-20c72bb01792.png)



# 「**LUIS**」でつまずいたポイント
- そもそもどういうものなの？
    - 学習させたLUIS Applicationにテキストを渡すと、JSONで言語認識結果を返すAPIを作ることができます。
- Intent,Entityに何入れるの？
    - なんとなくの意味として、Intentは意図、Entityは単語を表します。
    - ざっくりの理解だと、「＊＊＊ってなに？」「＊＊＊とはなんですか？」という文章を同じ意図ですよ、と認識するのがIntentで、「＊＊＊」というところがEntityになります。最初はそれをLUISさんへ一個ずつ入力して教育するような感じです。 
- Intentは何個まで入れられるの？
    - いまは最大20個です（2016.11時点）。これから増えるかもです。 調子に乗ってるとすぐに20個に達してしまうので、ここはグループ化の見積もりを最初にしておくと良いかもしれません。
- LUIS画面で最初は何したらいい？
    - [My application]を作成したら、まずはIntentの＋ボタン押してIntentNameと例文を入力して、から始めるとわかりやすいかと思います。
- 学習させた後は？
    - [Publish]というところでAPIを発行/更新することができます。教育させたのに、Botの反応が変わらないな～と思ったら、publishしてない、ってことがあったりしました。

# 「**bot framework**」でつまずいたポイント
- Configurationの設定
    - Message endpointはずれていると、反応がなくなるので注意です。結構躓きます。構築してみてBotの反応なかったらEndpointのパスを疑ってみてください。
 

# Azure Webapps
- git pushが出来れば、あとは普通に使えました
- Azure portalのブレードのメニューは結構変わったりするのと、英語から日本語への翻訳がわかりにくい表現になってたりするので、一回使ってみて理解するのがよいかと思います。マニュアル探すのも大変なので。

# 全般
結構、頻繁にUpdateがあるので、公式サイトはそれなりにチェックしておいたほうがよいかと。 自分がお試し利用中でも、突然日本語化対応されたりとか、BotFrameworkがWebappsと仲良くなったりとかしてました。

- 使ってみてよかったか？
    - Watson APIやGoogleAPIもありますが、BotFrameworkやWebappsが一社のサービスで構築できるので、作りやすさは感じました。性能に関しては、そこまで使い込んでないのでよくわかりません。
postfix でメール送信先を制限（固定）する

# 概要
開発環境等で特定の宛先にしかメールを送信したくない場合の設定メモ

# 設定内容


```
# vi /etc/postfix/main.cf

//以下を追加
canonical_maps = regexp:/etc/postfix/canonical.regexp
```


```
# vi /etc/postfix/canonical.regexp

#全てのメール
/^.+$/ xxx@example.com

#特定ドメインを除外
!/.+\@(hogehoge\.co\.jp|.*\.hogehoge\.jp)/ xxx@example.com

#送信先ドメインを変更
/@.+$/ @example.com

```

```
# /etc/init.d/postfix reload
```
Electron(Node.js)で同期処理関数を呼び出すと起こること

#Electron(Node.js)で同期API・非同期API利用時の違いを検証
Node.jsでのファイル操作は非同期API、同期APIが提供されていますが、
これらを使ったとき、どういう違いがあるのか？を検証してみました。

####**■なんのために、こんな検証をするの？**
C#なら、async/awaitを使えば、同期関数を呼び出しても平気じゃん？
Node.jsはダメなの？（結論から言えばasync/awaitとは別物です)

####**■画面構成**
こんな感じの画面で、ぐるぐるとアニメーションGIFが回り続けています。
![image](https://qiita-image-store.s3.amazonaws.com/0/147526/0857cf0e-c1ae-3aa3-da4a-fb518a5673d3.png)

####**■テスト結果**
- Syncボタンを押すと同期関数でファイル操作。
    - **GIFアニメーションは停止。**
- Asyncボタンを押すと非同期関数でファイル操作。
    - **GIFアニメーションは継続。**

![sync_async.gif](https://qiita-image-store.s3.amazonaws.com/0/147526/4d79a517-4ade-9ede-90e4-df3023f01244.gif)


####**■検証ソース**
[ソース一式](https://github.com/eurogrve/electron_sync_async)

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Sync Async Test</title>

    <script>
        var fs = require('fs');
        var maxcount = 50000;
        
        function async()
        {
            var times = maxcount;
            var count = 0;
            
            document.getElementById("btasync").disabled=true;
            
            function async_readdir() 
            {
                fs.readdir('.', 
                    function(err,files)  {
                        count = count + 1;
                        times = times - 1;
                        if(times>0) {
                            async_readdir();
                        } else {
                            console.log("complete : " + count);
                            document.getElementById("btasync").disabled=false;
                        }
                    });
            };
            
            async_readdir();
        }
        
        function sync()
        {
            var count = 0;
            var files = [];
            for(var i=0;i<maxcount;i++) {
                count = count + 1;
                files = fs.readdirSync('.');
            }
            console.log("complete : " + count);
        }
    
    </script>
  </head>

  <body>
    <div id="container">
        <p>Sync Async Test</p>
        <img src="gif-load.gif">
        <div>
            <button id="btsync"  type="button" onclick="sync();">Sync</button>
            <button id="btasync" type="button" onclick="async();">Async</button>
        </div>
    </div>

  </body>
</html>
```

####**■結論**
結局、Javascriptでの開発は非同期関数を使っておけ。
logrotate が圧縮してくれなかった


## 現象

とある rails アプリケーションのログローテートを設定していたが思ったように圧縮してくれない場合があった。

```
/path/to/app/log/*.log {
  daily
  rotate 7
  dateext
  missingok
  compress
  su ec2-user ec2-user
  sharedscripts
  postrotate
    puma_pid=/path/to/app/tmp/pids/puma.pid
    test -e $puma_pid && kill -USR2 $(cat $puma_pid)
  endscript
}
```

`logrotate -f` で強制的に実行してみると以下のようなエラーが出ていた。

```
error: error running shared postrotate script for '/path/to/app/log/*.log '
```

## 原因

以下のように puma.pid ファイルが存在する場合に puma の再起動を行う記述がまずいらしい。

```
    test -e $puma_pid && kill -USR2 $(cat $puma_pid)
```

上記だと、`test -e $puma_pid` でファイルの存在チェックを行って、存在しない場合はそのままスクリプトが終了するが、そのときの exit コードが 1 (異常) となって圧縮処理が行われない。

それを回避するため以下のように記述

```
    test -e $puma_pid && kill -USR2 $(cat $puma_pid) || true
```

上記のように、ファイルが存在せず再起動を実行しなかった場合は `true` を呼び出して exit コードを 0 (正常) にする。

これで想定どおりに圧縮されるようになった。
Android、iOSで画面を固定する

こんにちは。最近個人的にアプリ開発をしている時に気になったことについてまとめたいと思います。

#はじめに
スマートフォンでアプリを使用している時に、誤作動で他のアプリを起動したり、他アプリの通知が鬱陶しいと感じたことは、皆さん1度は経験したことがあるかと思います。
(私も某ひっぱりアクションゲームをやってる時に通知のせいでミスした時イライラを経験しております)
他には小さいお子さんがいる家庭では、子供にスマートフォンを貸した際に、見られたくないところへ遷移されてしまった、などという経験があるかと思います。

そんな時に使える便利な機能が、Android、iOSには存在します。
Androidは、
**アプリのピン留め**
iOSは、
**アクセスガイド**という名前の機能です。
本記事では、それらの呼び出し方について簡単にお話します。

#アプリのピン留め
アプリのピン留めはAndroid5.0から実装された機能です。
その名の通り、表示されているアプリを画面に固定してしまう機能です。(他アプリの通知も来なくなります)
![startLockTask.PNG](https://qiita-image-store.s3.amazonaws.com/0/151643/0bcdbae4-5d50-293e-bbe8-30823eb52837.png)

アプリのピン留めを行うには2つ方法があります。
1. 手動で設定する
2. プログラム上でStartLockTask()を呼び出す

1.について
端末上で、設定→セキュリティ→画面のピン留めという項目をonにした上で端末下部の□ボタンを押すと、
アプリの下にピンのマークが表示されますので、そちらを押すとピン留めが始まります。
![pinned.PNG](https://qiita-image-store.s3.amazonaws.com/0/151643/3235aa81-05d0-a997-7cca-3ed7a3f36aae.png)
解除したい時には、端末下部の◁ボタンと□ボタンを同時に押すことで、解除することができます
(解除後ロック画面へ遷移します)


2.について
アプリのピン留めを開始するには
android.app.ActivityのStartLockTask()をオーバーライドします。
https://developer.android.com/reference/android/app/Activity.html#startLockTask()

    @Override
    public void startLockTask() {
        super.startLockTask();
    }
上記を呼び出しますと強制的に起動しているアプリで画面を固定することができます。

ピン留めを解除したい時には、StopLockTask()を呼び出すことで解除が可能です。
https://developer.android.com/reference/android/app/Activity.html#stopLockTask()

    @Override
    public void  stopLockTask() {
        super.stopLockTask();
    }

Android5.0以上であれば上記の対応で問題なく機能しますが、Android5未満の対応を考えると、
Build.VERSION.SDK_INTなどで、OSのバージョン取得が必要になってきますね。

#アクセスガイド
iOSでの画面固定機能はアクセスガイドという名前で設定されています。
機能としては、アプリのピン留めと大体同じ機能です。(こちらも通知は来なくなります)

アクセスガイドの設定方法
1. はじめから手動で設定する
2. OpenURLなどで設定アプリを呼び出す(遷移まではできるけど設定操作は手動)
※アクセスガイドについては、プログラム上で強制する方法がわかりませんでした・・・
(ご存知の方がいらしたらご教授ください)

1.について
設定アプリを起動後、一般→アクセシビリティ→アクセスガイドの順で設定をonにします
<img width="414" alt="IMG_0013.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/151643/6f518c35-6ebb-8303-54cc-222c249fb670.jpeg">

その後、固定したいアプリを開きながら、ホームボタンを3回押下します。
諸々の設定事項を設定し、開始を押すとアクセスガイドが起動します。
https://support.apple.com/ja-jp/HT202612


解除する際には、ホームボタンを3回押下すると解除できます。

2.について
iOSは標準アプリにカスタムスキームが設定されており、それを呼び出すことで、
他のアプリから設定アプリ等へ遷移することができます
それを利用して設定アプリのアクセシビリティの項まで遷移することができます。
アクセシビリティのスキーマは、
Prefs:root=General&path=ACCESSIBLITY

で設定されておりますので、以下のような感じで呼び出すことができます

    if let url = URL(string:　"Prefs:root=General&path=ACCESSIBLITY") {
          UIApplication.shared.openURL(url)
    }

#まとめ
今回はAndroid、iOSで画面固定の方法をお話しました。
Androidではアプリ起動と同時に画面固定を設定することができますが、
かなり強制力の強い設定のため、ストアに公開するようなアプリに組み込むのは、
中々難しいかもしれません。
しかし、手段としてこのような機能も存在することを覚えていると
何か新しい発想へ繋がるかもしれません。

ご指摘等ありましたら、お気軽にご連絡下さい、
それでは。
git-ftp

## インストール

```
$ brew install git-ftp
```

## 設定

```
$ git config git-ftp.url ftp://<ホスト名>/<同期したいディレクトリまでのパス>
$ git config git-ftp.user <ユーザー名>
$ git config git-ftp.password <パスワード>
```

## 初期化

```
$ git add .
$ git commit -m "first commit"
$ git ftp init
```

## 使い方

```
$ git ftp push
```
[AWS S3]Content-Typeを一括で書き換える

# [AWS S3]Content-Typeを一括で書き換える

goofysを使ってS3に上げたファイルのContent-Typeが「binary/octet-stream」となっていたので、「application/pdf」に一括で変換した。
<pre>
$ aws s3 cp s3://path/to/dir/ s3://path/to/dir/ --metadata-directive REPLACE --content-type "application/pdf" --recursive
</pre>

参考
[AWS S3にアップロードしたファイルのContent-Typeを一括で書き換えるワンライナー](http://qiita.com/tmtysk/items/f85e7d03132e999c94a1)
Android アクションバーのメニューアイコンの変更方法

Androidのメニューで使われているアイコン(three dots)を変更したい！

![Screenshot_2016-12-12-12-44-43.jpeg](https://qiita-image-store.s3.amazonaws.com/0/74371/1319bc92-dc16-a22c-3d4a-384ddbf65713.jpeg)
これを↓
![Screenshot_2016-12-12-12-45-29.jpeg](https://qiita-image-store.s3.amazonaws.com/0/74371/c4955121-4d3b-935c-06d4-bed96e808788.jpeg)
こんな感じに自由に変更したい

###標準のメニューバー
####menu_main.xml
```ruby:qiita.rb
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="xxx.xxx">
    <item
        android:id="@+id/action_settings"
        android:orderInCategory="100"
        android:title="@string/action_settings"
        app:showAsAction="never" />

</menu>
```

###カスタマイズ
####menu_main.xml
```ruby:qiita.rb
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="xxx.xxx">
    <item
        android:id="@+id/action_settings"
        android:orderInCategory="100"
        android:title="@string/action_settings"
        android:icon="変更したいアイコン"
        app:showAsAction="always" >

        <menu>
            <item android:id="@+id/action_menu1"
                android:icon="@android:drawable/ic_menu_preferences"
                android:title="menu setting" />
            <item android:id="@+id/action_menu2"
                android:icon="@android:drawable/ic_menu_help"
                android:title="help" />
        </menu>
    </item>
</menu>
```

大きなitemの中にさらにmenuを作成し、そこに作りたいメニューを追加。
そして、常に表示するためにapp:showAsActionをalwaysに。
パワポで画像編集とか

どーもブランクLv30です。

パワポで絵コンテとか作る時って、
よくネットとかで類似する画像を探したりしてると思います。

そこで**欲しい画像が引っかからない**時ってイライラするよネ☆

なので、自分は気晴らしも兼ねてよくパワポを駆使して
そのまま作っちゃったりしてます。


今回はそのテクニックの一部を~~面倒なので~~ささっと紹介して終わらせようかなと！

#画像の斜めトリミング

トリミングなんて簡単だろというと思いますが、
斜めにトリミングはやったこと無い人多いと思います。


まずは・・・
適当に画像を作りました
![image](https://qiita-image-store.s3.amazonaws.com/0/153477/a0b99a77-eb3c-3adf-82dc-08814ccd370e.png)

ネットで落ちてるもの使うと著作権とかあったりするからね！

コレを使ってトリミングしようとすると
![image](https://qiita-image-store.s3.amazonaws.com/0/153477/fd554687-7ecc-5c29-009f-871103b2331e.png)
縦と横だけですよね。

これを斜めに回転しても
![image](https://qiita-image-store.s3.amazonaws.com/0/153477/7af817e7-b24c-ad20-c2c1-05e8fb655c48.png)
こうなるだけで斜め切りは無理なんです。


じゃあどうやるか


まずはコピー

からの形式を選択して貼り付け（どこかで右クリックすると貼り付けのオプションって出るやつです。）
![image](https://qiita-image-store.s3.amazonaws.com/0/153477/6b981e6c-4521-70e4-f267-3b6e2371b902.png)

図を選択！

![image](https://qiita-image-store.s3.amazonaws.com/0/153477/9d586d42-3919-49c9-1b12-1a63e1c88425.png)
すると・・・・

わかりづらい！！！

![image](https://qiita-image-store.s3.amazonaws.com/0/153477/5734b2aa-74c3-7854-b91b-f5c3537f162d.png)

わかりやすくしてみました。
こんな感じで貼り付けられます。

ちなみに自分はこのやり方ではなく、
コピー→ Alt+E → S で形式を選択して貼り付けを選んでます。（リボンになってから場所がわからなくなったので・・）

このやり方をすると、
![image](https://qiita-image-store.s3.amazonaws.com/0/153477/6243972f-e018-d951-c875-3df7d014db4a.png)
こんなん出てきます。
JPEGを選ぶと背景が透過されないのでPNGを選択してOKしてます。

ちなみにこれやるときにトリミングだったり画像縮小だったりしてからやると
ファイルサイズも小さくなるので一石二鳥です。特に画面スクショが多いファイルの場合。


で、

この斜めの画像を元に戻るように回します。

![image](https://qiita-image-store.s3.amazonaws.com/0/153477/5e78ec39-2b26-c431-1694-4d1a2c09e422.png)

こんな感じ。
回さなくてもいいんだけど回したほうがわかりやすいので。

ここでトリミング。もうあとは切りたいとこで切りましょ。

![image](https://qiita-image-store.s3.amazonaws.com/0/153477/fe939ad1-eaa1-6258-c2ff-e3f2bf38fbc8.png)

ってやると
![image](https://qiita-image-store.s3.amazonaws.com/0/153477/b889e662-2011-122b-0166-a18c4de63efd.png)
こんな感じで斜め切りが出来ます。
適当に切ったのが丸わかり！

ただこのままだと余白(透過背景部分)が多いので、

もっかい画像をPNGに張りなおしてー
余白をトリミングしてー
もっかいPNGで張りなおしてー

って
やると
![image](https://qiita-image-store.s3.amazonaws.com/0/153477/56448621-7071-9bf9-39c4-82db80534ea0.png)
余白が無くなるので完了！


・・・・あまり役に立たないネタかもしれませんが

参考までにどーぞ。
[Node.js]大企業様で使われているproxy.pacよりProxyサーバを設定している環境で「npm install」を使う方法


# Problem
大企業様の現場で構内請負や派遣で仕事していると、よく困ります。
それは、nodejsを使った簡単なツールをインストールする際に、npmでモジュールをダウンロードしようとするとダウンロードが出来ないことがある、ということ。
多くの場合、大企業様では[proxy.pac](https://developer.mozilla.org/ja/docs/Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_(PAC)_file)ファイルを使っています。そして、事務用PCが持っている固定IPアドレスによって、アクセスできるProxyサーバーを振り分けています。このようなネットワーク環境では、`npm install` でモジュールがダウンロード出来ません。

# Solution
この問題を解決するには次のように設定します。

```zsh
$ npm config set strict-ssl false
$ npm config set registry "http://registry.npmjs.org/"
（誤）$ npm config set registry "https://registry.npmjs.org/"
（正）$ npm config set registry "http://registry.npmjs.org/"

$ npm config set proxy "http://{{userid}}:{{password}}@{{server-address}}:{{port}}"
$ npm config set proxy "http://{{domain}}\{{userid}}:{{password}}@{{server-address}}:{{port}}"
```

|   |説明|
|:--|:--|
|{{domain}}           | ドメイン |
|{{userid}}           |ユーザーID, ユーザー名 |
|{{password}}         | パスワード |
|{{server-address}}   | サーバーアドレス。直接IPアドレスでもよい |
|{{port}}             |ポート番号。80とか8080とか。環境に合わせる。 |

- [npm config](https://docs.npmjs.com/cli/v6/using-npm/config)
    - [noproxy](https://docs.npmjs.com/cli/v6/using-npm/config#noproxy)
    - [proxy](https://docs.npmjs.com/cli/v6/using-npm/config#proxy)
    - [https-proxy](https://docs.npmjs.com/cli/v6/using-npm/config#https-proxy)

# See also

元の情報はこちら。

http://stackoverflow.com/questions/25660936/using-npm-behind-corporate-proxy-pac

## まとめ

proxy.pacでProxyサーバーを自動設定しているようなLAN環境では、

1. まず、proxy.pacファイルをダウンロードして、
2. 貸与された作業用PCの固定IPアドレスでproxy.pacファイル内を検索し、
3. Proxyサーバへのアドレスを見つけてね。

ということです。

元記事を調べて、事実を確認してね。

# Conclusion

とある企業様のネットワーク環境で、Windows10でnode.jsをダウンロードし、npmで上記設定を行い、モジュールがダウンロードできることを確認しました。（どこの企業様の社内ネットワーク？:rolling_eyes:）
Mac、Raspberry Piでは確認していません。たぶん同じ設定をすることになると思います。

新しい情報がありましたら、コメントにて教えていただけると幸いです。

# 補足情報

Windows 10で、`http_proxy`や`https_proxy`の環境変数に次のProxy設定を行うと、VSCodeの拡張機能ダウンロードやWSL2のLinuxコンテナーからの`sudo apt-get update`などもできるようになりました。

```msshell
$env:http_proxy
$env:https_proxy
$env:http_proxy = "http://<userid>:<password>@<server-address>:<port>"
$env:https_proxy = "http://<userid>:<password>@<server-address>:<port>"
```

または、環境変数に設定する。
![2021-06-17_153007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103572/29865047-4ad6-cf55-038f-0f1f6ff75b5b.png)


どこかのコミュニティーのどなたかの何らかに貢献できましたら幸いです。👍

（了）
Objectで、ng-repeatで、ちょいちょいハマるのでメモ

Angularで自分が一番駆使しているのがng-repeat
jsonの取得でちょいちょいハマるのでメモ
独学でやっているだけなので、自己責任で参照ください

## 整理：配列と連想配列の違い
#### 配列（array）

```ruby:javascript
testArray_1 = []; //配列の初期化
testArray_2 = {}; //連想配列の初期化
```
配列には要素に対して、様々なメソッドがある
以下、参考にどうぞ
http://qiita.com/takeharu/items/d75f96f81ff83680013f

連想配列には、末尾追加、先頭追加、場所を指定したような追加ができない
自分はよくObjectに**.push**を使って、Consoleに怒られる・・・。

これでng-repeatでハマることが多々ある

```ruby:javascript
testArray_3 = red:赤, green:緑, blue:青
```

```ruby:html
SPAN {{testArray_3.red}}{{testArray_3.green}}{{testArray_3.blue}}
```
赤緑青　となるが

```ruby:html
TD ng-repeat="(key, value) in testArray3"
 {{value}}
```
青緑赤　となる
連想配列はkeyをアルファベット順に取得してくるのでハマる
順番に **ng-repeat**を取得する場合は配列の方が扱いやすい。
配列の場合、歯抜けのデータで**""**ないし**void(0)(undefined)**を入れないと
フロントの処理が効かないのでズレズレテーブルになりやすい。

## 個人的力技
javascriptでは変数名（key）の先頭文字を数字にできないので、
姑息にもアンダーバーで数字を囲ってしまう。

```ruby:javascript
testArray_3 = _0_red:赤, _1_green:緑, _2_blue:青
```
こうしておくと、アルファベット順で書き出されても数字でソートが効く。
key:value　だと　歯抜けのときvalueだけ無い状態が担保されている気がするので
精神的ストレスが緩和する気がする。
【メモ】作りたいモノリスト

誰か作ってくれないかなぁ、でも最近、何も作ってないし何か作りたいなあと思っているもののリスト。
随時更新予定。

## ATOM-fuzzy-finderをまともにする

* .atomignoreとか、agignore対応とか。genコード無視とかリポジトリごとの都合ってもんがあるべや。
* AHOのように重すぎる。git ls-fileを使った高速化とかできるんじゃないの（雑）

## colorgoをまともにする

* https://github.com/songgao/colorgo
* t.Runとかでサブに入った時カラーリングされない。雑か
* FAILとかこそ色つけろよ的な。雑か

## ATOM-Go-guru

`Goggles` is written "ゴーグル" [goːgɯɽɯ] in katakana, so `Go-guru` is.

いい加減guru誰か頑張れよと思いつつ楽しそうなので作る

## ATOM-Japanesque-theme

[Japanesque](http://this.aereal.org/entry/2013/01/02/222304)

ふつくしい。
コーディングにも適用して使いやすい・見やすいかは未知数
LaravelでDBと連携したバリデーションを行う


退会済じゃない会員の中でメールアドレスが一意であることをバリデーションしたい。

```php:RegisterUserRequest.php
class RegisterUserRequest extends FormRequest
{

  public function authorize()
  {
    return true;
  }
  
  public function rules()
  {
    return [
      'email' => [
        'required',
        'email',
        'confirmed',
        Rule::unique('users')->ignore(false, 'canceled'), 
      ],
    ];
  }
  
  public function messages()
  {
    return [
    //
    ];
  }
}
```
Amazon Linux の aws cli が ImportError: No module named configloader とか吐いてる時の対処方法

## こんなのが出ている

```
aws
Traceback (most recent call last):
  File "/usr/bin/aws", line 19, in <module>
    import awscli.clidriver
  File "/usr/lib/python2.7/dist-packages/awscli/clidriver.py", line 42, in <module>
    from awscli.alias import AliasLoader
  File "/usr/lib/python2.7/dist-packages/awscli/alias.py", line 18, in <module>
    from botocore.configloader import raw_config_parse
ImportError: No module named configloader
```

## こうする

```
sudo pip uninstall awscli
sudo yum remove aws-cli
sudo -H pip install awscli --ignore-installed six
```

```
~/.bash_profile
export PYTHONPATH="/usr/local/lib/python2.7/site-packages:$PYTHONPATH"
```

```
source ~/.bash_profile
```
Angularの多次元配列でよくハマる

Angularでjsonから値を取得して表示させるケースで、ちょいちょいハマるのでメモ。
これが正しい使い方なのかが不明。参照は自己責任にてお願いします

## 通常の配列からのng-Repeat

```ruby:javascript
arraySample_A = ["1","2","3"]
```

```ruby:html
SPAN ng-repeat="sampleA in arraySample_A track by $index"
```

keyのない配列からの取得には、**track by $index** を入れる必用がある


## 二次元配列からのng-repeat
```ruby:javascript
arraySample_B = ["1","2","3"],["a","b","c"],["あ","い","う"]
```
```ruby:html
TR ng-repeat="sampleB in arraySample_B"
 TD ng-repeat="sampleC in sampleB track by $index"
```
sampleBは3回ループする
1. ["1","2","3"]
2. ["a","b","c"]
3. ["あ","い","う"]

sampleCも3回ループする
1. "1"
2. "2"
3. "3"
keyのない配列からの取得には、**track by $index** を入れる必用がある

## key:valueの取得(Object）
```ruby:javascript
arraySample_D = [like:apple,love:pen]
```

```ruby:html
{{ arraySampleD.like }}{{arraySampleD.love }}
```
アポーペンになる
keyで指定をすれば、valueが表示される

```ruby:javascript
arraySample_E = [like:apple,love:pen],[like:peach,love:pen],[like:banana,love:pen]
```
```ruby:html
TD ng-repeat="ppap in arraySample_E"
{{ arraySampleD.like }}{{arraySampleD.love }}
```
アポペン、ピチペン、バナナペンと表示される
多次元配列を行うケースでは key:value がとてもありがたい

## key:valueのng-repeat（Object)
```ruby:javascript
arraySample_E = [like:apple,love:pen],[like:peach,love:pen],[like:banana,love:pen]
```
```ruby:html
SPAN ng-repeat="(key, value) in arraySample_E"
{{ value }}
```
アポペン、ピチペン、バナナペンと表示される
keyを動的に持ちたいケースでは、**(key,value)**を使うことで
汎用的にデータを受け止めることができる
QiitaでTeXのロゴを表記する方法

$\rm\TeX$ のロゴをどうやって Qiita で表記するのか気になったので調べてみた。方法としては2つある。1つは、Google の Chart API で描画する方法、もう1つは、Qiita のコード挿入機能を使う方法。

# Google Chart API を使った方法

> *Markdown*: \![TeX]\(http://chart.apis.google.com/chart?cht=tx&chl=%5CTeX)
> 結果: ![TeX](http://chart.apis.google.com/chart?cht=tx&chl=%5CTeX)

# コード挿入
`math` コードブロックを利用する。

> (空行)
> \`\`\`math
> \rm\TeX
> \`\`\`
> (空行)

**結果**

```math
\rm\TeX
```

インライン表示するときにはインラインの数式表記を利用する。

> \$\rm\TeX$ はフリーの「組版システム」です。

**結果**

$\rm\TeX$ はフリーの「組版システム」です。
"yu" の y（人差し指）-> u（人差し指）でタイピングが一旦止まってしまいがち

Happy Elements株式会社 カカリアスタジオ Advent Calendar 2016の12日目の記事です。

## こういうことってありますよね

例えば、"レビュー(rebyu-)"と入力するときなのですが、ホームポジションに忠実に"yu" をy（人差し指）-> u（人差し指）と入力していました。
でも実は「あれ、一旦タイピングが途切れてる!?」的な感じをなんとなく感じていました。

![keyboard_typing-1.png](https://qiita-image-store.s3.amazonaws.com/0/37798/c4672a9f-b74f-6d0d-d31f-cd8bc565b23d.png)

## そのことへの対応

一旦タイピングが止まる感じへの対応をググった結果、y（人差し指）-> u（中指）と入力することにしました。
最初は違和感ありましたが、今ではすっかり馴染みました！

![computer_blindtouch.png](https://qiita-image-store.s3.amazonaws.com/0/37798/d85f69e0-1c02-dea0-c0f4-a8896707c35f.png)

## さらに

C#でコーディングしていると1日30回くらい"null"ってタイピングすると思うのですが、その流れで"nu"もn（人差し指）-> u（中指）と入力することにしました。
今ではすっかり馴染みました！

それでは、よいタイピングライフを！
文字列の一部をexampleにおきかえる

AWSのドキュメントみてるとたまに遭遇するこういうやつ
http://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSGettingStartedGuide/AWSCredentials.html

> アクセスキー ID:AKIAIOSFODNN7EXAMPLE
シークレットアクセスキー: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

手順書とか書いてると，キーを発行したいけど自分のキーを手順書に載せるわけにはいかない．．どうしよう，みたいな?

```ruby:examplify.rb
#!/usr/bin/env ruby

word = ARGV[0] || STDIN.gets

exit if word.length <= 7

def gen_e
  [%w(e E 3), %w(x X), %w(a A), %w(m M), %w(p P), %w(l L 1), %w(e E 3),].map {|a| a.sample}.join
end

def gen_s(w)
  return w if w.length < 8
  if w.length < 14
    s = rand 1..w.length-7
    w.tap {|_| _.slice!(s, 7)}.insert(s, gen_e)
  end

  [gen_s(w[0...w.length/2]), gen_s(w[w.length/2..w.length])].join
end

puts gen_s(word.chomp)
```

```shell-session
uraura@rosemary$ echo abcdefghijklmnopqrstuvwxyz0123456789 | ./examplify.rb
abexAMpL3jkEXAMplEs3xAmple012EXAmpl3
```

置き換えすぎな気もするけど．．．まぁいいか．．．
railsを5.0.0.1から4.2.7にダウングレードした時に出るエラーについて(Expected string default value for '--rc'; got false (boolean))

研修を受けていて、railsの最新バージョンではなく、Ruby2.2.2に対応しているrails4.2.7が必要になったのでバージョンを切り替えるためダウングレードをしました。
そこで問題が発生し、検索しても海外の方の記事しかなかったので共有したいと思います。

#まずはダウングレード
ダウングレードの参考ページ
http://qiita.com/Hassan/items/eef26c870eb26a0c68e0

Qiitaのこの記事を参考にしました。

やってみたところ変なエラーメッセージが出てきます。

```
$ rails -v
Expected string default value for '--rc'; got false (boolean)
Rails 4.2.7
```

エラーメッセージで検索しても日本のものはなかったです（単に調べたりないだけかも・・・）。
ちなみにrails newでアプリケーションを作った時にも出てきます。


```
$ rails new book
Expected string default value for '--rc'; got false (boolean)
・
・
・
```
こんな感じ。全く同じです。
海外の質問サイトの方を見てみると、一応無視してても動くには動くみたいです。

##バージョンを戻してみる
でも気になるのでrailsのバージョンを5.0.0.1に戻してみました。
同様に上のページの手順でやってます。

```
$ gem install rails -v '5.0.0.1' --no-rdoc --no-ri
Fetching: railties-5.0.0.1.gem (100%)
Successfully installed railties-5.0.0.1
Fetching: rails-5.0.0.1.gem (100%)
Successfully installed rails-5.0.0.1
2 gems installed
```
よくみるとgemのinstall数が少ない。
バージョンを確認してみると・・・

```
$ rails -v
Rails 5.0.0.1
```
rails 4.2.7のときに出てきたエラーのようなものが出てこない！
gemのinstall数の事を考えてみると、rails 5.0.0.1でinstallしていたgemがrails 4.2.7では使えないということではないかという結論に至りました。
もしかしたら違うかもしれません・・・。

#結論
アプリを作るのにも、サーバーに繋ぐのにも全く問題はないです。
海外の方が書いていたように、無視して大丈夫、railsは動きます。
これが気になる方はgemをいじるしかないんじゃないでしょうか？

#追記
解決策が見つかりました。
thorのバージョンもダウングレードが必要のようです。

```
$ gem install thor --version="0.19.1"
$ gem uninstall thor --version="0.19.4"  #前入っていたthor
```
で無事解決しました！

```
$ rails -v
Rails 4.2.7
```
と表示されています。
whiteleaf7@githubさん、ありがとうございます！
react-routerを使って静的コンテンツを配信する際のrewrite設定覚書

react-router使ってアプリ作った際、ディレクトリ掘ってブックマークすると、
404 not foundになってハマるんですよね。

ということで、rewriteしないといけないんですけども、
調べた範囲でまとめました。

## react-router サンプルコード

routerはbrowserHistoryを想定

```js:src/index.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
import App from '../containers/App';

window.React = React;

ReactDOM.render((
  <Router history={browserHistory}>
    <Route path="/">
      <IndexRoute component={App} />
      <Route path="/:userName" component={App} />
    </Route>
  </Router>
), document.getElementById('root'));
```


## httpd

```apache:public/.htaccess
RewriteEngine on
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
```

## Firebase Hosting

```json:./firebase.json
{
  "database": {
    "rules": "database.rules.json"
  },
  "hosting": {
    "public": "public",
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}
```

## Netlify
公開ディレクトリに置く必要あり

```:public/_redirects
/* /index.html 200
```
これからディープラーニング向けフレームワークを推す人にまず明らかにしてほしいスペック

各位におかれましてはディープラーニング推しツールがあると思われますがまずは以下のリストを埋めてほしいんですよ。それもプレゼンスライドでだらだらと説明するんじゃなくてA4を2ページくらいでサクッと把握したいんです。

きらびやかな言葉でまるで万能で将来性のあるように語られて、いざ調べてみるとアレもないコレもないみたいな無駄な作業はさせないでほしいわけですよ。

下のような基本的なことを把握するのに時間がかかるフレームワークが多すぎる！TensorFlow含めて！どのフレームワークの公式サイトもトップページがキラキラワードしかない！ディープラーニングだけじゃなくて最近のフレームワーク界隈はみんなそう！まず基本的な仕様を15分で把握させろ！売り文句はそこからにしろ！

### プレゼンする前にまずはともかく配布してほしいスペックの一覧

- オープンソース?プロプライエタリ?
- オープンソースの場合のライセンス
- 標準フロントエンド言語、コア言語、他言語実装
  - TensorFlowの例 : フロントエンド python、コア言語 C++、他言語 haskell, golangの実装が進行中
- 実行環境
  - Linux/macOS/Windows/iOS/Android/Windows phone
- インストール方法(ローカルビルド?deb?rpm?msi?exe?pip?gem?)
- GPU対応とバックエンド(CUDA? OpenCL?)
- その他依存ライブラリ(eigen, cuDNN, ...)
- マルチGPUへの対応
- 分散環境への対応
- モバイル対応
- ネットワークの記述法(コード?yaml?DSL?)
- 入出力ファイル形式
    - 学習時の入力は画像をそのまま読める？ビデオやオーディオのデコードは？CSVとかXMLとか便利に読める？独自の形式に変換する？
    - モデルの出力は？Json？独自バイナリ？ProtocolBuffers？
- 学習データのファイルフォーマット
- ビジュアライズツール
  - 学習の過程をモニタできるか
  - 特に画像において学習中の出力やフィルタなどをモニタできるか
  - グラフ構造を可視化できるか
- デバッグツール
- その他運用ツール
Python上でUNIXコマンドをたたきたいとき

#概要
MacのターミナルのコマンドをPythonで一括実行しようと思った人向け

#環境
・Mac OS Sierra 10.12.1
・python 3.5.2

#やり方
```py
import subprocess
subprocess.call(["command"])
```
これだけ
※最初の記事では、書き方が間違っていました。
[ShaderKid](http://qiita.com/ShaderKid)さんご指摘ありがとうございました！

#使用例
```py
import subprocess

# hello.txtを作成　中身は空
subprocess.call(["touch", "hello.txt"]) # --1

# hello.txtにhello world を書き込む
subprocess.call(["echo hello world > hello.txt"], shell = True) # --2
```

　書き方は２通りあって、上記の１の場合は、UNIXで空白とするところを「,」で区切る。
２つ目は、第１引数に文字列を与えて、`shell=True`とする。

　デフォルトでは`shell=False`となっており、公式でもTrueとすることはセキュリティ上の脅威となる、という記述があるため推奨されていない。
　ただ現時点では、２のようなコマンドを１の書き方で実行しようとすると、ターミナル上に文字が写されるだけなので、解消方法がわからない。

#Error:Segmentation faultが出てきたとき
最初実行しようとしたら`Segmentation fault`というエラーメッセージが出てきた。
ググってもよくわからず、試しにpython3で実行したら動いた。python3を入れていたら、`python3 index.py`みたいに打っても実行できるので、もし同じような現象になった方は実行してほしい。

#参考
・[サブプロセス管理](http://docs.python.jp/2.7/library/subprocess.html#module-subprocess)
・[Pythonでsubprocessを使ってコマンドを実行する方法](http://qiita.com/ssaito/items/cddd12dc762336484765)
Protocol Buffers はもう古い？ 爆速プロトコル SBE とメッセージングライブラリ Aeron！

先日、Akkaの最新ドキュメントをチェックしてみたところ、何やら、Akka Remotingをリニューアルしているらしく、新版のコードネームは「Artery」というらしいです。

[Akka Remoting (codename Artery)](http://doc.akka.io/docs/akka/2.4/scala/remoting-artery.html)

ちなみに、従来の Akka Remoting は、[Netty](http://netty.io/)を使って、実際のデータ転送部分は実現していました。

Artery では、このデータ転送部分の実装は、メッセージングライブラリである Aeron を使っており、この Aeron が [Simple Binary Encoding (SBE) ](https://github.com/real-logic/simple-binary-encoding/wiki)を使用しています。

<img width="50%" alt="stack diagram" src="https://qiita-image-store.s3.amazonaws.com/0/21380/7c6c2948-dd2b-cac3-2646-c15e404f9346.png" />

Artery には、次のような特徴があります。

* TCP ではなく UDP ベースの実装
* 高スループット、低レーテンシー
* ユーザメッセージから内部制御メッセージを分離して安定性を向上させ、与えられたサブチャンネルを使った、ヘビーなトラフィック発生時の失敗の検知を抑制する
* 自由な配置
* 小さなメッセージによる干渉を避けるための大きなメッセージを使った分離されたサブチャンネルのサポート
* 小さなメッセージのためのオーバーヘッドを削減するための通信時のアクターパスの圧縮
* バイトバッファを直接使った高速なシリアライゼーション・デシリアライゼーションのサポート
* 実装の仕様のイベントによるユーザログを汚さない、実装の問題のデバッグを助けるための内蔵されたフライトレコーダー
* 大規模システムのローリングアップデートをサポートのための、Akkaのメジャーバージョン間で提供されるプロトコルの安定性

そして、 Artery で利用されている Aeron の特徴は、信頼性の低いメディアプロトコル上で動作することを前提としており、 UDP 以外でも、 InfiniBand なども想定されているようです。
また、実際の処理は、メディアドライバーという形で、プロトコル毎のサポートを実装しています。
現在は、 Java と C の実装があり、今回見つけることができませんでしたが、FPGA版もあるようです。

次に、 Aeron で利用されている SBE の特徴は次のようなものになります。

* 低レイテンシー
* Protocol Buffers よりも 16〜25倍高いスループット
* Java、C++、.NETの実装
xUTPの著者から教えてもらった「テストのクラフトマンシップ」

これは[Recruit Engineers Advent Calendar 2016](http://www.adventar.org/calendars/1617#list-2016-12-11)の11日目の記事のはずなのですが、すいません完全に遅れております。今日書きます。

ひとまず、この辺りの話しようと思います。出来上がったら追記します。

http://singapore2016.xunitpatterns.com/

# 12日のエントリー

[akito0107](http://www.adventar.org/users/11202)さんのターン！　よろしくお願いします。
シェルでtry-catch. 標準出力を渡しながら異常終了ステータスを検知する

これは[VAddy Adventカレンダー](http://qiita.com/advent-calendar/2016/vaddy)12日目の記事です。
[VAddyは、継続的なWeb脆弱性検査が簡単に実現できるSaaSです。](https://vaddy.net/ja)

私が好きな国内クラフトビールに、志賀高原IPAがあります。
この会社は[自分たちが飲みたいビールを作るをコンセプト](http://www.tamamura-honten.co.jp/?mode=f3)に、ホップまで栽培しています。いいですねー！
いつか志賀高原でパウダースノーを堪能してホテルで最高の一杯を飲んでみたいものです。


# シェルのパイプで繋いだ先で、パイプ元のコマンドの異常終了ステータスを検知する
前回の記事で、[VAddyのWeb脆弱性検査を定期的に実行して結果をSlack通知](http://qiita.com/ichikaway/items/2492de7fa4a01f241a59)を書きました。
この記事ではVAddyのCLIツールから、脆弱性検査開始し、結果取得して脆弱性があった場合のみSlackに通知する方法を載せました。
VAddyのコマンドの結果をパイプで繋いでSlack通知スクリプトに渡せば問題ないだろうと思っていたのですが、パイプだけではうまく動かなかったため今回はその思考錯誤の結果を書きます。


## やりたかったこと

やりたかったことは、go-vaddyコマンドで脆弱性が発見された場合はコマンドが異常終了（ステータス1)するので、その時のみgo-vaddyコマンドが標準出力した結果をslackに投げることです。
わかりやすく言えば、
`go-vaddy.exe | slack.sh`
のような処理をしつつも、slack.shはgo-vaddy.exeが異常終了した時にのみslackに投稿する処理をしたいのです。
このため、クリアしなければいけない課題は下記になります。

- go-vaddyコマンドの標準出力を、slackに投稿するコマンド`slack.sh`で受け取る
- `slack.sh`は、go-vaddyコマンドが異常終了した時のみ動作する

1つ目はパイプだけで解決できますね。2つ目はリストを使って、`go-vaddy.exe || slack.sh`のようにすれば解決できます。
ただ、それらを同時に満たすには簡単ではありませんでした。

## 結論
先に結論から書きますね。
今回は、シェルのtrapコマンドを使いました。
これにより、異常終了した時のみtrapが発動して指定した関数を実行できます。
try-catchみたいな動きですね。異常終了したコマンドがあれば、catch(trap)が実行され、slack投稿スクリプトが動作します。

```bash
#!/bin/sh

set -eu

trap catch ERR

function catch {
    echo "$MESSAGE" | ./slack.sh
}

MESSAGE=$(./go-vaddy/bin/vaddy-macosx64)
```

`trap catch ERR`で異常終了した時のみ`catch()`が実行されます。
go-vaddyの標準出力は、`$MESSAGE`に入るため、trapの処理でその変数をechoしてslack通知スクリプトに渡しています。

trapの最後のERRをEXITにすれば終了時に必ず実行するようになるため、finallyの動きができます。


## 試行錯誤
ここからは、trapにたどり着くまでに試した方法を書いていきます。

### 実験1: パイプだけでやる
`go-vaddy.exe | slack.sh`
最初に思いついたのは、パイプの後のコマンド`slack.sh`の中で`$?`を使って最初に実行したコマンドの終了ステータスを取得して制御する方法です。
結果、パイプはコマンドの実行が同時に走るため前の処理の標準出力結果を待って処理することはできても、終了ステータスはうまく取得できませんでした。


### 実験2: ||リストを使って中間ファイルに出力する
`go-vaddy.exe || slack.sh`のように||リストを使うと、go-vaddyが異常終了した時のみslack.shが実行できるようになります。ただ、go-vaddyの標準出力はパイプのようにslack.shに引き継ぎできません。
これを解決するために、中間ファイルを作って処理してみます。

```bash
go-vaddy.exe > hoge.txt || cat hoge.txt | slack.sh
```

いいですね。これでできました。
ただ中間ファイルが正常終了した時に削除することができないのが少しダサいですね。。やめておきましょう。


### 実験3: コマンド置換で標準出力を変数に入れて処理する
コマンド置換は、

```bash
FOO=`go-vaddy`
FOO=$(go-vaddy)
```

のように、コマンドの実行結果の出力を変数`FOO`に入れるものです。
これで出力を変数にいれて、コマンド置換の実行結果を`$?`で評価すれば良いかと思いました。

```bash
FOO=$(go-vaddy)
if [ $? -gt 0 ]; then
  cat "$FOO" | ./slack.sh
fi
```

これはgo-vaddyが正常終了した場合はうまく動くのですが、`FOO=$(go-vaddy)`が異常終了した時点でこのスクリプト全体も終了するため、ifまでたどり着かずうまくいきませんでした。


##　さいごに
もしかしたらもっとエレガントな処理があるかもしれませんが、今回の仕様を満たすためにはtrapで十分そうだとわかりました。
今まで、パイプとリスト(&&, ||など)の動きを正確に理解して使っていなかったのだと反省しました。
シェルは大事ですね。これからシェル道に邁進していきたいと思います。
機械学習をこれから学ぶ人がPythonを使うべき3つの理由

<a href="https://kikagaku.net/blog/"><img src="https://kikagaku.net/blog/wp-content/uploads/2016/12/kikagaku_online_ogp.png"></a><br>
こちらは『[**キカガク Online**](https://kikagaku.net/blog/)』の記事を、Qiita向けに編集してお届けしています。

---

今回は、さぁこれから機械学習を勉強しようと思っている人に向けて、
どのプログラミング言語で学んでいくべきかをお伝えしたいと思います。

タイトルですでにバレていますが、私のオススメのプログラミング言語はずばり[**Python**](http://www.python.jp/)です。

世の中に数多あるプログラミング言語の中で、なぜPythonを使うべきなのか。

今回はその理由を3つ紹介します！

# 1. 機械学習に使えるライブラリが豊富！

プログラミングというのは普通、ゼロから自分で書くことはめったにありません。

ではどうするかというと、世の中に公開されている**ライブラリ**や**フレームワーク**を使って書くことが多いです。

例えば、Pythonを使ってWebサービスを作るときは[Django（ジャンゴ）](http://djangoproject.jp/)というWebフレームワークを使って作ったりします。

機械学習も同じで、大抵はライブラリを使ってプログラミングしていきます。

メジャーなプログラミング言語にはだいたい機械学習のためのライブラリがありますが、
その中でも**Pythonの機械学習ライブラリが豊富さ・実績において抜きん出ている**といえるでしょう。

いくつか関連するライブラリを上げますので興味があれば調べてみてください。

|ライブラリ|説明|
|:---|:---|
|[scikit-learn](http://scikit-learn.org/stable/)|たくさんの機械学習の手法を集めたライブラリ。|
|[TensorFlow](https://www.tensorflow.org/)|Googleが開発しているディープラーニングのフレームワーク。|
|[NumPy](http://www.numpy.org/)|数値計算用ライブラリ。高速に計算でき、計算時間がシビアな機械学習に使われることが多い。|

# 2. サービス公開まで一気通貫でできる！

機械学習だけだったり、研究用途だけであったりであればその他のプログラミング言語でも適切なものがあります（MATLABなど）。

Pythonがそれらの言語と違うのは、機械学習を使った**サービスの公開まで一気通貫にできる**という点です。

PythonはWebの世界でも広く使われているため、
先ほど上げたDjangoを始めとしたWebフレームワークが多くあります。

こうしたWebフレームワークを使うことで、
機械学習を使ったサービスを世の中にいち早く公開できるメリットがあります。

# 3. 参考となる書籍・サイトが多数！

最後の理由は、Pythonで機械学習を勉強する上で**参考となる書籍やサイトが豊富**にあることです。

これから始める方にはこれが最も重要なポイントではないでしょうか。

同じくキカガクOnlineの運営を行っている@carat_yoshizakiが
機械学習初心者のためのオススメの参考書を紹介してくれているので、
こちらも参考にしてください。

[【機械学習初心者向け】最初に抑えるべき３０項目とオススメの参考書２０選](http://qiita.com/carat_yoshizaki/items/1061aca10e6a193366c6)

# おわりに
以上、これから機械学習を学ぶ人がPythonを使うべき3つの理由を紹介しました。

キカガクOnlineでも、これからPythonを使って機械学習の手法を紹介していく予定ですので、
ぜひいっしょに勉強していきましょう！

# キカガク Online
[**キカガク Online**](https://kikagaku.net/blog/) では、機械学習入門向けの記事を配信します。

機械学習や人工知能、ディープラーニングを学びたい方向けの基礎講座の記事から、機械学習を使ったビジネス導入例まで幅広く取り扱います。

<a href="https://kikagaku.net/blog/"><img src="https://kikagaku.net/blog/wp-content/uploads/2016/12/kikagaku_online_ogp.png"></a>
Illustratorの制作TIps

# 便利なショートカットを覚えよう
イラストレータは切り紙で絵を作るようにオブジェクトの重ねで画面を構成していくため
photoshopのようなレイヤーの概念が希薄です。
ショートカットを覚えてオブジェクトの重ねを自由自在に操作できると
早く作業をすることができます。

>
詳しくはこちら
[Illustrator作業の効率化！覚えておきたいショートカットキーとカスタマイズ](http://liginc.co.jp/web/design/illustrator/87763)


# 覚えると便利なIllustratorの機能
- [トレースする時のパスの取り方](#トレースする時のパスの取り方)
- [アンカーポイントの切り換え](#アンカーポイントの切り換え)
- [リフレクト](#リフレクト)
- [複数のオブジェクトの塊で切り抜きする](#複数のオブジェクトの塊で切り抜きする)
- [線を部分的に引く](#線を部分的に引く)
- [線の部分を塗で表現する](#線の部分を塗で表現する)

## トレースする時のパスの取り方
![1.gif](https://qiita-image-store.s3.amazonaws.com/0/54596/82e0e916-eba6-78be-3533-f127a9750c57.gif)

1. ざっくりとパスを取ります。<br>
角とカーブの真ん中を意識的にポイントしていくと後で楽です。
1. ポイントをトレース元の線に寄せます。
1. ハンドル（ひげ）を使ってカーブを合わせます。


## アンカーポイントの切り換え
![2.gif](https://qiita-image-store.s3.amazonaws.com/0/54596/085f033e-8d26-0088-ec13-4b172fc713e0.gif)


## リフレクト
同じパーツが複数回必要な時、コピー＆ペーストより楽な方法。
![3.gif](https://qiita-image-store.s3.amazonaws.com/0/54596/3d57b362-264b-c53a-cd3e-32b79fe85ac4.gif)

1. パーツを選択し右クリック ＞　変形 ＞　リフレクト
1. 今回は右半身を反転コピーしたいので「垂直リフレクト」を選択。<br>プレビューにチェックを入れておくと仕上がりが確認できます。
1. 「コピー」をクリック。
1. 位置を調整して完成です。



## 複数のオブジェクトの塊で切り抜きする
![4.gif](https://qiita-image-store.s3.amazonaws.com/0/54596/9b100372-60ea-7c93-2bf4-7b9dacb27ba1.gif)


1. 余分な部分（オレンジ色）をすべて選択
1. ＞パスファインダー＞複合シェイプを作成＞拡張
1. 複合された余分な部分と、抜きたいパス（青色）を選択
1. ＞前面オブジェクトで型抜き


## 線を部分的に引く
![5.gif](https://qiita-image-store.s3.amazonaws.com/0/54596/a70695c5-6a42-cc66-b3b8-98bb51406199.gif)


1. 黄色い部分をコピーし、線を付けます。（塗りは無くします）
1. 主線と被る部分を削ります
1. 元の場所に再配置して完成


## 線の部分を塗で表現する
この辺は好みです。線の部分を塗で描画すると良い点をいくつかご紹介。
![6.gif](https://qiita-image-store.s3.amazonaws.com/0/54596/3fd8086e-cd9a-1688-9029-059b3fb8a6a5.gif)


1. 質感を出せる：<br>
線の細かな調子を出せます。<br>
キャラクターを描いたりするとき仕上がりが違ってきます。
1. 合成がラク：<br>
線の入り方を気にせず、オブジェクトの重ねだけに集中できます。<br>
※demoは線を最背面に再配置しています。
1. 編集がラク：<br>
「この色を塗りで使いたいな」→「あ！線だった！；；」という事故が減らせます。


##まとめ
数をこなすと早くなります。自分なりの楽しく練習する方法を探してみましょう。
わたしは好きなキャラクターをトレースしたり、テーマ決めて作ってみたりしてました。

![7.png](https://qiita-image-store.s3.amazonaws.com/0/54596/c325c09a-352b-2726-1b96-ba3abfb92fe7.png)



おしまい
Elm 0.18への対応方法

## はじめに

Elm 0.18 がリリースされていくらか経ったので、0.17依存のプロジェクトを0.18に対応させる手順を紹介します。
基本的には、[Elm 公式のアップグレード手順](https://github.com/elm-lang/elm-platform/blob/master/upgrade-docs/0.18.md)に従うだけで、ほぼ自動的に対応できますが、いくつか注意点を補足しています。

## Elm Platform のアップグレード

公式のアップグレード手順には明記されていないですが、まず Elm Platform のアップグレードが必要です。
基本的には、[Elm 公式ガイド](https://guide.elm-lang.org/install.html)に書いてあるインストールの方法で、最新の0.18版を上書きするだけです。
npm の場合なら、単に

```bash
npm install -g elm
```

でアップグレードできるでしょう。

### elmenv を使っている場合

elmenv なんかを使うのはやめましょう！
メンテナンスもあまりされていないし、ソースコードから elm をコンパイルするのでクッソ遅いし、コンパイルこけるし、つらいです。
かわりに、[elm-use](https://github.com/rtfeldman/elm-use)を使うことをおすすめします。
なんと、

```bash
npm i -g elm-use
# または
# yarn global add elm-use
elm-use 0.18
```

だけで、後述する `elm-format` もすぐに使えるようになります。
もちろん、すでに Elm 環境が入っている方は、そちらの実行ファイルが優先されないように、削除するなり、パスの優先順位を調整するなりしましょう。

## elm-format のインストール

Elm のコードをParsingして、整形する`elm-format`をインストールします。
これも公式ドキュメントには明記されていませんが、事前にインストールしておかないと、後述の`elm-upgrade`が途中でコケます。

[elm-formatレポジトリ](https://github.com/avh4/elm-format#installation-)の指示にしたがって、インストールしましょう。

## elm-upgrade

[`elm-upgrade`](https://github.com/avh4/elm-upgrade#elm-upgrade)を使えば、ほぼ一発で Elm 0.18 への対応が可能です。

```bash
npm install -g elm-upgrade
cd path/to/my/elm/project
elm-upgrade
```

## 依存ライブラリの変更に起因する修正

ここまでで、基本的な対応は完了ですが、`core`パッケージのAPIが変更されたりしている影響で、追加の修正が必要です。

Elmはコンパイラが優秀なので、`elm-make`などを走らせてみて、コンパイルエラーが出たところを修正するだけで問題ないでしょう。

詳しくは[移行ガイド](https://github.com/elm-lang/elm-platform/blob/master/upgrade-docs/0.18.md)にも書いてありますが、以下の変更に起因するエラーが出ると思います。

* `program` 関数の引数がかわった
* `andThen` の引数の順番がかわった
* 変数名に`'`を使えなくなった

いずれも、コンパイラの指示通りに修正するだけです。

## (オプション) インデントを修正

`elm-format`は、4スペースインデントのみに対応しています。
何度か「2スペースに対応してくれ」というissue([#158](https://github.com/avh4/elm-format/issues/158)、[#226](https://github.com/avh4/elm-format/issues/226))がありましたが、設定ファイルでの対応も含め、完全に否定されています。

どうしても2スペースインデントがいい方は、たとえば以下のコマンドで2スペースに変更しましょう。

```
find src -type f | xargs sed -i 's/    /  /g'
```

## (オプション) バージョンアップデート

もし、今回0.18対応させたプロジェクトを、[Elm Packages](http://package.elm-lang.org/)に公開しているのであれば、[バージョンを更新して公開](https://github.com/elm-lang/elm-package#user-content-publishing-updates)しましょう。