OmniAICreator/Qiita-1.07M huggingface dataset:
ELB経由のfluentd Aggregatorを安定化するためにやった3つの対策

この記事は[リクルートライフスタイル Advent Calendar 2016](http://qiita.com/advent-calendar/2016/recruitlifestyle)の2日目の記事です。

## はじめに

弊社ではログ収集に[fluentd](http://www.fluentd.org/) v0.12を主に使っており、システム自体はAWS上に構築しています。
fluentdのAggregatorには、ノードの追加がしやすいように負荷分散にELBを使う構成にしています。

![20161125_fluentd_cluster_001.png](https://qiita-image-store.s3.amazonaws.com/0/59581/3e826c2e-49a7-5c09-5bfa-f4669e794ecd.png)

ここ最近までは、複数のサービスからのログを1つのELBで受け、各Aggregatorノードで処理するという構成をとっていました。
ただログが増えてくると安定性に問題が出てきたため、その際に対策として行ったことについてまとめます。

## やったこと

### 1. コネクション数とログ量のアンバランスを解消する

fluentdのsecure-forward output pluginは、コネクションを切らずにログを送り続けます。
またELBは最もコネクション数が少ないノードへ接続を行う負荷分散の方式です。

1コネクションあたりのログ量がほぼ同じであれば、このロードバランシングはうまく機能します。
しかし、1コネクションあたりのログ量にばらつきがある場合においては、うまく負荷分散できない場合があります。
fluentdの負荷はログ量に対して上がっていきますが、ELBの負荷分散はコネクション数によって行われるためです。
例えば、サービスAとBは同じくらいのサーバー台数で、Aは非常にログ量が多く、Bは少ないといった場合に、特定のノードにログ量の多いコネクションが集中してしまうことがあります。

Aggregatorにログが流すサービスが増えることで、そういった状況が多く発生するようになり、ノード単位での負荷が安定しないという問題に遭遇しました。

#### 検証実験

以下は2台のfluentd Aggregatorに対して、4つのfluentdプロセスからログを送ったときのAggregatorのCPU使用率のグラフです。

<img width="449" alt="fluentd-cluster-cpu.png" src="https://qiita-image-store.s3.amazonaws.com/0/59581/e4ed1a30-1419-b4dd-9c4d-6438e1b2111c.png">

4つのfluentdプロセスのうち、1プロセスだけ1000レコード/secに設定し、残りの3プロセスは10レコード/secに設定しました。keep_aliveは60秒に設定しています。

グラフを見るとログ量の多いプロセスからログを受けているノードの負荷が高くなっています。
またkeepaliveの時間ごとに接続先が変わり負荷が安定しないことがわかります。
なお、この間2つのノードのでコネクション数には差はありませんでした。

#### 対策したこと

コネクションあたりのログ量のばらつきを抑えるためにサービスごとにAggregatorを分割する対応を行いました。
同じサービス内であれば、ログ量の多いサーバーは台数が多く、ログ量が少ないサーバーは台数が少ないため、上記のような問題は発生しにくくなるからです。

![20161125_fluentd_cluster_002.png](https://qiita-image-store.s3.amazonaws.com/0/59581/010626eb-abd7-6f8d-bd5d-486c1e34ef8f.png)

この対策を行った結果、ばらつきの大きかった各ノードの負荷がだいたい均一になりました。
これは効果の大きかった対策です。

### 2. アイドルタイムアウトを設定する

ELBは無通信のコネクションを切る時間としてアイドルタイムアウトを設定できます。
もしログが長時間流れない状態になるとELBから強制切断されてしまい、以下のようなWarningが出ます。

```
[warn]: disconnected host="xxx.xxx.xxx.xxx" port=xxxxx
[warn]: dead connection found: xxx.xxx.xxx.xxx, reconnecting...
[warn]: recovered connection to dead node: xxx.xxx.xxx.xxx
```

これを防ぐにはアイドルタイムアウトをsecure-forward output pluginの`keep_alive`より長い時間に設定すれば解消します。

### 3. 接続のストリーミングを設定する

ELBにはデタッチしたインスタンスへのコネクションを切れるまで維持してくれる機能として接続のストリーミングがあります。

この値も同じくsecure-forward output pluginの`keep_alive`より長い時間に設定しておかないと、デプロイ時などにインスタンスをデタッチした際に上記と同じWarningが出ます。

## まとめ

ELBを経由したAggregatorの構成はあまり情報がなく、試行錯誤を繰り返して安定化してきました。
ELBとは関係なく負荷を下げるために行ったことは他にもありますが、最も効果的だったのはAggregatorを分割したことでした。

Aggregatorを分割するとデプロイ時の手間が増えたりしますが、それをどうやって解消していったかについては[Recruit Engineers Advent Calendar 2016](http://www.adventar.org/calendars/1617)に書く予定です。
あと１ヶ月で2016年も終わるので、ES2016をおさらい。

classやアロー関数の登場したES2015に比べて、ES2016は地味な感じがします。
しかし、2017年になる前にもう一度ES2016を振り返ってみましょう！

## Array.prototype.includes

これは`Array.prototype.indexOf`みたいな感じで、配列の中の要素を確認できます。
indexOfとの違いは値があれば`true`、なければ`false`を返す所です。

すっきり書くことができます。


```javascript
const items = [1, 2, 3, 4, 5];

// Array.prototype.indexOf
if (items.indexOf(4) !== -1) {
  console.log(items.indexOf(4)); // 3
}

// Array.prototype.includes
if (items.includes(4)) {
  console.log(items.includes(4)); // true
}
```

## Exponentiation Operator

累乗計算に使用するMatn.pow()が簡単に書けるようになりました。


```
Math.pow(4, 2); // 16
4 ** 2 //16

let count = 3; 
count **= count; // 27
```
・・・以上です。

## まとめ

promiseやgenerator関数に関する仕様の変更はあったみたいですが、ES2016で追加された機能はこれだけみたいです。
個人的には、今後await/asyncなど実用的な機能が追加されるのでそっちのほうが楽しみです。
YesodのCSRF対策の作法

Webアプリの脆弱性としてCSRF（クロスサイトリクエストフォージェリ）というよく知られた攻撃があります。詳細はここでは割愛しますので、[IPAのページ](https://www.ipa.go.jp/security/vuln/vuln_contents/csrf.html)でご確認下さい。
Yesodは比較的堅牢で脆弱性を作り込みにくいフレームワークだと思いますが、CSRFについてもフレームワークレベルで対策が盛り込まれています。

# formでの対策
YesodのHTMLテンプレートであるhamlet内でformを扱う場合、CSRF対策となるトークンをform内のhidden項目として持つ必要があります。

が、この項目はYesodが自動生成してくれるので、プログラマはMFormを返す関数の定義で、Htmlを引数に取るようにすればいいです。

```hs
createForm :: Html -> MForm Handler (FormResult Text, Widget)
```

なお・・・MFormを返す関数は型宣言が面倒だが、Foundation.hsにこれを簡単に書くためのtype宣言があります。

```Foundation.hs
-- | A convenient synonym for creating forms.
type Form x = Html -> MForm (HandlerT App IO) (FormResult x, Widget)
```

これを使うと次のように書けます。

```hs
createForm :: Form Text
```


# Ajaxの場合
Ajaxの場合、トークンをリクエストにセットするのはプログラマの責任となります。

ただYesodは、scriptタグの中にCSRF対策のトークンを、トップレベルのスコープのvar変数として定義してくれています。
これをAjaxリクエストのヘッダにセットすれば、サーバ側でYesodがCSRFトークンをチェックしてくれます。

下記はSuperAgentを使ったAjax実行の例です。

```js
request.get(url)
    .set(csrfHeaderName, csrfToken) // Yesodが定義しているvar変数を使っている
    .end(function(err, res) {
        ...
    });
```

なおこれらのヘッダの設定を怠ると、YesodはCSRFチェックをNGとし、下記のようなHTMLを返してきます。

```html
<p>A valid CSRF token wasn&#39;t present in HTTP headers or POST parameters. Check the Yesod.Core.Handler docs of the yesod-core package for details on CSRF protection.</p>
```


# CSRF対策のトークン値を得る

あまり必要な局面が見当たらないですが、Haskellコードの中でCSRF対策のトークンの値を得ることができます。``` reqToken ```関数を使います。

```hs
token   <- getRequest >>= return . maybe "" id . reqToken
```
サーバーレスで色々作ってみて良かったこととハマったこと

# サーバーレスで色々作ってみて良かったこととハマったこと

この一年ほど、業務やプライベートでサーバーレスで色々作ってみました。
その上で良かったこと、ハマったこと、サーバーレスの使い所などを書いています。

**※ほぼAWS Lambdaの話です。**

# 何を使って作ったか
- Lambda (Java, node.js, Python)
- API Gateway
- DynamoDB
- ElastiCache (Redis)

など

# どんなものを作ったか
- モバイルアプリのバックエンド
- 短時間で完了するバッチ
- WebAPIのバックエンド
- メール配信システム
- リダイレクタ
- デプロイツール

など

# 良かったこと
## 安い
常にサーバーを起動させておく必要がなく、使った分だけお金を払えばいいので、うまく使えばサーバーを立てるより圧倒的に低コストで運用が可能です。
ただし、あまりにも実行時間が多いと、サーバーを立てた方が安上がりになるケースもあり得ます。

## 早い
例えばLambdaだとコードを書き始めてからデプロイまでの時間が早いですし、DynamoDBだとテーブルを作成してすぐにデータを投入できます。
わざわざ実行環境を用意する必要がないので、ちょっとしたツールなどを思い立ったときにすぐに作ろうという気にさせてくれます。
**「思い立ったけどめんどくさくて結局作らない」というのが劇的に減りました**。
いち開発者としてはここに一番のメリットを感じています。

## 安心
サーバーの状態を気にしなくても良いので安心です。
「xxサーバーのCPU負荷が上がってる」とか、気にしなくていいです。
そのコードを単体で実行するのに必要な性能を見積もるだけでOKです。
また、Lambdaなどでは実行環境が独立しているので、同時実行時のリソースの奪い合いなども起こりません。
もちろんハードウェア障害などで機能が停止することも(ほぼ)ありません。
サーバーのメンテナンスも不要なので、最初に挙げた「安い」というメリットにもつながります。

# ハマったこと
## (AWS Lambda)Cold startが遅い
これはWebAPIやモバイルアプリのバックエンドとして使う場合結構致命的な問題でした。
色々試してみると**Javaは特に遅く、Pythonであればそこそこ速い**ことがわかりました。
これが問題になったときはすでにJavaで作ってしまっていたので、**定期的にLambda functionを実行して温め続ける**という方法で乗り切りました。
この解決方法は後述する「VPC内のリソースへのアクセスの問題」の一部を解決してくれる副作用もありました。
現在はLambda functionを作るときはPythonを使用するようにしています。

## (AWS Lambda)外部リソースへのコネクション管理が大変
当たり前のことですが、**データベースのコネクションなどをプールしておくことができません**。
これを実現しようとすると、コネクション管理用のサーバーを立てたりする必要がありそうです。
ですので毎回コネクションを張って、使い終わったら破棄するという実装になってしまいます。

## (AWS Lambda)VPC内のリソースへのアクセスする際の諸問題
去年(2015年)の2月まではそもそもLambda functionからVPC内のリソースにアクセスすることができませんでした。
VPCにアクセスする際に仮想ネットワークインターフェースが作成されるのですが、その時間が長い。しかも一定時間アクセスがないとその仮想ネットワークインターフェースは削除されるという問題があります。
この問題については過去に記事を書いたのでそちらを参照してください。
[[AWS]LambdaからVPC内のリソースにアクセスした際のレイテンシーについて](http://qiita.com/ryosukehayashi/items/e4c12006ad9f363d4c3b)

また、VPCアクセスの設定をすると、今度はインターネットに出ていくためにnatインスタンスが必要となるという問題もあります。
[LambdaファンクションからのVPC内リソースへのアクセス](http://aws.typepad.com/aws_japan/2016/02/access-resources-in-a-vpc-from-your-lambda-functions.html)

このあたりはどんどん改善されていくものだと思います。

## ランニングコストの見積もりが難しい
基本的にはランニングコストは安いのですが、使った分だけの課金になるので、ランニングコストの見積もりが難しいです。
企業などで、正確な見積もりが必要な場合はここが導入のネックになることがあるかもしれません。

# サーバレスの使い所
Lambdaなどのコード実行環境は基本的に使い捨てなので、ステートフルに何かをしようとすると色々課題が出てきます。
逆に言うとステートレスな処理では多くのケースでサーバーレスを検討する価値はあると思います。
またバッチ処理などはサーバーレスと非常に相性が良いのではないかと思います。(Lambdaの場合は実行時間の制限が結構短いので、そこがネックですが)

そして前述のとおり、気軽にコードが書けて実行できるので、普段の業務を助けるちょっとしたツールやCIツールみたいなものにも向いていると思います。
私も以下のようなものを作成し、業務に役立てています。

- 指定した時間になったら開発用のサーバーインスタンスを起動/停止する
- デザイナーが指定のディレクトリにファイルをアップしたらCDNのキャッシュを削除する

# 最後に
改めて書いてみて、ハマったところって単純に環境に依存する部分ばかりでサーバーレス自体のデメリットって思ったより少ないんじゃないかと思いました。
実際のところサーバーレス自体がまだまだこれからのアーキテクチャなので、現状では裏側のコンテナやOS、ハードウェアの存在を完全に無視することはできない部分もありますし、正直使いにくい部分もあります。
これらが解決される頃には当たり前のアーキテクチャとして、サーバーレスという言葉自体無くなっているのかもしれません。
UEFI環境でiPXEからBitVisorを起動する

UEFI環境のiPXE (ipxe.efi) からBitVisorを起動します!

## やり方

やり方は以下の通りです。

- kernelにloadvmm.efiを指定する
- initrdにbitvisor.elfを指定する
- bootで起動する

loadvmm.efiはBitVisor起動後終了してしまいますので、続けて必要なコマンドを指定する必要があるかも知れません。

## 何が起きるのか

詳しくはiPXEのマニュアルを見てください。

- http://ipxe.org/cmd/kernel
- http://ipxe.org/cmd/initrd

マニュアルにあるように、kernelはimgselectあるいはimgloadと同じ意味で、initrdはimgfetchあるいはmoduleと同じ意味になるみたいです。どうやらUEFI環境では、どちらに指定したファイルもメモリーに転送された後、UEFIの世界のファイルシステムとして見える形になります。bootコマンドで実行されるのがkernel側のファイルっぽいです。

なので、例えばiPXEからUEFI Shellを起動して、その上でloadvmmやらその他のコマンドを実行したいなら、kernelにUEFI Shellを指定し、loadvmmその他をinitrdで繰り返し指定してあげると良いです。

## 起動例

iMacでの操作例を示します。(厳密にはUEFIではないのですがちゃんと動きます。)

![pic1.jpeg](https://qiita-image-store.s3.amazonaws.com/0/103733/666ebfbd-c62d-221a-f738-1d5898b1fda8.jpeg)

ここではいきなりshellになるように設定したiPXEをUEFI Shellから起動し、httpでBitVisor関連ファイルを持ってきて起動させています。その後UEFI Shellに戻り、UbuntuのGNU GRUBを起動させています。Ubuntuからは以下のようにBitVisorが起動していることが確認できます。

![pic2.jpeg](https://qiita-image-store.s3.amazonaws.com/0/103733/2bcae38f-7f99-d4c4-edc0-44f8c1744daf.jpeg)
vue.js 2 でお気軽ajax通信(rails)

## 概要

作成中のRailsアプリケーションで、vuejsを取り急ぎ適用してみたお話です。
お手軽だった！

- vuejsをアプリケーションに組み込む
- jsからrailsのapiを叩いて表示を行う

このあたりの内容になります。

## 私

* Rails寄りな人
* js強くない

## 目的

学習コストが少なそうなjsフレームワークをさがしてまして、なんとなくたどりついたのがvue jsでした。ゆくゆくはrails側はAPIに徹してもらって、jsでAPI経由でデータの取得/更新できる形ができれば良いなと考えていました。


- viewの変更が比較的容易にできる
- resourecesが理解できるくらいにはお手軽にできる
- 少し新しい感じのもの
- 名前がなんか良い

上記4つが選定のポイントだった気がします。


## 環境

やったことを記述する前に使用環境を示しておきます。


- mac os sierra
- vuejs-rails 2.0.5
- rails 5.0.0.1
- ruby 2.3.1


## vuejsをアプリケーションに追加

最初、webpackなどのjs環境を整えて管理しようかと思ったんですが、js界隈に疎かったためこれは何やら煩雑な予感がしました。調べていくうちに rails の場合は gem を使用すれば比較的お試しで使うにはお手軽だということがわかりその方法を取ることにしました。

Gemfileに下記を追加し `$ bundle install`

```Gemfile
gem 'vuejs-rails'
```

これを行うと


- vue 
- vue-router (シングルページアプリケーションの構築用) ※今回は利用していない
- vue-resource (ajax通信を担ってくれる)
  - こちらを合わせて呼んだほうが良いかも https://jp.vuejs.org/2016/11/03/retiring-vue-resource/ (vue-resourceの引退について)

が、もれなくついてくるのも私にとって大変好都合でした。

`application.js` に下記を追加して読み込むようにしています

```application.js
//= require vue
//= require vue-resource
```

参考: https://github.com/adambutler/vuejs-rails

あと、私は上記ページにturbolinksについて言及されている部分があったので、読み込むから外すこととしました。


## jsのリクエストを受けるための土台を作成

ここはちょっとrailsの話になります。jsでリクエストが有った際に json の形でデータを返すためにrailsの方の設定を追加していきます。

modelは既存のものが存在するので、すごくざっくりコントローラとルーティングを設定します。

ルーティング

```routes.rb
get 'api_test',          to: 'pages#api_test'
```

コントローラ

```pages_controller.rb
    def api_test
      params = Page.where(site_id: @site.id).all # 複数のPageを想定
      render json: params
    end
```

Pageモデルからデータを持ってきてjsonとしてそのまま渡してしまいます。


## js側で受け付けられるようにする

ざっくりといろんなサイトを参考にしながら作成した

html側(haml) はこんな感じで用意してid=helloで取得したデータを利用し
v-forで複数あるデータをテーブルに押し流す感じを想定しています。

```page.html.haml
    #hello
       %table
       %tr{ "v-for" => "page in pages"}
         %td
           %a{ href: "{{page.url}}" }
             {{page.name}}
         %td
           {{page.explaination}}
```

それを可能にするためにjs側で書いたのがこちらです。
ajaxで取得して受け渡し用のところに 複数のデータを順番に追加していきます。

```page.js
    window.onload = function () {
      var app = new Vue({
        el: '#hello',
        data: { pages: [] },
        created: function(){
          this.$http.get('/api_test').then(function(response) {
            // success
            for(var i = 0; i < response.body.length; i++) {
              this.pages.push(response.body[i]);
            }
          }, function() {
            // error
          });
        }
      });
    }
```
これだけで終了です。
もともとデータをもっていたものを表示させることができました。

思っていたよりも早く手軽にできてしまったので、記事が薄いですが、
jsフレームワーク使ったことない人はvuejsから入るの割と良いような気がします。

## 終わりに

angular1を少し触っていたのでふんわりjsのajaxとかが頭にあったので、vuejsも割とすんなりだったような気がします。
個人的にはangularだったらあの便利なやつがあったなー。みたいなものが時々なかったりしたので、これの他にunderscore.jsを追加したりしました。
jsのフレームワークはフルスタックなものから、view特化なものまで色々あるようなので自分にあったものを探してもらって「とりあえずフォームのバインドだけでもしてみたい」とかならvuejs使って皆よと思う次第です。

明日は @kaorun343 さんです。
とっさのConfluence-情報を素早く見つける方法-

# はじめに
この投稿は Atlassian Advent Calendar 2016 の2日目です。

Confluenceに情報がたくさん集まってくると、自分の必要な情報にいちはやくたどりつけるかが重要になってくると思います。通常は検索して情報をみつけるということになると思いますが、ここでは検索以外で情報を見つける、もしくは気づく方法を書いてみたいと思います。

# さっき見てたページに素早くアクセス

「ブラウザを間違えて閉じてしまった、さっき見てたページどれだっけな」
なんてことあると思います。
さらには会議などでさっきまで見てたConfluenceのページがなかなか表示できないと、探す時間 x 参加してる人数分の時間が無駄になります。
とはいえ作ったページをいちいちブックマークもしくはコンフルのお気に入りにいれるのは面倒です。
そんな時はコンフル開いている画面で **gr** と打ってみましょう。
下記のような画面が出てきます。
見てわかる通り、最近自分の見たページが見た順序でリストされています。
しかもフィルターもあるので、わずかでもタイトルを覚えていればさらに素早くアクセスできます。
これはユーザ単位で保持されている情報なので、異なるデバイスで共通の情報です。
![Capture 2016-12-04 at 3.33.27.png](https://qiita-image-store.s3.amazonaws.com/0/103246/e20b0d7e-4de3-e615-3945-9b6ce6264c5e.png)

grじゃなく画面右上のメニューにも「最近の表示履歴」という処からも同じことができます。

# ドキュメントの作成状況をいち早く把握する

例えば以下のようなシチュエーション。
上司「Aくん、こういう資料つくってくれる」
Aくん「わかりました」
~ 3日後 ~
Aくん「できました。確認お願いします」
上司「意図してたものとちがうなあ、やり直しだ。。」

お願いしたものを完成までまたないと見れないというのは、スタートの認識がずれてたりすると悲惨ですよね。
こういうときコンフルでは **ネットワーク機能** を使うと、認識のずれがいち早くきづくことができるかもしれません。
下記がコンフルのネットワーク機能の画面です。簡単に言うとユーザをフォローしておくと、その人のアクティビティがタイムラインで表示されます。
![Capture 2016-12-04 at 22.01.36.png](https://qiita-image-store.s3.amazonaws.com/0/103246/0433b66c-2b94-0f97-141d-a0e14c8c67c1.png)

先ほどのシチュエーションにもどると上司はAくんをフォローしておけば、お願いしたドキュメントのWIP(Work In Progress)がわかるわけです。それを見れば自分のお願いしたものと違うものになっていれば、いち早く指摘、軌道修正することができます。
3日の無駄が1日で済むかもしれません。

副次的な効果としては、その人の作業する時間帯や、過程をうかがい知ることでドキュメントの作成時のくせ、さらにはその人の仕事の仕方みたいなものもわかったりするかもしれません。
デメリットとしては、仕掛中のものにあれこれ言うと嫌がられするリスクがあります。

このネットワーク機能、フォローされるのをブロックすることはできないです。企業内で使うのにブロックする機能あったらまずいとおもいますが。。

#みつけたドキュメントを素早く共有

こんなシチュエーションのとき
Aさん「そういえばConfluenceにhogehogeに関する情報あったよね」
Bさん「ありましたね、どこでしたっけ」
Cさん「あ、ありましたよ」

ここで見つけたページをどうやって共有しますか。

口頭でpageIDをつたえますか。

メール送りますか。

Confluenceには共有機能があります。画面右上の **共有** というところから使えます。下記の通り、confluenceのユーザー、グループなどに送信できます。
![Capture 2016-12-04 at 21.49.08.png](https://qiita-image-store.s3.amazonaws.com/0/103246/ea1855ed-9727-ce4f-f3de-cbb7f3d13e7c.png)

メールでもくるのですが、ヘッダーのワークボックスにpush通知されます。
![Capture 2016-12-04 at 21.53.08.png](https://qiita-image-store.s3.amazonaws.com/0/103246/40283e0c-e2bf-b43a-ada5-f86072321130.png)

ワークボックスを選択するとページへのリンクがあります。

![Capture 2016-12-04 at 21.54.13.png](https://qiita-image-store.s3.amazonaws.com/0/103246/b956dab6-c214-9dd3-b7bc-528dd86bca19.png)

これで素早くアクセスできますね。
といいつつ、hipchatのようなツールの方が共有は簡単かもしれません。。

以上、3つほどConfluenceの機能を使用した情報の見つけ方でした。
個人的にはgrのショートカットは本当によく使います。
是非お試しください。
学生目線でXamarinを使うことのメリット・デメリットについて

この記事は、[[学生さん・初心者さん大歓迎！]Xamarin Advent Calendar 2016](http://qiita.com/advent-calendar/2016/xamarin-student) の2日目の記事です。

今年の2月に買収され、4月には無償化の発表があり、「Xamarinはいいぞ」の掛け声とともにある一定度の知名度を獲得したXamarinですが、実際に触ってみていい感じに書いている方もいれば、うーんとなった方も多いのではないでしょうか。

私自身まだ学生の身ですが、学生がXamarinを使うことのメリット・デメリットを考えて色々書いていきたいと思います。

## 言語面

Xamarinで主に使用されるのはC#とXAMLです。一方、iOSとAndroidをネイティブで書こうとした際はSwiftとJavaになるでしょう。

この2つの言語を初めて触る人であれば、両方同時に習得するよりはC#一本だけの書き方を覚えるほうが楽ではあります。

C#が出来るようになることのメリットとしては、UnityやASP.NETといったフレームワークへの参入がしやすくなるといった点です。

また、VisualStudioをメインで使用するため、VSへの知識が増えるという点も大きいと思います。

一方、デメリットとしては、Javaなどに比べるとC#の使用頻度は低いという点です。

Swiftと比べても、SwiftはiOSアプリの開発がメイン用途のため使用用途がJavaやC#に比べ限定はされますが、それでも勢力を伸ばしつつあり、言語自身の人気としても抜かれる可能性が高くあります。

## プラットフォームとして

Xamarinの推しのポイントである「複数プラットフォームを同一環境で、コードを共通化できる」 という点について考えてみます。

Xamarin Nativeであれば、UI部分などを元のネイティブ環境と同じように（AndroidのレイアウトXMLやiOSのストーリーボード）作ることができ、ロジックの部分やモデルの部分、データベース・アクセスなどの部分を共通化できます。

Xamarin.Formsであれば、UI部分まで共通化させることが可能です。

メリットとしては、このように一度書いたものを別言語で再度実装し直す必要がなくなるということがあります。

特に、JavaとSwiftに限った面で言えば言語仕様の違いとしてnull非許容があるかといった点でModel自身にNull非許容であるというような制約をJavaでは加えられなくなります。

デメリットとしては、確かに共通化できる部分はできますが、最終的にプラットフォーム依存のコードなどは各OSごとの実装となってしまう箇所が出てきてしまいます。（実際Xamarinに触れた方ならわかるかもしれません・・・）

また、各プラットフォームごとに作られている様々なOSSライブラリが基本的に使えなくなってしまうので、ライブラリによって便利になっていた部分を自分自身で実装し直す、いわゆる車輪の再発明的なことをやらざるを得ない可能性が出てきてしまいます。

## 学習コストとして

Xamarinを使用した開発において必要なスキルとしては、

- C#(XAML)への知識
- Xamarin自体のAPIの知識
- .NET系への知識
- 各プラットフォームの最低限の知識（エラー解決方法や内部ロジックなど）
- 各プラットフォームのAPI(Xamarin Nativeはmust、FormsはOptional)

が必要だと個人的には感じています。

結局のところ、下２つのような各プラットフォームへの知識がどうしても必要になってしまうので、最終的な学習コストは非常に高くなってしまうというのが自分のイメージです。

今までプログラミングやアプリ開発にあまり縁のなかった人がいきなりこの5つを進めようとすると、非常に厳しいかとは思います。

しかし、逆に考えると一気に両プラットフォームの知識を身につけることができ、+αでC#/.NETへの知識がついてくると考えれば学生くらいの知識の吸収力であれば逆に効率がよくなるのかなとも思います。

## さいごに

私自身は元からマルチプラットフォームというのが大好きで、何個かモバイルアプリ開発のプラットフォームは見てみましたが、俗に言うハイブリッドアプリは個人的になんか違うという面が強くありました。

しかし、2月にXamarinを初めて聞き、触ってみたところ、まさしく自分が求めている形での開発ができると思いました。
（元からAndroidをやっていたというのもすんなり入りやすかった点かもしれません。）

もちろん万人にフィットするとは考えていないので、ぜひ一度触ってみて、こういうものかと見てほしいと思っています。

自分自身の考えとしては、学生といういろいろ手を出しやすい期間だからこそ、触ってほしいと思っています。
[1day1lang AdventCalender] day1 C言語

「AdventCalenderにあやかって1日1言語触ってみよう」という地獄の24日間企画。
実行環境を整えるところから、できるところまで。

開発環境はVirtualBox上にUbuntuを立てた。バージョンは以下。

```bash
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04 LTS"
```

初日の今日はC言語。
はじめて使ったプログラム言語なので、かなり懐かしい。

#C言語について

>C言語は、AT&T ベル研究所のケン・トンプソンが開発したB言語の改良として誕生した

ということで名前が「B」の次のアルファベットの「C」。
ちなみに、A言語もちゃんとあってAPLと呼ばれている。
これは「プログラミング言語」(a programming language) の略で、Aは冠詞のA。
なんともまぎらわしい…。
A言語とB言語に継承関係はなく、B言語は継承元のBCPLを略した名前。

#環境構築
##コンパイラの確認
gccがインストールされているか確認。

```bash
$ gcc -v
gcc version 5.3.1 20160413
```
実行環境整える必要なく、元からインストール済み。

##Hello world

```c:helloworld.c
#include <stdio.h>

int main(void) {
    printf("Hello World!\n");
    return 0;
}
```

helloworld.cをコンパイル。

```bash
$ gcc helloworld.c
```

出力ファイル名を `-o` で名前を指定していないので、 a.out となった。
Assembler Output の略。

```bash
$ ./a.out 
Hello World!
```
#ツリー描画プログラム

24個のアスタリスクでツリーを描画する宿題的プログラミング。
学校の宿題で三角形とか書いてた。

```c:tree.c
#include <stdio.h>

int main(void) {

    const char ASTER[] = "* ";
    const char SPACE[] = " ";
    const int  EVE   = 24;
    
    int sumAster = 0;
    int step = 0;
    int i,j;
    int trnk;    //幹

    // 行数を算出
    while(sumAster <= EVE) {
        step ++;
        sumAster += step;
    }

    // 正三角形からはみ出た数は幹として使用する
    trnk = EVE - (sumAster - step);
    
    // ツリー描画
    for (i = 1; i <= step; i++){
    	if (i < step) {
    		// 葉
    	    for (j = step; j > i; j--) printf(SPACE);
    	    for (j = 1; j <= i; j++)   printf(ASTER);
    	} else {
    		// 幹
    		for (j = i - trnk; j >= 1; j--) printf(SPACE);
    		for (j = 1; j <= trnk; j++)     printf(ASTER);
    	}
        printf("/n");
    }

    return 0;
}
```
実行

```bash
$ gcc tree.c -o tree.out
$ ./tree.out 
      * 
     * * 
    * * * 
   * * * * 
  * * * * * 
 * * * * * * 
    * * * 
```

クリスマスツリー完成。

#おわり
初日から時間ギリギリの投稿…。
久々にC言語触って、「あったあった `stdio.h` !」という妙なテンションなった。

明日はたぶんC++
主キーの有無によりinsertとupdateを切り替えるにはmergeを活用する


データベースアクセス層(いわゆるDAO)からとあるテーブルの行の更新情報がDBに引き渡されるとします。そのテーブルは主キーによって行が一意に特定されるため、渡された更新情報に含まれる主キーの有無によって、更新と挿入を切り替えます。いいかえれば__「主キーがテーブルに存在するときは`update`、存在しないときは`insert`」__ということをしたいわけです。たとえば疑似コードで書けば次のようになります。

```
if (primary_key in table.primary_keys ) then
    update table 
else 
    insert table
end
```

かえってわかりにくいような……。それはさておき、以上のような要件を達成するには`merge`を利用します。

```sql
-- テーブル「tbl」を作成する。
create table tbl (
	id varchar(10) not null primary key,
	value varchar(10)
);

-- 初期化: テーブルの内容を作成する。
insert into tbl values
	('AAA', 'A'),
	('BBB', 'B'),
	('CCC', 'C');

-- 初期状態を確認しておく。
select * from tbl;

-- updateのサンプル: id = 'AAA'が存在するときはupdate/ないときはinsertしたい。
merge into tbl
using (select 'AAA' as id from sysibm.sysdummy1) as condition
on tbl.id = condition.id
when matched then
	update set value = 'updated A'
when not matched then
	insert (id, value) values ('AAA', 'inserted A');

-- insertのサンプル: id = 'DDD'が存在するときはupdate/ないときはinsertしたい。
merge into tbl
using (select 'DDD' as id from sysibm.sysdummy1) as condition
on tbl.id = condition.id
when matched then
	update set value = 'updated D'
when not matched then
	insert (id, value) values ('DDD', 'inserted D');

-- id = 'AAA'が更新され、id = 'DDD'が挿入されていることを確認する。
select * from tbl;

/*
=== 1回目のselect文の結果 ===

select * from tbl

ID         VALUE
---------- ----------
AAA        A
BBB        B
CCC        C

  3 レコードが選択されました。
 
 
 === 2回目のselect文の結果 ===

select * from tbl

ID         VALUE
---------- ----------
AAA        updated A
BBB        B
CCC        C
DDD        inserted D

  4 レコードが選択されました。

*/
```

`merge`を利用すると「主キーがテーブルに存在するときはその行を更新/`update`、存在しないときは挿入/`insert`」を実現できることが上記の例から確認できました。

ポイントとしては`using`節の使い方でしょうか。__`using`節ではテーブルを指定する必要があるので、上記の例ではダミー表を活用することにより、疑似的にテーブルを実現しています。__

なお上記の例はDB2を利用しているため、ダミーのテーブルの名前が`sysibm.sysdummy1`になっています。DB2以外を利用する場合は別のダミー表名を指定するなり、`from`節を省略するなりして、適宜読み替えてください。
xcopyの謎

# バグの原因が不明、、

業務でxcopyコマンドで作業を行っていたところ、下記のバグが。
ファイル構成はこんな感じ。

```
C:.
├─aaa
│  │  samename.txt
│  │
│  └─directory
│          samename.txt
│
└─bbb
    │  samename.txt
    │
    └─directory
            samename.txt
```

テキストの内容は以下とする。

* aaa/samename.txt

> aaaの直下のテキスト

* aaa/directory/samename.txt

> aaa/directory配下のテキスト

* bbb/samename.txt

> bbbの直下のテキスト

* bbb/directory/samename.txt

> bbb/directory配下のテキスト


で、下記コマンドでコピーを実行
フルパスで階層の浅いファイルを指定してコピーを試みる。

> echo y|xcopy C:\Users\~~\aaa\samename.txt C:\Users\~~\bbb\samename.txt /E /Y

すると結果が以下

> C:\Users\~\aaa\samename.txt
C:\Users\~\aaa\directory\samename.txt
2 個のファイルをコピーしました

あれ、、一個だけコピーしたいのに、、
ファイルを見ると

* bbb/samename.txt

> aaa/directory配下のテキスト


しかも階層の深いほうの内容がコピーされている、、、
仕様とかを調べようとしたけどわからん、、、助けて偉い人、、、
【VBA】TTLマクロを起動するときのノウハウ


ExcelのVBAから、teratemを起動したり、TTLマクロを実行することができる。
下記のような感じ。

````コマンド
Shell ttermpro.exe test.ttl
````

ある時、TTLファイル以外にも引数を与える必要が出てきたので、下記のような感じに実行してみた。

````コマンド
Shell ttermpro.exe test.ttl <引数2>
````

ただ、コマンドは正常に終了するけども、デバッグしてみたところ、引数2が渡されていない。。。

いろいろ調べてみたところ、ttermpro.exe はTTLファイル以外の引数を渡しても認識されないみたい。
TTLファイル以外の引数も認識させたいのであれば、ttpmacro.exe を使うしかないみたい。

つまり、こんな感じ。

````コマンド
Shell ttpmacro.exe test.ttl <引数2>
````

なんでなのかは、別途調査してみようと思う。。。。。
【ほぼメモ】flexbox系のemmetチートシート

フレボを実務でガッツリ使い出したのでまとめました。（ほぼ俺専用）

``` emmet.css

.flexbox {
  /*d:f*/
  display:flex;

  /*jc*/
  justify-content: ;

  /*jc:c*/
  justify-content: center;

  /*jc:fs*/
  justify-content: flex-start;

  /*jc:sb*/
  justify-content: space-between;

  /*jc:sa*/
  justify-content: space-around;

  /*fxf*/
  flex-flow:;

  /*ai*/
  align-items:;

  /*ai:b*/
  align-items:baseline;

  /*ai:c*/
  align-items:center;

  /*ai:fe*/
  align-items:flex-end;

  /*ai:fs*/
  align-items:flex-start;

  /*ai:s*/
  align-items:stretch;
}

```

flex-flowのプロパティまで書けたら楽だったのに…（flex-directionとflex-wrapで分けて書けよとそうですか）

参考
http://docs.emmet.io/cheat-sheet/
sbtでjarファイルを作る

#環境

sbt 0.13.13

#手順

[sbt-assembly](https://github.com/sbt/sbt-assembly)を使います。
下記を記載したファイルをprojectフォルダ配下に配置。

```sbt:project/assembly.sbt
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3")
```

project配下であればsbtファイルの名前は自由。
この状態でsbtコンソールからassemblyコマンドを実行すれば、jarファイルが生成されます。

#jarファイル名の指定

標準だとファイル名は"【nameキーの値】-assembly-【versionキーの値】.jar"になる模様。
jarファイル名を変更するには、build.sbtに以下を記載します。

```sbt:build.sbt
assemblyJarName := "【ファイル名】"
```

#jarファイル出力先の指定

標準だと出力先はtarget/scala.x.xx配下になります。
出力先を変更するには、assemblyOutputPathを指定すれば良い・・・と思いきや、指定しても動作が変わらない？
assemblyJarNameの値で相対パスを指定することが可能なので、それで大抵の場合は解決できるかと思われます。
モジュールを条件で切り替えて読み込む


断捨離。

`use` の時に与える `LIST` の一番目で、読み込むライブラリを変更する方法。


### 経緯

ある完成されたライブラリに、全体に影響する形で条件を増やして、出力を出す様にしてくれ。と言われた。で、複数個の関数に引数を追加して、条件文を追加して、、、ってのがいやだったから、ラッパモジュール[^1]の引数に、モジュール名を与える事で分岐するようにした。それの簡略版メモ。

[^1]: 共通関数を設置するモジュールでもある。

## コード
### 元

例として古いタイプの `Exporter` の使い方で記載している。

```
$ cat Legacy.pm
package Legacy;
use Exporter ;
use vars  qw( @ISA @EXPORT ) ;
use subs qw( somefunc()) ;
@ISA    = qw ( Exporter ) ;
@EXPORT = qw( somefunc ) ;
sub somefunc  { print "\@package Legacy.\n" ; }
1;
$ perl -MLegacy -e somefunc
@package Legacy.
```


### ラッパ


```perl:P.pm
package P;
use strict ;
use warnings ;
use Exporter ;
sub import {
    no strict 'refs' ;
    eval "require $_[1];" ;
    *{"${_[1]}::export"} = \&Exporter::export ;    # Bar の方式では必須
    #return $_[1]->export_to_level( 1, @_[1..$#_]) # Bar の方式ではエラー
    return Exporter::export_to_level($_[1], 1, @_[1..$#_]) ;
}
1;
```



### 条件分岐用

例として別の `Exporter` の使い方で記載している。

```perl:Bar.pm
package Bar;
use Exporter 'import' ;
our @EXPORT = qw( somefunc) ;
sub somefunc { print "\@package Bar.\n" ; }
1;
```

## 実行

```shell-session:
$ ls
Bar.pm Legacy.pm P.pm
$ perl -MP=Legacy -e somefunc  # perl -e 'use P qw(Legacy); somefunc'
@package Legacy.
$ perl -MP=Bar -e somefunc
@package Bar.
$ perl -e 'sub somefunc ; require P ; P->import( $ARGV[0] || q{Legacy} )  ; somefunc;' Bar
@package Bar.
```

最後のコマンドラインは、`perl` スクリプト内で動的に利用するなら、って例。先行宣言をするのが面倒なら普通に `&somefunc` で呼ぶ。


## memo

### 変更ないファンクションもあるよ

って場合は、もちろん `P` に埋め込む。

```P.pm
package P;
use Exporter  ;
our @EXPORT = qw( comfunc ) ;
sub import {
    no strict 'refs' ;
    eval "require $_[1];" ;
    *{"${_[0]}::export"} = *{"${_[1]}::export"} = \&Exporter::export ;
    Exporter::export_to_level($_[0], 1, @EXPORT ) ;
    return Exporter::export_to_level($_[1], 1, @_[1..$#_] ) ;
}
sub comfunc { print "\@package P.\n" }
1;
```

```shell-session:
$ perl -MP=Bar -e 'somefunc ; comfunc'
@package Bar.
@package P.
```

### 変更ないファンクションもあるよ、別解

`Legacy` に全てを書いて、`Bar` で `Legacy` 呼んで、動的に `function` を書いてしまう方法もある[^2]。

[^2]: 例のコードは `use Bar` では駄目で、 `use P qw(Bar)` でのみ動くコードだけど。

```perl:Bar.pm
package Bar;
use Exporter 'import' ;
use Legacy ;
our @EXPORT = @Legacy::EXPORT;
no strict 'refs' ;
no warnings 'redefine' ;
sub import {
    for my $f ( @Legacy::EXPORT){
        *{"Bar::$f"} = \&{"Legacy::$f"} ;
    }
}

sub somefunc { print "\@package Bar.\n" ; }

1;
```

### EXPORT_OK の場合は？

`@Legacy::EXPORT`, `@EXPORT` の `EXPORT` を `EXPORT_OK` に置換して、

```
$ perl -MP=Bar,somefunc -e somefunc
$ perl -e 'sub somefunc ; require P ; P->import( ($ARGV[0] || q{Legacy} ), "somefunc" )  ; somefunc;' Bar
```

などとする。
[Swifty]プロトコル指向プログラミング

<p>今回は、出だしは少し辛口。</p>

<p>MacOS時代、クラスライブラリMacAppを使用したプログラミングの手法として、オブジェクト・プログラミングというのがあった。これは、利用側が、必ずしもオブジェクト指向プログラミングをする必要がない。オブジェクト指向で実装されたライブラリを利用すればいいということだったと思う。</p>

<p>この考えは、NeXTstepでもあったと思っていて、継承以外のクラスを拡張する方法としてデリゲートが用意されていたり、InterfaceBuilderはクラスでなく、インスタンスを生成するところなどがそうではないだろうか？</p>

<p>自分はたいした職歴でないが、過去を思い出すと、継承を多用したプロジェクトは、必ず、スパゲッティになっていた。何が問題なのかなとボンヤリと思うと、継承をコードの共通化として利用し、オブジェクトとしての構成がよくなかったのではないか？では、そこを頑張ればいいのかというと頑張ると変な方向に行ってしまうような。</p>

<p>なかなか、この考えに考え抜いたスパゲティを生産される方は、その主張がパッと聞くと正論のように思われ、止めることはできず。逆に止めようとすると、論争になり、ますます、泥沼にはまっていたよな〜。</p>

<p>恐ろしいのは、この設計論争は、何もモノを生み出さない。趣味ですね。</p>

<p>Swiftでclass出なくstructを。継承でなくプロトコルを勧めているのも、多くの方々が、このスパゲティ・クラスに疲れ果ててしまったからかな思う。</p>

<p>イカンイカン。脱線しているので本題に戻る。</p>

<p>今回取り上げるのはWWDC2015のセッション『<a href="https://developer.apple.com/videos/play/wwdc2015/408/">Protocol-Oriented Programming in Swift</a>』。</p>

<p>課題を3つ挙げている。</p>

<ul>
<li>Implicit Sharing</li>
<li>Inheritance All Up In Your Business</li>
<li>Lost Type Relationships</li>
</ul>

<p>一つ目は、リファレンス型のことを言っているようで、値を変えると、他で所有しているところで驚くという内容だ。ただ、これは、以前も説明した通りモジュール化の問題で、Model（Dataコントローラ）を用意するとか、必要な複製は行うとかすれば問題ないと考えている。</p>

<p>二つ目は、継承の問題で、パッと思いついたのは、親でreadonlyにしたが、一部の子でwriteしたくなり、そのためにそれ専用のメソッドを用意したり、逃げで苦労するということか。継承しすぎ、Baseクラスやめたら、ですね。</p>

<p>最後は型の問題で、親子で方がうまくいかず、他の子のことを考慮したり、親で子を考慮したりということか。</p>

<p>ということで、推奨されたのが以下の7つ。</p>

<ul>
<li>Supports value types (and classes)</li>
<li>Supports static type releationships (and dynamic dispatch)</li>
<li>Non-monolithic</li>
<li>Supports retroactive modeling</li>
<li>Doesn't impose instance data on models</li>
<li>Doesn't impose initialization burdens on models</li>
<li>Makes clear what to implement</li>
</ul>

<p>詳細は割愛するが、それでプロトコル指向プログラミングということだが、何とか指向というと、スパゲティの悪夢が蘇って腰が引けてしまうが、まずは、自称オブジェクト指向プログラミングを制限するというのは、いいかも。</p>

<p>これで、悲劇が繰り返さないことを願う。</p>

ソースコード
GitHubからどうぞ。<br />
<a href="https://github.com/murakami/workbook/tree/master/ios/Hand">https://github.com/murakami/workbook/tree/master/ios/Hand</a> - GitHub<br />

関連情報
<a href="https://realm.io/jp/news/tryswift-daniel-steinberg-blending-cultures/">文化を調和させる</a><br />

【Cocoa練習帳】
<a href="http://www.bitz.co.jp/weblog/">http://www.bitz.co.jp/weblog/</a><br />
<a href="http://ameblo.jp/bitz/">http://ameblo.jp/bitz/</a>（ミラー・サイト）<br />
<a href="https://t.co/6P3h2jtbRk</a>note<br />
2016年も終わりです。


#　はじめに
2003年にWeb開発の現場から足を洗い、2016年にまたWebコーダーとして戻ってまいりました。
うーん、2013年くらいに職業訓練を受けて多少わかってはいたけど本当に色々変わりましたね。
※当時は講師に立っていた新人エンジニア君に「代わりに講師やって！」って泣きつかれたので授業の程度はお察し
まず、専門用語が増えすぎていてよくわかりませんね。
よーわからんカタカナ言葉を「うんうん」と頷きながらメモを取り、心の中で「日本語おなしゃす！」って叫んでますよ。

しかしながら、開発環境はよくなりましたね！
中の人の頭の固くなったところを柔らかくして新しいものを埋め込んでいく作業が大変すぎるので色々なサービスがありがたいです。

ようやく自分の仕事に必要な書籍も揃ってきたので、インプットしつつのアウトプットを始めていきたいと思います。
Web上の情報もブックマークでは足らなくなってきたのでそちらの整理もしないとならないですね・・・。
Webサービスのほうは現在まだ吟味中なので、登録してみたこちらでアウトプットできたらよいなぁ、と。

いつもは見ているだけなので使い方とか全くわかりませんが、試行錯誤してやっていけばなんとかなるかな？

とりあえず文章投稿のTESTはこの辺で。
Magento2.1のマイナーアップデート手順（CLI）

ComposrインストールでセットアップしたMagento2をCLIでマイナーアップデートした時の手順メモ。

基本公式Doc[「Command-line upgrade」](http://devdocs.magento.com/guides/v2.1/comp-mgr/cli/cli-upgrade.html)と同じ。

## 対象バージョン
Magento 2.1.2 => 2.1.3（Composerインストール）

## サマリー
- composerで新バージョンを指定してアップデート
- Magento2のmoduleを再セットアップ
- キャッシュ類をクリア

## コマンド
```:magento/root/

# 公式ドキュメント表記の手順
composer require magento/product-community-edition 2.1.3 --no-update
composer update
magento setup:upgrade

# 以下はオマケと定型リフレッシュ

# bin/magentoのパーミッションが戻ってしまったので775に再設定
chmod 775 bin/magento

# モジュール再コンパイル
magento setup:di:compile

# インデックス・キャッシュ再生成
magento indexer:reindex
magento cache:flush

```
VSCodeでTypescriptの型定義ファイルを適用

VSCodeにtypescriptの型定義を適用したときのメモ

## 環境

* windows10
* vscode1.8

フォルダ構成

```
project
  + .vscode
  + src
    - sample.ts
  - tsconfig.json
  - node_modules
    + @types
```

## node.jsのインストール

[Node.js](https://nodejs.org/en/)から6.9.2(LTS)をダウンロードしてインストール。

## typescriptのインストール

```bash
npm install -g typescript
```

古くなるとVSCodeが警告を出してくれる

## 型定義ファイルのインストール

vscodeで開いているプロジェクトのルートフォルダにインストールする。
以下はreactの型定義ファイルの設定例

```
npm install @types/react
```

## tsconfigの設定

es6の文法を使いたいのでes6をtrueに。
vscodeで開いているプロジェクトのルートフォルダに配置する。

```json:tsconfig.json
{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es6",
        "noImplicitAny": false,
        "sourceMap": false,
        "jsx": "react",
        "allowJs":true
    }
}
```

## 参考

[Editing Typescript][*3]
[typescript doc][*1]
[特別なツール不要！ TypeScript 2.0時代の型定義ファイルの取り扱い方][*2]

[*1]:https://www.typescriptlang.org/docs/handbook/compiler-options.html
[*2]:http://qiita.com/tonkotsuboy_com/items/634b0921b6170cf56813
[*3]:https://code.visualstudio.com/Docs/languages/typescript
スマホブラウザから Firebase Realtime DB の WebAPI 接続に時間がかかる

スマートフォンのブラウザから Firebase Realtime DB への接続にやたらと時間がかかる。特に重いデータ等ないはずなのに、10秒くらいかかる。PCだと問題ないのに、スマートフォンだけ遅い。Google Chrome のスマートフォン・エミュレーションでも遅いので、回線やスペックの問題ではなさそう。

よく見てみるとスマートフォンだけ以下のログがコンソール出力されていた。

> iframe.js:316  [  0.483s] [firebase-auth] Info: The current domain is not authorized for OAuth operations. This will prevent signInWithPopup, signInWithRedirect, linkWithPopup and linkWithRedirect from working. Add your domain (******.jp) to the OAuth redirect domains list in the Firebase console -> Auth section -> Sign in method tab.

Authentication 使っていないので関係ないかなと思ったものの、スマートフォンだけこれが出ているので、もしかして……と思って試しに書かれている通り設定してみたら、PCと同じ速度で接続できるようになった。

なんでやねん。
ParentNode.childrenをfor...ofループするときの注意点

* `for (const el of parentElement.children)` は動かないものと考える
    * 原因と対策について解説


## ES2015 おさらい

### for...of ループ

* **iterable** なオブジェクトを1件ずつ処理するためのループ構文
    * `for each` 的なやつ

```javascript
var elements = document.querySelectorAll('.item');

// for...in だと hasOwnProperty とかややこしい
for (const i in elements) {
  if (elements.hasOwnProperty(i)) {
    const el = elements[i];

    ...
  }
}

// forEach() メソッドは Array にしかない
//elements.forEach((el) => { ... });
Array.prototype.forEach.call(elements, (el) => {
  ...
});

// そこで for...of
for (const el of elements) {
  ...
}
```

### iterable

* `for...of` 文に渡すことができるオブジェクトのプロトコル (インターフェイスのようなもの)
    * `String`, `Array`, `Map`, `Set` などのループできそうなオブジェクトが該当
    * `[Symbol.iterator]` メソッドを呼び出すと **iterator** オブジェクトが取得できる

```javascript
const items = ['one', 'two', 'three'];
const iter = items[Symbol.iterator]();

console.log(iter.next());  // { value: "one", done: false }
console.log(iter.next());  // { value: "two", done: false }
console.log(iter.next());  // { value: "three", done: false }
console.log(iter.next());  // { value: undefined, done: true }
```


## NodeList と HTMLCollection

* `document.querySelectorAll()` などの戻り値は `NodeList` オブジェクト
* `ParentElement.children` の戻り値は `HTMLCollection` オブジェクト
* どちらも似たような、DOM要素の配列
* `NodeList` は iterable だが、 `HTMLCollection` は **iterable ではない**
    * たとえば下記のコードを Babel with babel-polyfill で　ES2015 にトランスパイルして動作させた場合、 `HTMLCollection` に `[Symbol.iterator]()` がないため **エラーになる**

```javascript
// 仕様上は動作しない
// (ただ Google Chrome だと HTMLCollection も iterable 化されてるので動く)
for (const el of parentElement.children) {
  ...
}
```


### 対策

* Array に変換するのが手っ取り早い

```javascript
// とりあえず Array に変換
for (const el of Array.from(parentElement.children)) {
  ...
}

// だったら forEach でもいいや感 key/value つかえるメリットはある
Array.from(parentElement.children).forEach((el) => {
  ...
});
```

* どうしてもやりたいなら `HTMLCollection` のプロトタイプを書き換えて iterable に

```javascript
if (HTMLCollection.prototype[Symbol.iterator] === undefined) {
  HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
}
```


まあ DOM を直でさわらない時代だし、雑学的に知っておくとよいかもくらいな話です。


## 参考文献

* [ParentNode.children - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/API/ParentNode/children)
* [for...of - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for...of)
* [反復処理プロトコル - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Iteration_protocols)
* [3.2.10.1. Interface NodeList | DOM Standard](https://dom.spec.whatwg.org/#interface-nodelist)
* [3.2.10.2. Interface HTMLCollection | DOM Standard](https://dom.spec.whatwg.org/#interface-htmlcollection)
* [Iterable DOM collections | zloirock/core-js](https://github.com/zloirock/core-js#iterable-dom-collections)
JavaScriptのスニペット

第一引数で与えた関数がtrueを返すまで、
第二引数の関数の実行を待つ関数。

```js
function(func, callback, context){
 var args = _.toArray(arguments).slice(3);
 var timer = null;
 var ifunc = function(){
  if(func.apply(context, args)){
   if(!context){
    context = null;
   }
   if(timer){
    clearInterval(timer);
   }
   callback.apply(context, args);
   return true;
  }
  return false;
 };
 if(!ifunc()){
  timer = setInterval(ifunc, 50);
 }
 ifunc = null;
 return timer;
}
```

こーゆーのもうあるとか、こうしたほうがいいとかあったら教えてほしいなぁ
子育てから始まるライフスタイル変革

## はじめまして
過去にQiitaで書いた記事は100個ほどありましたが、今回は技術ネタではない"子育て"ネタです。
私は4歳と1歳の男児を子育て中の2児の父親です。
私はSEでほぼほぼ自席に座ってデスクワークしていますが、妻の職業は看護師なので座る暇もろくにないの肉体労働をしています。、

## 子どもが生まれて変わったこと
* もっと大きい家が必要になった
 * 2LDKのマンションに住んでいましたが、子どもの行動範囲や収納など考えて、家を購入することにしました
* 経済的に少し苦しくはなった
 * 手当などもありますが、いつまであるかわからないものなので全額貯金に回して子どもの進学の軍資金になればいいなと
 * おむつ代はいうほど高くないと思っていましたが、服やたべもの、ときにはおもちゃや○○ショーなど足していくといいお値段になります

## ライフスタイルはどう変わった？
* 19時(夕食時)ですでに眠さMAX
 * 子どもが小さいときは夜も寝れない＆朝早い
 * 子どもが大きくなって(1歳over)保育園に行き始めると保育園の送迎＆用意が追加されますます育児中心の生活に
* 私の最近の１日
 * 06:30 起床 - 着替え - 朝食
 * 07:30 保育園の準備
     * 水筒をオールシーズン持参
     * 白米をお弁当箱につめる
     * 服を中々着ない & 靴を中々履かないMen's VS PaPa
 * 08:00 登園
     * 2人とも別の保育園なので地味に時間がかかる
 * 08:30 出社
 * 17:00 お迎えへ
 * 17:45 帰宅 with ちびっこ
 * 18:00 連絡帳チェック/風呂掃除/洗濯/食事準備
     * 食事は妻が元気なときは全力で任せる(私がやると手際がわるいのでw)
 * 18:30 夕食(中々食べないのでいつも1時間くらいかかる)
 * 19:45 風呂
 * 20:30 歯磨き & 寝かしつけスタート
 * 22:00 寝かしつけ完了
     * 子どもが1人のときは21:30とかだったけど、保育園で寝まくったり2人になってからはだいたい遅い
 * 22:15 洗い物/保育園の準備(スタイ/タオル/オムツ/着替えなど)/明日着させる服の準備/ごはん炊く/散乱したおもちゃの片づけ
 * 23:30 寝たいw
* 日課を書いてみたけど、こんなにうまくいく日はそんなないですねぇ
 * さぼってもつけは回ってくるので^^
* ネット契約しているのにPC自体を1か月以上起動していなくてネット解約してもいいんじゃ！？って考えたことも・・・

## ワークスタイルはどう変わった？
* フレックスタイム勤務で働かせてもらっています(フレックスについての説明は割愛します)
 * 今の生活では必要不可欠な制度と感じています
* 突然の半休や時間休などが多くなりました
 * 保育園から「熱が出ました、迎えに来てください」「水様便が続いているので迎えに来てください」etc...
 * 逆に自分自身の体調不良でお休みをいただくことは減りました(健康になった？)

## 保険は入っておくべし
* 卒乳して保育園生活も始まったころが一番危ないんですよね
* 2人ともウィルス性の感染症やヘルパンギーナ(それに伴う脱水)、中耳炎などこれまでに何度か入院し、保険にはもう何度もお世話になりました

## 子育てで役立ったスマホアプリ
* 誰もが知ってる「おにから電話」アプリ
　* 「もしもし、赤鬼です」のやつですが、うちの子は着信音だけでもうギブアップですw
　* 最近はそのモノマネを私がしても効果があるほど
* 読み聞かせ絵本アプリ
 * 絵本が手元にないときに活躍します
* FaceTime/Skype
 * Skypeでもなんでもいいのですが、核家族家庭だとじぃじ/ばぁばに連絡とれるのいいですよね

## 突然ですが、足し算アプリを作りたい！
* 最後になにか技術者らしいことを言って終わろうかと
* 4歳の子どもが簡単な足し算ができることに気付いたので少し教えてみました
 * 両指を使って左右の総本数を数えるといったシンプルな学習方法です
     * 父「2+3=  ・・・ 左手が3本、右手が2本　くっつけて全部数えてると何本？」
     * 子「1,2,3,4,5・・・5本」
* なにかアプリにしてしりとりをするかのように「足し算面白い！」とならないかなと試行錯誤するも一体どうやると面白いと感じ学んでくれるのだろう？と
* そして、次に1～10まで数字を書いておいて、2に人形を置いてそこから3歩進むと人形は何のかずにいく？と尋ねると1回は答えてくれたもののすぐギブアップしちゃいました
 * どうやら面白いやん！と思ったのは自分だけだったようです^^
* 「4歳の子どもには難しいでしょ！まだひらがなを少しかけるくらいなのに」と私の母にいわれて、ほんまそうですな！と思ってはみたもののまだあきらめてませんw
* とりあえずなにか作ってみて成功したら記事書きます！！

## さいごに
* いくら家事育児でいっぱいいっぱいでも体を動かさなくなったらダメだろうと思って、子育て中も動けるときに勉強会に参加しています
 * つい最近も子育てなうのパパがたくさんいる勉強会に参加して、刺激を受けるだけでも大事だなと改めて思いました
 * そして、参加した際にはできるだけなんか発表することに心がけています
* 田舎にいるのでひょいと都会の勉強会に参加というわけにもいかないので自分でオンライン勉強会開いてみたり
 * [Selenium談話会 in Slack](http://qiita.com/oh_rusty_nail/items/b8ba525d31ea7c522856#selenium-%E8%AB%87%E8%A9%B1%E4%BC%9A-in-slack)
Win32API関連で自分がよく参考にしているサイトと書籍

自分が Windows アプリを作成する際に Win32API 関連で参考にするサイトと書籍についていくつかまとめてみました。

MSDN
https://msdn.microsoft.com/ja-jp/
まずは公式。だけど重いし翻訳日本語だったり、体系的に知るには不便だったり。
リファレンスとしてはまずまずなので最終的にはココを確認することも多い。

WisdomSoft（旧）
http://wisdom.sakura.ne.jp/
Win32 API入門は最初から勉強するにはとても良いサイトだと思います。

HSPの裏技？？
http://chokuto.ifdef.jp/urawaza/
HSPだけどまあC言語等とほぼ同じ。

インコのページ
http://gurigumi.s349.xrea.com/
ちょっと突っ込んだコントロールとかの使い方とかがある。

EternalWindows
http://eternalwindows.jp/index.html
多岐にわたる分野の技術についてあります。

以上が自分が良く使うサイトになります。その都度検索した結果で出てくるサイトを参考にする場合も多いですが、上記のサイトは判りやすさや信頼性の点で記憶に残ってよく使うようになりました。ちなみにこういう場合良く紹介されているサイトである「猫でもわかるプログラミング」は自分とは合わなかったです。サンプルコードも要点だけを突いた判りやすいモノではないように思えます。

次に書籍になります。

Windows95 APIバイブル1 Win32編
http://www.shoeisha.co.jp/book/detail/9784881354308
Windows95 APIバイブル2 コモンコントロール・メッセージ編
http://www.shoeisha.co.jp/book/detail/9784881354469
所謂バイブルですね。一つのジャンルについて関数や定数が網羅されているのでリファレンスではなく一通り読むと意外に知らなかった便利な関数があったりします。また複数の関数を使って始めて意味をなすようなものだとサンプルで使い方が示されているので理解しやすいと思います。

APIで学ぶWindows徹底理解
http://itpro.nikkeibp.co.jp/article/MAG/20061218/257206/
ウィンドウコントロールだけではなく OS の機能（プロセス等）の情報が体系立てて学べる本だと思います。

自分はあまり本を読まないので読んだ本の中で良かったと思うのは以上三冊ですが、ちょっと調べてみると良さそうな本はいくつか出てきますのでもっと勉強したい方はそちらも読んでみると良いかもしれません。
コードを書くように筋トレするのか、筋トレするようにコードを書くのか

こんにちは！筋肉、してますか！？
この記事は [筋肉 Advent Calendar 2016 \- Qiita](http://qiita.com/advent-calendar/2016/muscle) 21日目の記事ですよ！！

さて、アドベントカレンダーも 21 日目ともなれば、筋トレがもたらす肉体的・精神的なメリットはもはや熟知されているかと思います。
そこで、この記事では私が感じる筋トレとコーディングの共通点を紹介し、筋トレは健康だけではない！コーディングスキルの向上にも貢献するのだ！！ということをまとめてみます。

職場に **筋肉手当** を導入してもらおう！！

# 筋肉を分割して考えるように、メソッドを分割しよう

筋トレでは鍛えたい部位に意識を集中し、徹底的に一つの筋肉をいじめ抜くことで最大限の成果が得られます。

上腕二頭筋のトレーニングをしているときに肩の筋肉で持ち上げていないだろうか…背中を鍛えるつもりが腕でバーベルを持ち上げていないだろうか…

あれ、なんだかコーディングに似てますね。

Model のメソッドなのに、ルーティングに関する処理を行っていないだろうか… `get_hoge` というメソッドなのに、 get する以外の処理を書いていないか

そうです。コードの役割を分割することにすごく似ているんですね。

もし「この関数に処理が多すぎる」とか、「Controller でやる処理じゃない」などのレビューが多い方がいましたら、筋トレをイメージしてコードを書いてみてください。

今は上腕筋のトレーニングだ。何があってもこの筋繊維以外は絶対に動かさないぞ！！そんな気持ちで、 Model の処理は Model にだけ書いていきましょう。


# Github で草を生やすかの如くトレーニングをする

トレーニングってつらいですよね。継続できないですよね。そんなときは Github を思い出してください。Github の草、生えてますか？
草がたくさん生えている人は、やはり相対的に優れた技術者であることが多いと思います。優れた技術者になるために、毎日草を生やすためにコードを書く人も多いのではないでしょうか。

筋トレも一緒だと考えてください。継続して草を生やすために毎朝コードを 1 push するように、我々は毎朝プッシュバーを 1 push しましょう。コードを pull した回数だけケーブルマシンを pull しましょう。
そして、草を生やす代わりに、空になったプロテインの容器を並べましょう！

筋トレそのものを目的にするのは難しいですが、周りから見てわかりやすい目標を持って、トレーニングに励みましょう。

# 運動、食事、睡眠

筋トレの効果を最大限に発揮するためには、運動するだけではなく、食事と睡眠にも気をつける必要があるのはご存知の通りかと思います。

_筋肉を維持・発達するために運動し、傷つけた肉体を修復するために栄養のある食事を取り、体力を回復させるために十分な睡眠をとる。_

コーディングも一緒ですね。

生涯コーディングで食べていくためには身体がとても大事です。

_健康を維持するために運動し、運動と思考で失った栄養を食事で補う。明日もまたコードを書くために、しっかり休んで体力を回復させる。_

もし「あいつ今日もジム行くとか言って早く帰りやがった…」なんてぼやく同僚がいましたら、この先を見据えて効率良く質の高い成果を出すための投資だぞ！と言いくるめ、そいつもジムに連れて行きましょう！

1人でできる効率化なんてたかが知れていますが、チームメンバー全員を巻き込めれば、みんな筋肉！強い筋肉は強いチーム(物理)を作ります！

# 最後に

ある日、クライミングを終えて帰宅中の出来事です。

どうやったらもっと強くなれるか…そしてどうやったら仕事でもっと良いコードが書けるか…

_「あ、筋繊維に意識してトレーニングするのと、クラス・メソッドの役割を意識してコード書くのって似てるな…」_

こうしてこの記事は作られました。

明日は musclemikiya さんで、「エンジニアが最高のパフォーマンスを発揮し続けるための筋肉メンテ術」です。楽しみですね。
並列バッチパターン[MySQL on Fusion-IOのパフォーマンスを引き出す]

# 背景
この4年間に弊社サービスで扱っている企業データは10万社から約380万社まで増えました。
最も大きなテーブルには約７億レコード格納されています。
この大量のデータを処理するためのバッチ処理の工夫を紹介したいと思います。

# 前提条件
## データの性質
更新は少なく追加がほとんどです。
処理対象データはフラグ管理されています。
## 改善前の処理方式
改善前の処理方式は、処理の起点になるデータを一括して取得して、1レコード単位で関連する処理を実行する方式でした。

```
begin();
List<Target> targets = selectTargets();
for (Target t : targets) {
    //select
    //insert
    //select
    //update
    //select
    //delete
    //etc.. と続く逐次処理
}
commit();

```
## ボトルネックと対応方針
インデックスが正しく貼られている場合、通信コストがボトルネックになってくるのでそこを改善する方法を考えます。
パフォーマンス改善のために、クエリの発行回数を削減することと待機時間の削減するようにトライしました。
普通に処理してるとFusion-IOが遊んでしまうのでFusion-IOに仕事させるために並行処理します。

## 環境・ライブラリ
Java 8
jOOQ 2.8 (上げたい)
Fusion-IO (HDDやSSDでも速くなります)

## その他の制限
binlog方式のレプリケーションをしているためコミット単位は大きくなりすぎないように注意が必要になります。



# CQS [コマンドとクエリの分離]
ループ内で逐次実行していたselectをループ外で一括取得してDtoに詰めておきます。
データ取得結果をファーストクラスコレクションにしてキャッシュするデータを置くのもいいと思います。
```

List<Integer> targetIds = selectTargets();
List<Target> targets = fetchData(targetIds);
List<Result> results = targets.stream().map(t -> process(t)).collect(toList());

begin();
bulkInsert(results);
bulkDelete(results);
bulkUpdate(results);
//etc...
commit();
```
- テーブルロックがかかる時間が減る
- テストを容易にする(fetchDataとprocessをテストすれば良い)
 
参考[CQS:wikipedia](https://en.wikipedia.org/wiki/Command%E2%80%93query_separation)

# 並列処理
```
// キーの取得は軽い処理なのでひとまず並列処理しなくていい
List<Integer> targetIds = selectTargets();
List<List<Integer>> chunks = Lists.partition(targetIds, 1000);
chunks.parallelStream().forEach(ids -> {
    // 複数テーブルへのselectや重いクエリを実行は並列処理したい
    List<Target> targets = fetchData(ids);
    List<Result> results = targets.stream().map(t -> process(t)).collect(toList());

    Retry.do(3, () -> {
        begin();
        bulkInsert(results);
        bulkDelete(results);
        bulkUpdate(results);
        //etc...
        commit();
    });
}
```
- データの取得とDBの更新をマルチスレッドで実行
- デッドロックしないように実装するが、稀なデッドロックはリトライでカバーする


ここまでの改善で(重複処理の削除やキャッシングも組み合わせて)約200倍性能改善し、
１週間かかる想定だった大量データ投入を１時間で終了できました。


# 今後の改善
計画中でまだ実施していないもの
### Queue or Stream or Messaging基盤の導入
対象データのフラグ管理を廃止してロックを大幅に減らせる。
データ量や遅延に応じて処理の並列度を増やせる。
### トランザクションの分解とイベント処理
まとめて処理している更新系の処理を分割して実行効率を上げる。
トランザクションでデータの整合性を担保しないため、参照データの整合性を保つ仕組みが必要になる。
Aggregator(Reactive Messaging Patterns Chapter 7.Message Routing)
のような仕組みでヘッダテーブルへの書き込みを全てのデータが揃ってから実行することで対応したい。



# 終わり
つっこみお待ちしてます。
Magento2例外エラー内容を表示する方法

```
There has been an error processing your request
Exception printing is disabled by default for security reasons.
Error log record number: 1234567890
```
このようなメッセージが出た時にエラーの内容を表示したい場合は、
`pub/errors/local.xml.sample`を`pub/errors/local.xml`に置き換えるとブラウザへの例外内容表示が許可される。
他にも指定したemailへ送信する設定が用意されている。

### 環境
- Magento2.1.2

### 参考
[Exception printing is disabled by default for security reasons Magento 2](https://www.mageplaza.com/kb/exception-printing-is-disabled-by-default-for-security-reasons-magento-1-2.html)
開発環境のPostfixの設定


開発環境でのメールに関する設定。
開発環境から送信したメールが外部に送信されないようにする。

環境はCentOS 7.3。

```bash
$ cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
```

# aliasを作成する

所定のアカウントにメールを転送するaliasを作成する。

```bash
$ sudo tee /etc/aliases.regexp <<EOT > /dev/null
> /(?!^root\$|^$USER\$)^.*\$/ $USER
> EOT
```

上記のコマンドを実行した結果。

```bash
[te2u@centos73 ~]$ cat /etc/aliases.regexp
/(?!^root$|^te2u$)^.*$/ te2u
```

rootもしくは自分へのメール以外を自分に転送する。

# local転送に変更する

開発環境から送信するすべてのメールをlocal転送にする。

```bash
$ sudo tee /etc/postfix/transport_maps <<'EOT' > /dev/null
> /^.*@.*$/ local
> EOT
```

# 上記2つのファイルを適用する

現状の設定ファイルのバックアップを取り、上述の2つの設定を適用する変更を行う。

```bash
$ sudo cp /etc/postfix/main.cf /etc/postfix/main.cf.org
$ sudoedit /etc/postfix/main.cf
```

適用前と適用後の差分。

```
$ diff -u /etc/postfix/main.cf.org /etc/postfix/main.cf
--- /etc/postfix/main.cf.org	2016-12-21 11:58:25.010525872 +0900
+++ /etc/postfix/main.cf	2016-12-21 11:59:22.709358250 +0900
@@ -383,9 +383,10 @@
 # "postfix reload" to eliminate the delay.
 #
 #alias_maps = dbm:/etc/aliases
-alias_maps = hash:/etc/aliases
+#alias_maps = hash:/etc/aliases
 #alias_maps = hash:/etc/aliases, nis:mail.aliases
 #alias_maps = netinfo:/aliases
+alias_maps = hash:/etc/aliases, pcre:/etc/aliases.regexp

 # The alias_database parameter specifies the alias database(s) that
 # are built with "newaliases" or "sendmail -bi".  This is a separate
@@ -677,3 +678,5 @@
 # readme_directory: The location of the Postfix README files.
 #
 readme_directory = /usr/share/doc/postfix-2.10.1/README_FILES
+
+transport_maps = pcre:/etc/postfix/transport_maps
```

変更内容を適用する。

```
$ sudo systemctl reload postfix.service
```

# 確認する

mailコマンドで設定が正しいか確認する。

mailコマンドがないときはmailxをインストールする。

```
sudo yum install mailx
```

mailコマンドでメールを送信する。

```
$ echo 'test' | mail -s 'test' test@example.com
```

正しく設定されていれば先ほど送信したメールが自分自身宛にきているので、それを確認する。

```
$ mail
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/te2u": 1 message 1 new
>N  1 te2u@centos73.vm      Wed Dec 21 12:02  21/669   "test"
& 1
Message  1:
From owner-test@centos73.vm  Wed Dec 21 12:02:18 2016
Return-Path: <owner-test@centos73.vm>
X-Original-To: te2u@centos73.vm
Delivered-To: te2u@centos73.vm
Delivered-To: test@example.com
Date: Wed, 21 Dec 2016 12:02:18 +0900
To: test@example.com
Subject: test
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=us-ascii
From: te2u@centos73.vm
Status: R

test

```

# 参考

- [Postfixで絶対にメールを外に出さずに特定のローカルユーザー宛に集約する開発用メールサーバのつくり方 | roundropブログ implements Programmable](http://blog.roundrop.jp/show/22)
- [Postfix設定パラメータ(alias_maps)](http://www.postfix-jp.info/trans-2.2/jhtml/postconf.5.html#alias_maps)
- [Postfix設定パラメータ(transport_maps)](http://www.postfix-jp.info/trans-2.2/jhtml/postconf.5.html#transport_maps)
phina.jsでマルチにタッチ

この記事は、[phina.js Advent Calendar 2016](http://qiita.com/advent-calendar/2016/phinajs) の記事です。
昨日→[phina.jsのShapeを複数まとめて画像として使う by simiraaaaさん](http://qiita.com/simiraaaa/items/7355ed8037ebd7d99bcb)

#話のまくら
マルチタッチと言っても、[マルチ(HMX-12)](https://www.google.co.jp/search?q=%E3%83%9E%E3%83%AB%E3%83%81+hmx-12&rlz=1C1CKMB_enJP543JP543&espv=2&biw=1104&bih=616&source=lnms&tbm=isch&sa=X&ved=0ahUKEwjC5Ivi8ITRAhUGErwKHW4wBY0Q_AUIBigB)にタッチする事ではありません。
関係ないですが、To Heartがもう２０年前とか吐血しそうになりませんか。私はなりました。
あの頃のLeafは良かったよね、とかどうでも良い話はおいといて。

#モバイルでのマルチタッチについて
phina.jsでは、標準で対応しようとすると面倒ですが、それを簡単に扱える機能が多く用意されています。
マルチタッチもその一つです。

とりあえずサンプルをご覧ください（iPhoneでしか動作確認してません）
http://runstant.com/minimo/projects/MultitouchSample/full
<img width="375" alt="IMG_5254.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/31052/59a56e88-de4e-4bfa-754f-8e2f4e36ecfd.png">

スマートフォンで実行すると、タッチした地点に丸と番号が表示されます。


#コードの説明
`phina.display.DomApp`には`pointer`、`keyboard`等、ＵＩに関して自動で更新されるオブジェクトを持っています。
マルチタッチの情報が入っているオブジェクトは`pointers`です。

```JavaScript:マルチタッチ情報取得
var p = app.pointers;
this.label.text = "touches: "+p.length;
for (var i = 0; i < 5; i++) {
    if (i < p.length) {
        this.finger[i].visible = true;
        this.finger[i].setPosition(p[i].x, p[i].y);
    } else {
        this.finger[i].visible = false;
    }
}
```
pointersは配列になっていて、モバイルの場合は現在タッチされているポインタ情報全てが入ります。
一か所もタッチされていない場合は配列の中身は空になります。

PCの場合、初期段階ではpointersの中身は無く（長さ０の配列）、一回でもポインタが画面内に入ると０番目にポインタ情報が入り、それ以降はpointersには必ず０番目にポインタ情報が入ります。（これはPCの場合、ポインタが画面外に行った判定が出来ない為と思われます）

#注意点
配列の順序は全てタッチされている間は保持されますが、一個でもタッチ解除され間が抜けた場合に配列番号が詰まってセットされます。
例：
０：人差指　１：中指　２：薬指
↓（中指を離す）
０：人差指　１：薬指

タッチが連続して行われているかの判定は、配列の添字では無く、`pointer`に`id`というプロパティがセットされていますので、それを利用して判別してください。

タッチした地点の上にIDが表示される様に変更したサンプル
http://runstant.com/minimo/projects/MultitouchSample2/full

#おしまい
という事で、phina.jsならマルチタッチも簡単に扱えるよ！という記事でした。
サンプルの背景をマルチにしようかと思ったのですが、著作権的に怒られそうなのでやめました。
ちなみに私はマルチ派でもセリオ派という訳でもなく、綾香派です。
MockMvcを使ったControllerのUnitTestでJsonのRequest

# 概要

SpringのMockMvcを使ってControllerのテストで、JsonRequestする。

## 前提

- Spring Boot を使用する。
- モデルでは日付型に JSR310 (LocalDate、他) を使用する。


## テスト対象メソッド

```java
@PostMapping(value = "hoge", consumes = MediaType.APPLICATION_JSON_VALUE)
public void hoge(@RequestBody Hoge hoge) {
    System.out.println("hoge");
}
```

## `Jackson` を依存に追加

JavaとJsonの変換にはJacksonを利用する。
下記はMavenの例。

```xml
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.6.1</version>
</dependency>
```

## UnitテストでJsonのリクエスト

下記はSpockでの例。

```groovy
def "JsonのPostリクエスト"() {
    setup:
    // JacksonでオブジェクトをJson形式に変換
    def hoge = new Hoge();
    ObjectMapper mapper = new ObjectMapper();
    String json = mapper.writeValueAsString(hoge);

    expect:
    mockMvc.perform(MockMvcRequestBuilders
        .post('/hoge')
        // ContentTypeの設定
        .contentType(MediaType.APPLICATION_JSON)
        // Jsonの設定
        .content(json)
    ).andExpect(
        MockMvcResultMatchers.status().is(HttpStatus.OK.value()),
    )
}
```

## 参考

- [Testing Spring's @RequestBody using Spring MockMVC](http://stackoverflow.com/questions/20504399/testing-springs-requestbody-using-spring-mockmvc)
- [Jackson使い方メモ](http://qiita.com/opengl-8080/items/b613b9b3bc5d796c840c)