OmniAICreator/Qiita-1.07M huggingface dataset:
マクロ定数が多すぎる。

メンテナンスしづらいC++ソースコードの特徴の１つに、
・マクロ定数が多すぎる。
・マクロ定数を含むヘッダファイルを\#includeするファイルが多すぎる。
というのがあると思っている。

　そこで、なぜそう思うのかと、どのように書くべきと考えているのかを述べたいと思う。
C++の書き方の本におそらく書いてあるだろうと思うのですが、自分の経験に基づいて書いてみようと思う。

- \#ifdef \#else \#endifのコードは、ビルドを確かめていないコードになっている。
　自分がよく使う組み合わせについてだけは、ビルドを確認しているが、そうでない組み合わせでは、ビルドが通るかどうかさえ、確かめられていないコードになりがち。
　この場合、ビルドできないコードは基本この\#ifdef \#else \#endifの範囲に生じる。このブロックの中で\#defineを定義していなければ、このコードの範囲でビルドできないが生じる。 


- \#ifdef \と#define マクロ定数の組み合わせはさらに危険。
　いつの間にかビルドできない部分がさらに広がる。
  
　次の例は、\#ifdefによって、マクロ定数を定義している例。

```example.h:
#ifdef WIN32
    #define SPAM    "SPAM"
    #define HAM     "HAM"
    #define EGG     "EGG"
#else
    #define SPAM    "spam"
    #define HAM     "ham"
    #define EGG     "egg"
#endif

```

　　このくらいの範囲だったらまだいいが、マクロ定数の定義をやりすぎると、それぞれのブロックの中で、数十個以上のマクロ定数を定義することになる。
　このexample.hを\#includeするファイルの中では、どちらの条件でも、SPAM,HAM,EGGの全てがマクロ定義されていることを前提とする。
　しかし、数十個のマクロ定数を記述しているうちに、２つのブロックの間の整合性がとれなくなってしまっていることを生じやすくなる。


```example2.h:
#ifdef WIN32
    #include "case_win.h"
#else
    #include "case_linux.h"
#endif
```

 このようなファイルでも、case_win.h, case_linux.h の中の記述、とりわけマクロ定数の記述が増えていくと、一方だけ定義してあって、他方には定義がないという状況を生じやすくなっていく。

\#if～\#elif～\#else も記述が増えていくと整合性が保たれにくくなっていく。

```example3.h:
#if defined(MODEL_A)
    MODEL_A用の記述
#elif defined(MODEL_B)
    MODEL_B用の記述
#elif defined(MODEL_C)
    MODEL_C用の記述
#elif defined(MODEL_D)
    MODEL_D用の記述
#else
    その他の場合の記述
#endif
```
 このような各記述の部分が数十個におよぶと、どこかで記述の整合性が壊れやすい。
そして、ビルドしたときに、コンパイルエラーが出る範囲は、このヘッダファイルをinclude しているファイル全体に影響を生じやすくなっていく。

　繰り返し言う。試されていない組み合わせでは、ソースコードがビルドできるかどうかは検証されていないということだ。

- \#ifdef DEBUG \#endif のようなコードも書かれてくる。
- さらに\#if 0 \#else \#endif という気まぐれなコードが書かれやすい。

その中に記述されるマクロ定数の数が増えていくと、一方の組み合わせでは動作するのに、他方の組み合わせではビルドさえ通らないコードが簡単に作れてしまう。いつの間にか、本当にビルドできるのか不明なコードになっていく。


C++を使っている限り、このようなマクロ定数を使わなければならない状況は、とても少なくなっている。
配列の大きさを定義するのに、const intを使える。

```sample.cpp:
  const int array_size = 10;
  int array1[array_size];  // OK!!
```

- include されるマクロ定数は、広い範囲でスコープを持ちすぎる。
 \#define DATA_SIZE 100
などとしたヘッダファイルをincludeすると、DATA_SIZEというマクロ定数がincludeした全てのソースコードの中で影響を受ける。DATA_SIZEなどというマクロ定数名は、容易に書きがちな名前であるので、includeするヘッダファイルの中でぶつかるということがおきやすい。
　マクロ定数の他、マクロ関数もそうです。
　有名どころでは、```#include <windows.h>``` とすると、std::max()のmax()さえ文字列の置き換えを受けてしまうというのがある。(そういう意味でもWindows.h は利用したくない。)

このようなバグを生じなくても、マクロ定数、マクロ関数の使用は、広い範囲でスコープを持ちすぎるので、そのため、依存性を減らすことが難しくなる。依存性が多すぎるので、単体テストを書きにくくなっている。


追記：
　安易なマクロ定数の追加は、#ifdef の組み合わせによっては、ある場合にはビルドできて、別な場合にはビルドできないという状況を生じやすくなります。

###**参考にした記事**
[C++では定数はヘッダではなくソースファイルに書こう](http://d.hatena.ne.jp/taiyakisun/20101209/1291915414)

[それC++なら#defineじゃなくてもできるよ](https://blog.myon.info/blog/2015-12-18/avoid-defining-macros/)
Pythonのコンテキストマネージャは何が嬉しいのか？

# 経緯

[Fabric コンテキストマネージャー](http://fabric-ja.readthedocs.io/ja/latest/api/core/context_managers.html)

Fabricを利用しているプログラムを読むと、with文で呼び出されているオブジェクトが有る。
ちょっと調べてみると、どうやら、**コンテキストマネージャ**と呼ばれるものらしい。。
文脈（**コンキテスト**）を管理する者（**マネージャ**）とは、
Pythonでは一体何を意味し、何か嬉しいことが有るのだろうか？
よく分からず安易にコピペしてはいけないと思い、調べてみようと思った。

# そもそもコンテキストマネージャとは、何か？

公式ドキュメントでは、
with文実行時に**runtime context**を定義し確立させるためのオブジェクト、と説明されている。
では、**runtime context**とは何だろうか？

そこで、stack overflowに記事を見つけた。
[What is a “runtime context”?](http://stackoverflow.com/questions/19652662/what-is-a-runtime-context)

**\_\_enter\_\_()呼び出しで組み立てられて、\_\_exit\_\_()呼び出しで取り壊される環境**、と説明されている。
この**環境**とは、コンテキストマネージャ自身が持つプロパティの集合を指しているのだろう。

コンテキストマネージャは必ず、特殊メソッドの\_\_enter\_\_()と\_\_exit\_\_()を定義しなければいけない約束になっている。
\_\_enter\_\_()と\_\_exit\_\_()のシグネチャは厳密に取り決められている。詳細は割愛。

# 何故、ガチガチに取り決められたコンテキストマネージャをわざわざ作るのか？

with文でコンテキストマネージャが呼び出されると、withブロックの直前に、
必ず\_\_enter\_\_()が呼び出され、
withブロックの処理が正常終了（または例外発生）したならば、
必ずコンテキストマネージャの\_\_exit\_\_()が呼び出される。

以上よりコンテキストマネージャを利用するメリットが見えてきた。

- 少ないコード量（特に例外処理にあたる部分）と高い可読性
- withブロックによるローカルスコープの環境（プロパティの集合）の提供
- 前処理（\_\_enter\_\_）と後処理（\_\_exit\_\_）の強制

# コンテキストマネージャを自作して呼び出そう
後日記載
AWS Rekognition と GCP Cloud Vision の比較

この記事は [Opt Technologies Advent Calendar 2016](http://qiita.com/advent-calendar/2016/opt-technologies) の23日目の記事です。

-----

今年(2016)の AWS re:Invent で Rekognition という GCP Cloud Vision と同領域のサービスが発表されました。

ということで、ほんの少し触った程度ですが、色々な点から比較してみたいと思います。

以下全て2016/12/24時点での情報です。

# サービスの特長

紹介ページより

### AWS Rekognition

- 物体およびシーンの検出
- 顔分析
- 顔の比較
- 顔認識

日本リージョンではまだ使えません

### GCP Cloud Vision

- ラベル検出
- 有害コンテンツ検出
- ロゴ検出
- ランドマーク検出
- 光学式文字認識（OCR）
- 顔検出
- 画像特性

### 比較

- 物体検出系は Cloud Vision の方が細分化されているっぽい
- それぞれの分析結果と確からしさのスコアがセットで返ってくるのはどちらも一緒
- 顔分析系に対するアプローチは若干異なるが、表情分析に相当するものはどちらもにもある
- 機能面で明確に違うのは以下かも
  - Rekognition -> 顔の比較(類似度算出)ができる
  - Cloud Vision -> OCRができる

# Quick Start

### AWS Rekognition

http://docs.aws.amazon.com/rekognition/latest/dg/

AWS Console に GUI があって、即座に試すことができる。

機能は以下の３つ。

- Object and scene detection (物体およびシーンの検出)
- Facial analysis (顔検出および顔分析)
- Face comparison (顔比較)

API も AWS SDK のほか、 AWS CLI からも簡単に試すことができる。

### GCP Cloud Vision

https://cloud.google.com/vision/docs/quickstart?hl=ja

GUI はないが、 Quick Start のページで API を試せる。

分析タイプは7種類。

- FACE_DETECTION
- LANDMARK_DETECTION
- LOGO_DETECTION
- LABEL_DETECTION
- TEXT_DETECTION
- SAFE_SEARCH_DETECTION
- IMAGE_PROPERTIES

API を直叩きしてもいいし、もちろん GCP SDK からも使える。

### 比較

- 物体検出はあまり違いがわからなかったが、用途との相性が大きい部分かも
- 顔分析は精度は良さそうだが、どちらもあまり変わらないように見える
- AWS Rekognition
  - GUI便利。非エンジニアに使ってもらうにもいいかも
  - Face comparison は割りと精度良さそうだし、他に同じことができるサービス無さそうでスゴイ
- GCP Cloud Vision
  - OCRは手書きでなければ実用的っぽい
  - アダルト検出が必要な場合、ピンポイントでハマることはあるかも（精度は試せてない）

# 料金

### AWS Rekognition

https://aws.amazon.com/jp/rekognition/pricing/

| 画像分析枠 | 処理画像 1,000 枚あたりの料金 |
| --- | --- |
| 1 か月あたり画像処理* 100 万枚まで | 1.00 USD |
| 1 か月あたり画像処理* 100 万枚超 1,000 万枚まで | 0.80 USD |
| 1 か月あたり画像処理* 1,000 万枚超 1 億枚まで | 0.60 USD |
| 1 か月あたり画像処理* 1 億枚超 | 0.40 USD |

その他オプション料金もある。

### GCP Cloud Vision

https://cloud.google.com/vision/pricing

1,000 ユニットの価格。ユニット数は月単位の使用量に基づいて計上されます。だそうです。

| 機能 | 1～1,000 ユニット/月 | 1,001～1,000 ユニット/月 | 1,000,001～5,000,000 ユニット/月 | 5,000,001～20,000,000 ユニット/月 |
| --- | --- | --- | --- | --- |
| ラベル検出 | 無料 | $1.50 | $1.50 | $1.00 |
| OCR | 無料 | $1.50 | $1.50 | $0.60 |
| 有害コンテンツ検出 | 無料 | 現在のところ、ラベル検出を利用している場合は無料* |
| 顔検出 | 無料 | $1.50 | $1.50 | $0.60 |
| ランドマーク検出 | 無料 | $1.50 | $1.50 | $0.60 |
| ロゴ検出 | 無料 | $1.50 | $1.50 | $0.60 |
| 画像特性 | 無料 | $1.50 | $1.50 | $0.60 |

### 比較

- Cloud Vision の方が全体的に高いように見えます
- というか Rekognition が価格優位性をしっかり意識したプライシングを出してきているように見える

# まとめ

割りと繰り返しの内容ですが、

- 顔比較やるなら Rekognition
- OCRやるなら Cloud Vision

かなあ。価格差はC向けサービスをやるのでなければ気にする程ではないと思った。
持ち時間を測るWebツール「測るヤツ」

この記事は、[SLP_KBITその2 Advent Calendar 2016 - Qiita](http://qiita.com/advent-calendar/2016/slp_kbit2)の22日目の記事だったはずの記事です。

# はじめに

また遅刻しましたごめんなさい。
![yakidogeza.jpg](https://qiita-image-store.s3.amazonaws.com/0/33326/83f279b8-5871-498d-2f14-9b420883bcae.jpeg)
卒論とか年末発表の準備とかで忙しくて...忘れてました...

# 持ち時間計測の必要性

発表のときとか議論の時に、無駄にだらだらと長引いてしまうことって有りますよね。
そういった際に、各々の持ち時間を計測して管理出来るといいなってことで作ったツールです。割りと理由は適当です。

イメージ的には、[PointingPoker](https://www.pointingpoker.com/)のようなものを作ってみたかった感じです

# 環境

CentOS6.6
NodeJS v7.2.1

リポジトリ: https://github.com/SLP-KBIT/hakaru-yatsu
contributer: @gembaf @nobarudo @vitamiena 

# 動作画面

![hakaruyatsu.gif](https://qiita-image-store.s3.amazonaws.com/0/33326/38e1250d-2ce2-e193-c9c2-5051c205b9a5.gif)

# 利用した技術

Express : NodeJSの軽量Webアプリケーションフレームワーク
socket.io : Webでリアルタイム通信をするためのWebsocketをjavascriptで利用できるようにするライブラリ
ECMAScript2015 : Javascriptの次世代言語仕様?(あんまり良くわかっていないけど、とにかく書きやすくなったJavascript)

# 工夫した点 セッションの概念の導入

PointingPokerのように、誰かがセッションを作成して、みんながそこにJoinする形に実装したかった。
普通にwebscoketを使ってるだけだと、入ったユーザ全員が同じような動作をしてしまうので、Sessionクラスを作成して、そこにjoin中のユーザのidを入れて、「同じセッションに参加している」、ということがわかるようにした。([src](https://github.com/SLP-KBIT/hakaru-yatsu/blob/master/src/session.js))

ユーザの区別には、ユーザごとのsocketのidを利用しました。(@gembafさんがやってくれました)
以下抜粋。

```
  socket.on('join', function (data) {
    session = Session.find(data.id);

    session.join(socket.id, data.name)

    // 送信元のユーザに現在のログインユーザの一覧を送信
    io.to(socket.id).emit('list-user', {users: session.users})
    // 送信元のユーザ以外にユーザが増えたことを通知
    socket.broadcast.emit('joined', {name: data.name})
  });
```

作成されたSessionのリストは、Sessionクラスのクラス変数として保持しています。
そこから指定したsessionを`find`メソッドで取り出し、socketのidとユーザ名を引数にして、`join`メソッドで参加したことを登録しています。
そして、送信元のユーザには現在のログインユーザ(自分を含む)を送信、既に参加済みのユーザには新し参加したユーザのデータを送信しています。

# 今後の課題

現在、時間の情報は各ブラウザが持っているだけなので、全ユーザ間で統一されていることが保証されていません。実際、使っていると最大で100秒近くずれることがあります。原因は不明ですが。。。
そこで、STOPが押された時に、現在の自分の時間を送信することで、時間の統一を図りたいと思っています。
加えて、現在計測するスタート時間は決め打ちなので、変えたいときはソースコード書き換えてbuildし直す必要があるので、そこを自由に設定できるようにしようと思います。これはまあ簡単ですね。

# まとめ

適当に気になった技術とかを使って、割とどうでもいいもの作ってみたりするの楽しいですね。
もっといろいろ触ってみたい技術があるので、今後もっとこういったことをしていきたいです。
就職後もそんな時間があったらいいなあ...
WindowsAPIを使ってPCを一定時間放っておくと自動でシャットダウンするようにしてみる

#はじめに
突然ですが、皆さんはPCをシャットダウンをするのを忘れたまま、出かけてしまったりすることはないでしょうか？僕はあります。
そこで僕は考えました...どうすれば消し忘れないのかと...
そして、自動で一定時間放っておかれたらシャットダウンしちゃえばいいのではないかという結論に至りました。

※Windows7(32bit)で動作確認しております。
#さっそく作ってみる
今回は、C言語+WindowsAPIを用いて作ってみます。
まず、[一定時間放っておかれたら]という点ですが、これはスクリーンセーバーを用いれば楽なのではないかと思いつきました。
つまり、

スクリーンセーバーが起動
　　　　　↓
　　シャットダウンさせる

みたいな感じですね。

というわけでまずは、スクリーンセーバーをWindowsAPIを使って書いていきます。
調べてみたところ、スクリーンセーバーを使うためには、
scrnsave.hをincludeし、
ScreenSaverProc関数、ScreenSaverConfigureDialog関数、RegisterDialogClasses関数を用いればよいようです。
というわけで書いてみました

```C:screensaver.c
#include <windows.h> 
#include <scrnsave.h>

#pragma comment(lib,"ScrnSave.lib")
#pragma comment(lib,"Comctl32.lib")

LRESULT WINAPI ScreenSaverProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {

	HANDLE token;
	LUID id;
	TOKEN_PRIVILEGES token_p;

	switch (msg) {

	case WM_CREATE:

		OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token);
		LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &(token_p.Privileges[0].Luid));

		token_p.PrivilegeCount = 1;
		token_p.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

		AdjustTokenPrivileges(token, FALSE, &token_p, 0, NULL, NULL);

		ExitWindowsEx(EWX_FORCE | EWX_SHUTDOWN, 0);

		break;

	case WM_DESTROY:

		PostQuitMessage(0);

		return 0;

	default: break;
	}

	return DefScreenSaverProc(hWnd, msg, wParam, lParam);
}

BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
	return TRUE;
}
BOOL WINAPI RegisterDialogClasses(HANDLE hInst) {
	return TRUE;
}
```

以上です。
WM_CREATE内のごちゃごちゃしたやつは、シャットダウンするために必要なExitWindowsEx関数を呼び出すためにSE_SHUTDOWN_NAME特権を有効にしています。

#実行結果
ちゃんとシャットダウンできました。
拡張子をsrcに変えてあとは、時間を設定すれば使うことができる（はず）です。

#追記
これじゃ設定時にシャットダウンしてしまい設定できませんでした...
起動した直後に若干待機させるなどして設定用の時間を設けなければいけないかもしれません。
社内転職のすゝめ

# TL;DR

現職に転職してから10年目に入りました。
入社以来2回、自分の意思による異動をしています。
その際に何を考えているのかを、さらっと書き留めてみました。


# 自分のこと

専門学校卒です。
15年ほど前に自宅近所の零細SIerに就職し、初めてプログラミングに触れました。

現在は2社目、大手Webサービス会社に10年ほど在籍してきます。
在籍期間は長いですが、2回、自分の意志による部署異動を経験しているため、3年に一度程度転職しているような感じです。

異動のたびにロールも変わっており、自分で言うのもなんですが、割と変わったキャリアパスかもしれません。

1. Webサービス開発運用エンジニア(DEV)
2. オペレーションエンジニア(OPS)
3. SRE/Migrtationエンジニア　←いまここ

現在は新規・既存サービス群のkubernetesで構築されたDocker platformへの移設と、それにともなうCI/CD Pipeline構築支援、SREとしてのデプロイ・運用作業を担当しています。


# なぜ異動を希望するのか？

異動するモチベーションは3つあります。
優先順位順に並べています。

1. より良い報酬を得るために必要な仕事を得ること　　
2. より良い仕事をするための能力を身に付けること
3. 新たな仲間を得ること



## "1. より良い報酬を得るために必要な仕事を得る"ために意識していること

- 誤解を恐れずに書きますが、現状これが１番目の理由です。
- 上を求めたらきりが無い、誰と働くかが重要だという意見もわかりますが、それはある程度の資産を確保してからでも遅くないと考えています。
自分はまだお金を貯める時期だと思っています。

そのために

- 事業の根幹に近く、予算の規模が大きい場所、かつ、自分の強みを活かせる仕事がある場所であること
  - 自分の強みを活かせる＝その場に足りないものを見つけて、必要な人間になるよう、それを埋めること
- 今後のキャリアに活かせる技能が身につけられること

を重視して異動先を選択しています。


## "2.より良い仕事をするための能力を身に付ける"ということ

上でも少し書きましたが、より良い報酬を得るために能力とは

- その場所に必要とされる人間になれること

だと考えています。

そのために、その場に足りないものを探して、自分が埋めることを意識しています。

一例ですが、弊社の場合は組織の規模が膨らみ、分業が進んでいるため

- サービス開発はできるけど、サービスが動くインフラのことはよく知らないため
  - インフラにどのような選択肢があるのかよく知らない
  - サービスが世に出るまでに何をする必要があるかよく知らない

というエンジニアが多いです。
なので、それを知っているだけでもありがたがられたりします。
自分はそれを得るために、WebエンジニアからOPSエンジニアに異動しました。

どんな場所でも、仕事を獲得しながら、信頼を積み重ね、さらに良い仕事を得ていくのが重要ですが、どうせなら他の人が苦手としているけど、自分が得意なことをで仕事と信頼を増やしていけるといいですね。

そうして得意なことで信頼を得ながら、空いた時間で技術を磨き、チャンスが来た際に手をあげられると最高です。

現在の職場にてkubernetesによるDockerizeを進めている方は、まさにそのように信頼を積み重ねつつ、技術を磨き続けてチャンスをモノにされました。
自分もそんなエンジニアになりたいと思い続けています。



## "3. 新たな仲間を得ること"

これは目的というより、副次的なものになります。

どのような場所にも、自分より何かが優れた人がいます。
特に、報酬を得るために必要な仕事がある場所には、必ず素晴らしく優れた人がいます。
技術・情熱・チームへの接し方、様々な部分で刺激を受けています。
そういった人たちと出会い、同じ仕事に関わることで自分自身も成長できる。
まれに自分の経験や行動から、相手に刺激を与えることができる。
これは本当に楽しいです。


# 実のところ

異動を希望する理由にはネガティブなものもあります。

- 英会話力を向上させるため、日本人スタッフの少ない部署へ異動する
- 技術的モチベーションを維持するため、自分にない技術を利用しているチームへ移る

本来このあたりは自助努力でなんとかするものなのかもしれませんが、自分は追い込まないとなかなか頑張らない正確なので、周りに迷惑をかけつつ、追い込む日々を送っています。
アーキテクチャ比較にゃ 2016 コード編

# これは？

社内発表のコードの反省会/説明/言い訳 用です。主に下記になります。

* きになる点
* 省いて（ズル）いる点


# やったこと

* 同じアプリケーションをそれぞれのアーキテクチャを用いて作成
* xhr , アニメーション , シーケンサー(イベント発生器)は共通モジュールを利用

_アプリ画像_

![sample.gif](https://qiita-image-store.s3.amazonaws.com/0/106271/a57383e5-43f5-d493-8b07-7478e14892e0.gif)


利用アーキテクチャ

* Flux
* Clean
* ReactivePrograming

# 全体的に

## 全体を通して気になっていること

* １ファイルに集約するように実装したので、変数の参照スコープがスパゲッティになっている

## Riotjs で気なったところ

* Rxjs の mixin の機能を用いているので、this のスコープが 実際の tag そのものになるので
 ぱっと見気持ち悪い。実際は一つのアーキテクチャを選択するので、tag ない記述するので変数の参照スコープは綺麗になるはずです

# それぞれのアーキテクチャで

* コードの成分は画像から確認してください

* {Web}, {Sequencer} は共有モジュールに該当します


## Flux

[app-flux.js](https://github.com/YooWaan/KickingProgram/blob/master/web-riot-rxjs/js/app-flux.js)

![flux-arch.png](https://qiita-image-store.s3.amazonaws.com/0/106271/1142bce0-7b6e-5692-ae15-b709180608d0.png)


## Clean

[app-clean.js](https://github.com/YooWaan/KickingProgram/blob/master/web-riot-rxjs/js/app-clean.js)

![clean-arch.png](https://qiita-image-store.s3.amazonaws.com/0/106271/9ef29076-1b66-8f2e-0a62-4032365c2701.png)


## ReactivePrograming

[app-rp.js](https://github.com/YooWaan/KickingProgram/blob/master/web-riot-rxjs/js/app-rp.js)

![rp-arch.png](https://qiita-image-store.s3.amazonaws.com/0/106271/1eca008a-f62e-3016-f1b6-6a45b3b48fd8.png)


# Flux 考察

## 構造

![flux-code.png](https://qiita-image-store.s3.amazonaws.com/0/106271/786d8707-bf59-8625-b3e7-80803692367a.png)

_ずる_

* action creator, callback, change events store querises 周りは、ふわっとぼやかしました

## 気になったところ

* Dispatcher は、Singleton, 画面？機能？ドメイン？などどのスコープがいいのだろう
* action creator, store 周りは、クラス化するのが大数の実例になりそうな気がするけど、ファイル量産体制になるんのでやだなぁ
* Riotjsなら単純に Riot.Observable を利用すれば、いいだけで Flux感はいらない気がした

* animation, sequencer の View に関連しない所の扱いがカテゴライズされずに微妙な扱いになった


# Clean 考察

## 構造

![clean-code.png](https://qiita-image-store.s3.amazonaws.com/0/106271/913e0e27-2c6e-4916-6a74-a898e1e3cdf2.png)


_ずる_

* Usecase Input Port / Interactor / Output port を個別に書くと、タイプ量が増えるので、Riot.Observable に集約して、trigger => input, on('xxx') => output+interactor な立ち位置で記述した


## 気になったところ

* ガッチガチにすると クラスファイル量産体制になるので 柔らか頭の人たちがいる場合でないと選択したくないなぁ
* 概念ごとに綺麗に分けられるので、Fluxより整理整頓したければ利用すればいいと思った

# ReactivePrograming 考察

## 構造

![rp-code.png](https://qiita-image-store.s3.amazonaws.com/0/106271/70c46452-9d6e-a441-1776-e5e1bc8e460f.png)


## 気になったところ

* Rxjs でイベントのsubscriberを作成する場合、tagのイベントの中で関数を定義すると
 イベント毎にObservableを生成するので、切り出して作成が必要

_ダメな例_

```js
  var me = this;
  me.clickObservable = undefined;
  function onClick(event) {
    me.clickObservable = Rx.Observable(function() {
           // subscriber some thing
      })
  }
```

* subscriber の関数を生成する時に、tag のインスタンスが必要で mixin を利用すると参照できるタイミングが、今回だと initPanel のタイミングに絞られて、そこで subscribe() の関数を設定していて見た目がきもい感じになってしまった

## 参考

* [社内発表用 擬人化アーキテクチャ](https://speakerdeck.com/wooyoowaan/ni-ren-hua-akitekutiya-anmarini-ren-ni-ren-sitenaikedo)
* [アーキテクチャ比較にゃ 2016 概要編](http://qiita.com/YooWaan/items/f281ea567f05de98a067)
SketchUp Make v17 / Ruby > 立方体をずらすスクリプト (半手動版)

```txt:動作環境
SketchUp Make v17.1.173
MacOS X El Capitan
```

http://qiita.com/7of9/items/806f287f032e600b2fcd
にて検討していた、立方体をずらす方法。

手動手順の検討 http://qiita.com/7of9/items/c2eee027ef307fe26b54

## v0.1 半手動版

### code

簡易版（半手動)を実装できた。　

```test161224.rb
require 'sketchup.rb'

def dokodoko(distance)
	model = Sketchup.active_model
	selection = model.selection.to_a
	faces = selection.grep(Sketchup::Face)

	flag = 0
	faces.each do |face|
		if flag == 0 then
			face.pushpull(distance)
			flag = 1
		else
			face.pushpull(-distance)
			break
		end
	end
end
```

### 使い方

http://qiita.com/7of9/items/ff5921cf65b5f88d9311#_reference-0b70faed1275d8553793
に記載のフォルダに上記のrbファイルを置く。

Rubyコンソールにて以下でスクリプトを読込む。

```
>load "test161224.rb"
true
```

ずらしたい立方体の「前面」と「後面」を選択する。

Rubyコンソールで以下のようにする。
(100.mmは移動距離)

```
> > dokodoko(100.mm)
```

### 移動例1

移動前
（この例では左側の面とその反対の面を選択してからdokodokoする)

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/5375ec4d-cccc-1d16-bf4f-d6662d2b6fed.png)

移動後

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/5859a605-27eb-1373-ab77-3a617768d4e5.png)

### 移動例2

以下の形状の真ん中をずらしてみた。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/311403b4-a269-6cc9-f1b9-51b15cdefbd7.png)

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/33444256-83e7-c5b9-5e06-cf18a17d2b4f.png)

あとはくっついている平面を削除して、移動された立方体をグループ化すると、個別のパーツとして扱うことができるようになる。
TrueOSを日本語環境で使うために注意すべき点

###始めに
----
TrueOS(&copy;Copyright 2011-2016, iXsystems)をインストールし日本語環境で用いようとしたのだがいくつか引っかかった点があったのでここに書き記す.

###キーボードの設定はインストール後,初期起動の設定でも行わないとログイン後の画面でUSキーボードだと認識されてしまう
----
- インストール時のキーボード設定はログインする前までしか効果がない。[\[1\]](https://www.trueos.org/handbook/install.html#language-selection-screen)
- 初回起動時の設定で設定すればログイン後まで反映された。

###ウィンドウのヘッダの日本語部分が文字化けする
----
- ~~おそらく~~バグ。[\[2\]](http://www.webzoit.net/hp/it/internet/homepage/env/os/bsd_unix_linux/fedora/x_wm_desktop/lumina.html)[\[3\]](https://github.com/trueos/lumina/issues/335)
- 設定&rarr;デスクトップ設定&rarr;ウィンドウマネージャのウィンドウのテーマを変えると治る。 &larr; なぜ治ったかは謎...
- 具体的にはBlueNightに設定したら治った。
- ~~このため,ウィンドウのテーマの問題であると考えられる。~~
- &uarr;Luminaの元となったFluxboxの方の問題らしい...
- &uarr;実はウィンドウテーマで設定されているフォントが日本語に対応していないせい
- 日本語に対応したフォントを使っているウィンドウテーマまたはウィンドウテーマのフォントを日本語に対応したものに変えれば治る

###日本語の漢字の表示に違和感がある
----
- デフォルトではCKJフォントが設定されている。
- ipaフォントやtakaboフォントを入れて設定することによって解決する。

###最後に
----
初投稿なので拙い部分もあると思いますがよろしくお願いします。

###参考文献
----
[1]:[4.1. Language Selection Screen(4. Installing TrueOS(&copy;Copyright 2011-2016, iXsystems.)-TrueOS(&copy;Copyright 2011-2016, iXsystems.) User Guide )](https://www.trueos.org/handbook/install.html#language-selection-screen)
[2]:[Fedora 23にデスクトップ環境Luminaをインストール](http://www.webzoit.net/hp/it/internet/homepage/env/os/bsd_unix_linux/fedora/x_wm_desktop/lumina.html)
[3]:[Window header can't show japanese text](https://github.com/trueos/lumina/issues/335)
整数型の大きさで関数をオーバーロードする方法

こんにちは。

[初心者C++er Advent Calendar 2016](http://www.adventar.org/calendars/1691#list-2016-12-23)の昨日の記事で[面白い問題](http://dev.activebasic.com/egtra/2016/12/23/939/)が上がっていたので、対策してみました。

記事ではuint8_t、uint16_t、uint32_t、uint64_tでオーバーロードした関数にDWORDを与えたらコンパイルエラーになってしまうとのこと。DWORDとuint32_tって同じものの筈なのでDWORDで呼び出せないって変ですね。

種明かしも記事にありました。Visual C++ではuint32_tはunsinged int、DWORDはunsigned longで定義されているので型が違うため、暗黙の型変換で曖昧になってしまうそうです。
なるほど。

関数テンプレートを[SFINAE](http://d.hatena.ne.jp/prettysoft/20101104/1399911110)して対策できます。
すっごい宣言が長ったらしくなるのでマクロで縮めました。C++11以上で通ります。
イネーブラが無い方がスッキリするので[nullptr_tテクニック](http://qiita.com/kazatsuyu/items/203584ef4cb8b9e52462)を使ってます。

```C++
#include <iostream>
#include <type_traits>
#ifdef __WIN32__
    #include <windows.h>
#else
    typedef unsigned long DWORD;
#endif

#define TEMPLATE(dType)                                                     \
    template                                                                \
    <                                                                       \
        typename tType,                                                     \
        typename std::enable_if                                             \
        <                                                                   \
            (sizeof(tType) == sizeof(dType)) &&                             \
            (std::is_signed<tType>::value == std::is_signed<dType>::value), \
            std::nullptr_t                                                  \
        >::type=nullptr                                                     \
    >

TEMPLATE(std::uint8_t)  void f(tType) {std::cout << "uint8_t\n";}
TEMPLATE(std::uint16_t) void f(tType) {std::cout << "uint16_t\n";}
TEMPLATE(std::uint32_t) void f(tType) {std::cout << "uint32_t\n";}
TEMPLATE(std::uint64_t) void f(tType) {std::cout << "uint64_t\n";}

int main()
{
    DWORD x = 12345;
    f(x);
}
```
Perl5.24をインストールする（ソースからコンパイル） for CentOS7.2

CentOS7.2のPerlは、v5.16.2がインストールされておりさほど新しいものではありません。昨今ではサーバー上でPerlを使うことは限定的になってきましたが、いまだに依存関係の多いアプリケーションは多く存在します。
この記事では、2017年4月現在の最新である、Perl v5.24.1をインストールする方法を記載します。

尚、OS標準のPerlと分けて管理するため、デフォルトのインストールパスである、「/usr/local」配下にインストールされます。


##インストール方法

```bash
cd /usr/local/src
wget http://www.cpan.org/src/5.0/perl-5.24.1.tar.gz
tar xvzf perl-5.24.1.tar.gz
cd perl-5.24.1

#コンパイルオプションをつける
export CFLAGS='-m64 -mtune=nocona'
./configure.gnu -des -A ccflags=-fPIC

#ビルドする
make
make install
```

##バージョン情報を確認する

```bash:
/usr/local/bin/perl -v


This is perl 5, version 24, subversion 1 (v5.24.1) built for x86_64-linux

Copyright 1987-2017, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
```

5.24.1と出ていればOKです。
SketchUp Make v17 / Ruby > 長方形を適当にプッシュプルするスクリプトを試してみた

```txt:動作環境
SketchUp Make v17.1.173
MacOS X El Capitan
```

関連 http://qiita.com/7of9/items/806f287f032e600b2fcd
関連 http://qiita.com/7of9/items/c2eee027ef307fe26b54

http://developer.sketchup.com/en/content/welcome
に書いているスクリプトは、実行すると選択した複数の長方形をランダムな長さにプッシュプルするようだ。

試してみた。　

```test161224.rb
require 'sketchup.rb'

def dokodoko
	model = Sketchup.active_model
	selection = model.selection.to_a
	faces = selection.grep(Sketchup::Face)

	faces.each do |face|
		face.pushpull(rand(20))
	end
end
```

http://qiita.com/7of9/items/ff5921cf65b5f88d9311
に記載した場所に上記のスクリプトを置いた。

SketchUpにて直方体を作り、その側面に適当な数の長方形を作成した。

その長方形を複数選択した状態にした。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/d6fa3834-6621-53ff-d61c-61e3502a6fd6.png)

Rubyコンソールにて以下を実行した。

```
> dokodoko
[#<Deleted Entity:0x7fcfabe13048>, #<Deleted Entity:0x7fcfabe13020>, #<Deleted Entity:0x7fcfabe12ff8>, #<Deleted Entity:0x7fcfabe12f80>, #<Deleted Entity:0x7fcfabe12f58>, #<Deleted Entity:0x7fcfabe12ee0>, #<Deleted Entity:0x7fcfabe12eb8>]
```

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/d8dc2f0c-f286-2d53-4201-9dc05b3ce741.png)
表示改善を始める前に~HTTPリクエストの概要~

googleさんのツール、[PageSpeed Insights](https://developers.google.com/speed/pagespeed/insights/?hl=ja)を使用した表示改善を行うにあたって、事前に調べたことがあったのでこの機会に頭の整理がてらメモしておきます。何か参考になれば幸いです。

## はじめに
httpとはなんなんだというところに簡単に触れます。
HTTPは、 「Hyper Text Transfer Protocol」の略で、WWW(World Wide Web)上でWebサーバとクライアントが、 HTML(Hyper Text Markup Languageの略＝Webページを記述するための言語)で書かれた文書などの情報をやりとりする時に使われる通信手順(プロトコル)を意味している、、みたいな感じでいろんな本では描かれていると思います。まあこういうものらしいです、webの歴史のおおまかなイメージがつきやすいのかなと思うので載せておきます→[意外と知らないwebの歴史](https://www.internetacademy.jp/special/history.html)
これを聞くと「あれ？httpsってものなかったっけ？」と思う人がいると思うので[「http」と「https」の違いとは？ 最後の「s」はあなたを守る魔法の言葉だった](http://time-space.kddi.com/ict-keywords/kaisetsu/20160311/index.html)を読んで簡単なイメージを持ってください。


## 全体像
<img width="676" alt="スクリーンショット 2016-12-24 16.07.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/74580/f0cf521f-6d1d-4d75-67ce-545fce0ccda0.png">

　④で最後のデータの受信が完了したところまでが「とあるページ」が表示されるまでの流れのやり取りになっています。

## 詳細
全体像でどういう感じのやり取りが行わられているのかはイメージつくと思いますので次は文章で各々を説明していきます。

#### ① DNS Lookup(名前解決)
ブラウザのURLバーにURLを打ち込んでアクセスする。そのページを見にいくということはつまり、そのURLに対してHTTPスキームでリクエストします。クライアントであるブラウザは入力されたURLを判断して、viewのファイル（htmlファイル）を要求します。この時URLとのドメインは人間が覚えやすいように勝手につけた名前なので、ブラウザはこれだけだとviewを描画するファイルに到達することができません。そこでそのドメインをIPアドレスに変換する。これをDNS Lookup(名前解決)と言います。


#### ② Connecting(ソケット接続)
IPアドレスがわかるとサーバーに接続しようとします。この時にクライアントは「サーバーさんはいますか？」と尋ねてサーバーは「いますよ」と答える。このやりとりをConnectingといい、いわゆるソケット接続が確立することを指します。

#### ③ Waiting
サーバーとの接続が確立したので、ここでやっとHTTPリクエストを要求します。このとき、動的ファイルの場合だとファイル生成などプロセスが走る。そのあと見つけた・生成したファイルをクライアントに送信する。送信した最初のパケットがクライアントに届いた時点までが、Waitingという時間になる。

#### ④ Receiving
そして最後のパケットが送り終えた時点までが、Receivingという時間になる。ここがいわゆるファイルのダウンロード時間にかかる時間。

#### ツール
これらのタイミングにかかる時間はGoogle ChromeのDeveloper ToolsのNetworkパネルTimingタブで確認できる。


##　まとめ
HTTPリクエストの中身を確認して言えることは、クライアントとサーバーとのやりとりにかかる時間、①〜③までをラウンドトリップタイム(RTT)と、④をダウンロードにかかる時間（DL）が表示速度という面では重要であると思います。


### おまけ
ちなみにこういう速度の問題が出た時にネイティブアプリにしようという意見が出てくることがあるがその理由はここにありました。ネイティブアプリは初回のアプリダウンロードで、アプリ内にリソースがまとめているので、このようなことは気にしなくてもほぼ良いらしいです。しかしWebアプリとなると、いかにサーバーとクライアントのやりとりを減らすか、がボトルネックとなります。特にRTTに関しては、根本的に改善するにはサーバーをユーザーの近くに置くことしかできないので、フロントエンドをいじる時はラウンドトリップさせないということが重要になってきそうですね。


参考記事
[http（通信プロトコル）とは？httpの仕組みと、通信内容（リクエストヘッダとレスポンスヘッダ）の確認手順まとめ](http://viral-community.com/other-it/http-1873/)
[1週間で学ぶネットワークの要点](http://itpro.nikkeibp.co.jp/article/COLUMN/20000518/200024/)
SketchUp Make v17 / Ruby > Rubyコンソールにスクリプトを読込む / Face追加スクリプトの実行

```txt:動作環境
SketchUp Make v17.1.173
MacOS X El Capitan
```

関連 http://qiita.com/7of9/items/806f287f032e600b2fcd
関連 http://qiita.com/7of9/items/c2eee027ef307fe26b54

## スクリプトの読込み

SketchUpにてRubyスクリプトを実行しようとしている。

スクリプトを読込むには`load myscript.rb`のようにして読込む必要がある。
その読込みをするには指定の場所にrbファイルを置くことになる。

参考 http://help.sketchup.com/en/article/38583
> Version 2013 and newer: Open a new Finder window, press and hold the Option key on your keyboard, the click Go in the menu bar > Library > Application Support > SketchUp # > SketchUp > Plugins

こちらの環境での置き場所は以下だった。

Library > Application Support > SketchUp 2017 > SketchUp > Plugins

以下のファイルを置いた。

```test161224.rb
print("Hello")
```

SketchUpの「Rubyコンソール」で読込んでみた。

```txt:結果
> load "test161224.rb"
Hellotrue
```

trueという文字が表示されてしまっているが、とりあえず読込みはできた。

## 日本語ヘルプのミス?

ちなみに、日本語ヘルプの方は置き場所の記載が古いのか、英語ヘルプと異なる。
https://help.sketchup.com/ja/article/38583
> Mac OS X - デフォルトの場所は次のとおりです。
[あなたのユーザー名]/Library/Application Support/Google SketchUp #/SketchUp/plugins

SketchUp Make v17の場合は「Google SketchUp #」というフォルダはありません。


## v0.2 draw face

http://developer.sketchup.com/en/content/new-ruby
の「Moving On, Adding a Face!」を試した。

```test161224.rb
def drawFace
	point1 = [0,0,0]
	point2 = [100,100,100]
	point3 = [0,100,100]
	model = Sketchup.active_model
	entities = model.active_entities
	entities.add_face(point1, point2, point3, point1)
end
```

```
> load "test161224.rb"
true
```

これで　drawFaceというメソッド?が追加される。
あとはdrawFaceを実行すればいい。

```
> drawFace
#<Sketchup::Face:0x007fcfabe85850>
```

三角形が出現した。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/00a8e62f-876b-505c-6bc1-6b73ee98e809.png)
マイクロソフトの人工知能をSmalltalkで

# はじめに
以前、Smalltalk勉強会にてSORABITOの吉田さん(@newapplesho)が即興で[Google Cloud Vision API](https://cloud.google.com/vision/)を使った画像認識をライブプログラミングされて面白かったのですが、それに対抗してマイクロソフトの人工知能サービスを [Pharo Smalltalk](http://pharo.org/) で使ってみました
なお、人工知能サービスについては以下の記事が元ネタです。
>[人工知能パーツ Microsoft Cognitive Services を使った表情分析アプリを作ろう！ (Emotion API × JavaScript 編)](http://qiita.com/annie/items/96b37ef94885510c1b6b)

Microsoft Cognitive Services は以前 Project Oxford と呼ばれていた一連のAPI(顔画像から年齢を算出するとかありましたよね)と他のサービスを整理して統合したもののようです。

# 準備
API呼び出しに必要なサブスクリプションキーを取得します。
Cognitive Services では複数のサービスが提供されているので、利用するサービスごとに登録(サブスクリプト)してサブスクリプションキーを取得します。
取得は以下の手順で行いますが、詳細は[人工知能パーツ Microsoft Cognitive Services を使った表情分析アプリを作ろう！[サブスクリプション準備編]](http://qiita.com/annie/items/ba6392b7d1a7647adc4b)を参考にしてください。

1. (マイクロソフトアカウント取得) (持ってない場合)
2. Cognitive Services サブスクリプションの登録
3. サブスクリプションキーの取得

# 使ってみる
今回は Emotion API を使ってみました。
これは画像の表情を分析して感情因子を弾き出すものです。
なので、顔の画像のURLを用意して実験します。
まずはWikipediaに掲載されてたモナリザで試してみます。
![モナリザ](https://upload.wikimedia.org/wikipedia/commons/thumb/a/a9/Mona_Lisa_detail_face.jpg/467px-Mona_Lisa_detail_face.jpg)

以下にコードを示します。
imageUrl変数に画像のURLを代入し、コード中のXXXX_XXXX_XXXXの箇所を準備で取得したサブスクリプションキーで置き換えます。

```smalltalk:
| imageUrl client |
imageUrl := 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a9/Mona_Lisa_detail_face.jpg/467px-Mona_Lisa_detail_face.jpg'.
client := ZnClient new.
client headerAt: 'Ocp-Apim-Subscription-Key' put: 'XXXX_XXXX_XXXX'.
client url: 'https://api.projectoxford.ai/emotion/v1.0/recognize'.
client contents: ('\{Url: ''{1}''\}' format: {imageUrl }).
client contentType: 'application/json'.
client contentReader: [ :entity | STON fromString: entity contents ].
client post first.
```

これをinspectすると以下の結果になりました。
![mona-liza.png](https://qiita-image-store.s3.amazonaws.com/0/13174/7b4b4072-5cfb-b434-1dd4-0288d515829d.png)

概ね neutral (0.68) で happiness が (0.30)という辺りが「謎の微笑み」たるところでしょう。

ちなみに御大では
![アラン・ケイ](http://www.westatic.com/img/dict/binbi/biaa001.png)

![alan-kay.png](https://qiita-image-store.s3.amazonaws.com/0/13174/ab543998-f2e6-c73f-f8a7-dc5f0d943b9c.png)

hapiness 0.9999999
幸せ全開でした。

# おわりに
あとはアプリに組み込むだけですが
サーバーアプリならばSeasideのコンポーネントに。
(http://www.seaside.st/)

また Roassal と組み合わせたビジュアライゼーションも面白そうです。
(http://agilevisualization.com/)

なお、Cognitive Services には Emotional API 以外にもサービスがあるので色々試してみたいところです。
(https://azure.microsoft.com/ja-jp/services/cognitive-services/)

以上
jsonでスクレイピングできるnode_module作りました

# Nightmare

いまいち、Nightmareがスクレイピングに向かない部分があり、jsonでスクレイピングできるようになるnode_module、[The Fool](https://github.com/ito-p/the-fool)を作りました。

`npm install the-fool`

Nightmareって、すごいシンプルなAPIになってるんですけど、
やっぱりテスト用のツールなので、メソッドチェーンでシーケンシャルにテストするために作られてるんですよね。

公式から抜粋ですが、phantomだと20行かかっていたものが、4行になりました。

## Phantom(20行)

```js
phantom.create(function (ph) {
  ph.createPage(function (page) {
    page.open('http://yahoo.com', function (status) {
      page.evaluate(function () {
        var el =
          document.querySelector('input[title="Search"]');
        el.value = 'github nightmare';
      }, function (result) {
        page.evaluate(function () {
          var el = document.querySelector('.searchsubmit');
          var event = document.createEvent('MouseEvent');
          event.initEvent('click', true, false);
          el.dispatchEvent(event);
        }, function (result) {
          ph.exit();
        });
      });
    });
  });
});
```

## Nightmare(４行)
```
yield Nightmare()
  .goto('http://yahoo.com')
  .type('input[title="Search"]', 'github nightmare')
  .click('.searchsubmit');
```

# もっと自由にスクレイピングしたい

メソッドチェーンだと、欠点として、プログラマブルに内容を変えるのに苦労しますね。
しかもnightmareの中身は、メソッドによって自身を返したりPromiseのように見える何かを返していたりと、
メソッドチェーンを途中で区切ってごにょごにょしてから何かする、というような自由度が少ないんですね。

何が言いたいのかというと、ぶっちゃけ**テストじゃなくてスクレイピングしたいんですよ**世の名の大半の人達は。

https://github.com/ito-p/the-fool

## The Fool(実行は1行)
```js
const data = {
  data: [
    ["goto", "https://www.google.co.jp/"],
    ["type", "input[title='Search']", "github nightmare"],
    ["click", ".searchsubmit"]
  ]
};

const fool = new Fool();

yield fool.travel(data);
```

これで順番を組み替えたり取得してきたデータから処理を変えたり自由自在ですね。

# その他

連続してデータをとりたい場合は、coやvoを使いましょう。
wrapができるcoのほうが僅かにおすすめです。

https://github.com/tj/co

the-foolの中にexample用意しました。
そこでco使って直列なスクレイピングをしています。

# 注意

使用は自己責任でお願いします！
MacユーザならWindow Makerでしょ

[MacユーザがPC自作してFreeBSD入れてみた](http://qiita.com/tenomoto/items/4774eaf16c5aa4cdd64c)の続き。

# キーボード

MacのJISキーボードはaの左はctrlなのでCaps Lockと入れ替えます。コンソール
では、rc.confに書くだけです。

```/etc/rc.conf
keymap="jp.capsctrl"
```
追記: jp.106xと書いていたのですが、capsctrlと書けと警告でました。

# pkg

FreeBSDのパッケージ管理は10.0-RELEASEからpkgです。

* [BSD界隈四方山話 第2回　パッケージ管理システム「pkg 1.5」と基本的な使い方](http://gihyo.jp/admin/serial/01/bsd-yomoyama/0002)
* [pkg によるバイナリ package の管理](https://www.freebsd.org/doc/ja_JP.eucJP/books/handbook/pkgng-intro.html)

## su

ルート権限が必要なのですが、suでスーパーユーザになれないときは、wheelグループに一般ユーザを追加します。viで編集してしまいましたが、pw(8)が用意されています。

* [グループの管理](https://www.freebsd.org/doc/ja_JP.eucJP/books/handbook/users-groups.html)

## sudo

FreeBSDはMacやLinuxとは異なり、標準でsudoは入っていませんので、pkgでsudoをインストールして/etc/sudoersをvisudoで編集します。

```
# pkg install sudo
# visudo
```

wheelグループのユーザがsudo権限を持つように設定しました。

```
%wheel ALL=(ALL) ALL
```

# ウィンドウマネージャ

## Intel統合グラフィクス

グラフィックカードは搭載しなかったので、CPU内蔵のものを使うことになります。

[Wiki](https://wiki.freebsd.org/Graphics)によると、残念ながらSkylakeには対応していないようです。[ASUS VX24AH](http://amzn.to/2hblBly)を使っていますが、コンソールではWQHD (2560 x 1440)で表示されています。

### SCFB

対応していない場合用のSCFBだと粗い解像度になりました。戻す場合はi915カーネルをロードします。

```
# kldload i915
# kldload i915kms
```

### Window Maker

Cinnamonを試してみましたが、落ちてしまいました。cinnamon-session-cinammon2dで起動しても良かったのですが、macOSの先祖NextSTEPを模した[Window Maker](http://windowmaker.org)を試すことにしました。

Window Makerはデスクトップ環境ではなく、ウィンドウマネージャです。GNUStepとの[関係](http://www.gnustep.org/information/wm.html)に書いてありますが、Window MakerでもGNOMEやQtベースのアプリケーションは動きます。Firefox, LibreOffice, [Shotwell](https://wiki.gnome.org/Apps/Shotwell), [Leafpad](http://tarot.freeshell.org/leafpad/)を入れました。

```
$ sudo pkg install firefox
$ sudo pkg install ja-libreoffice
...
```

日本語フォントもいろいろと用意されていてja-libreofficeと一緒にインストールされますが、IPAexフォント（ja-font-ipaex）を入れました。

なお、cinammonを削除したあと、不要なパッケージはautoremoveで一括削除しました。

```
$ sudo pkg delete cinammon
$ sudo pkg autoremove
```

## 日本語入力

日本語入力はibus + mozcに落ち着きました。私にとっては、かな入力が快適にできることが必須。fcitxは起動時にエラーが出るなど上手に設定できませんでした。uimはmozcで設定したかな入力がアプリケーションを起動するとローマ字入力に戻ってしまい断念しました。ibusの起動はSuper + Spaceです。設定で如何様にもなるのですが、既定がMacと同じなのには好感を持ちました。

``` ~/.xinitrc
export LANG=ja_JP.UTF-8
export GTK_IM_MODULE=ibus
export QT_IM_MODULE=xim
export XMODIFIERS=@im=ibus
/usr/local/bin/mozc start
ibus-daemon -r --daemonize --xim

exec wmaker
```

Caps LockをCtrlにしてCaps Lockは無効にします。入れ替える場合はctrl:swapcapsにします。Command + Spaceをさらに快適にするため、Alt (Option)とCmdを入れ替えます。複数のOptionはコンマで区切ります。xkeyboard-config (7)にキーボードの種類や様々なOptionが示されています。

ついでにスクロールを逆向きにしておきます。

```/usr/local/etc/X11/xorg.conf.d/input.conf
Section "InputClass"
    Identifier "keyboard defaults"
    MatchIsKeyboard "on"

    Option "XkbModel"  "jp106"
    Option "XkbLayout" "jp"
    Option "XkbOptions" "ctrl:nocaps,altwin:swap_lalt_lwin"
EndSection
Section "InputClass"
    Identifier "natural scrolling"
    MatchIsPointer "on"

    Option "ZAxisMapping" "5 4"
EndSection
```

Window Makerはウィンドウマネージャなのでウィンドウやデスクトップに関する設定はありますが、日本語入力の設定のようなものはありません。mozcの設定ダイアログは

```
$ mozc_tool config_dialog
```

で起動します。無変換、変換キーでIMEのオフ、オンをするようにしました。ibusの設定はibus-setupです。
Amazon LinuxでDocker版のHDP Sandboxを立てるTIPS

HDPのサンドボックスのコンテナは13GBあるので、Dockerコンテナのストレージサイズのデフォルト値である10GBだと足りない。なのでDockerのコンフィグファイル`/etc/sysconfig/docker`にあるdocker daemonの起動オプションに下記を追記してやる。

```
--graph='/mnt/docker-data' --storage-driver=overlay --storage-opt=dm.basesize=30G"
```

デフォルトでいろいろ書いてあるので、足すと以下のように。

```
OPTIONS="--default-ulimit nofile=1024:4096 --graph='/mnt/docker-data' --storage-driver=overlay --storage-opt=dm.basesize=30G"
```

ソースはこちら。systemdを採用しているディストリビューションでの設定方法もこちら。
https://community.hortonworks.com/content/kbentry/65714/how-to-modify-the-default-docker-configuration-on.html
デザインパターンをJavaScriptとJavaでの実装を比較して理解する【随時更新】

#はじめに
大学の研究室でデザインパターンをPythonで書くことになりました。
だがデザインパターンもちゃんと理解できていないのに、Pythonで書けないと感じました。
なので、Javaと好きなJavaScriptでのデザインパターンを比較して理解していこうと思います。
全てのパターンをこの記事に書くと長くなってしまうので、パターンごとに記事を作り下の表を埋めていく形にしていきます。

※パターン名がリンクになっています。


#デザインパターンとは
ソフトウェアの設計でよく起こる問題を解決し、再利用可能にする慣例
GoF(Gang of Four)の23種類のデザインパターンが有名である
GoFは『エーリヒ・ガンマ』『リチャード・ヘルム』『ラルフ・ジョンソン』『ジョン・ブリシディース』の4人
『オブジェクト指向における再利用のためのデザインパターン』でデザインパターンとうい用語を初めてソフトウェア開発に導入した

#デザインパターンのカテゴリー
デザインパターンはさまざまな視点から分類することができる
##生成に関するパターン
**オブジェクトを作成する仕組みに着目し、オブジェクト生成の過程を制御することによって、問題を解決する**

|パターン名|概要|
|:---------|:----|
|Factory Method|渡されたデータやイベントをもとに派生クラスのインスタンスを作成する|
|Abstract Factory|具象クラスの細部を明らかにせずにクラスのインスタンスを作成する|
|Builder|オブジェクトの作成過程を表現形式と切り離す。常に同じタイプのオブジェクトを作成する|
|Prototype|コピーの際に、完全に初期化されたインスタンスを利用する|
|**[Singleton](http://qiita.com/Kurowasi/items/797cd555606bb1240d38)**|グローバルからアクセスできるインスタンスが一つしかないクラス|
##構造に関するパターン
**オブジェクトの合成に関するもので、異なるオブジェクト間の関係性をわかりやすくするために使われる**

|パターン名|概要|
|:--|:--|
|Adapter|異なるクラスのインターフェイスを対応させて、インターフェイスが対応していないクラス同士でも組み合わせて使えるようにする。|
|Bridge|オブジェクトのインターフェイスを実装から切り離し、インターフェイスと実装をそれぞれ独自に変更できるようにする|
|**[Composite](http://qiita.com/Kurowasi/items/b0123d20e052cb0bff44)**|個々のオブジェクトとオブジェクトを合成したものの構造を一様に扱うことで、別々に扱うよりも多くのことができる|
|**[Decorator](http://qiita.com/Kurowasi/items/82b98c246043a6649fbc)**|オブジェクトに動的に処理を追加する|
|Facade|一つのクラスがサブシステム全体の複雑性を隠蔽する|
|Flyweight|いたるところで使われている情報を効率的に共有するために、小さなサイズのインスタンスを利用する|
|Proxy|本物のオブジェクトの代わりとなる代理オブジェクト|

##振る舞いに関するパターン
**システム内の異なるオブジェクト間の通信を改善簡素化することに着目した**

|パターン名|概要|
|:--|:--|
|Interpreter|アプリケーションに言語的要素を追加し、対象とする言語の文法に対応する
|Template Method|メソッド内にアルゴリズムのかたまりを作り、サブクラスへのステップを遅延させる|
|Chain of Responsibility|一連のオブジェクトの中でリクエストを順番に渡していき、その要素を対処できるオブジェクトを見つける方法|
|Command|コマンドの実行動作をコマンドを発行する立場から切り離す|
|**[Iterator](http://qiita.com/Kurowasi/items/d517ab932a5c003dfea1)**|コレクションの内部動作について知ることなく、そのコレクションの要素に順番にアクセスしていく|
|Mediator|クラス間のやり取りを簡素化し、クラス同士が直接参照し合うのを防ぐ|
|Memento|オブジェクトの内部状態を記録し、後でそれを復元できるようにする|
|Observer|変更をたくさんのクラスに通知し、クラス間の一貫性を保証する方法|
|**[State](http://qiita.com/Kurowasi/items/8d5a981a6f5c2ddd2976)**|状態が変わった時にオブジェクトの振る舞いを変える~
|**[Strategy](http://qiita.com/Kurowasi/items/1d48aa45b99a63d11bb2)**|クラス内部のアルゴリズムをカプセル化し、アルゴリズムの選択をクラスの実装から独立させる|
|Visitor|クラスを変更することなく、そのクラスに新たなオペレーションを追加する|


#参考
[増補改訂版Java言語で学ぶデザインパターン入門](https://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88Java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80-%E7%B5%90%E5%9F%8E-%E6%B5%A9/dp/4797327030)
[JavaScriptデザインパターン](https://www.oreilly.co.jp/books/9784873116181/)
Gebで何かに困ったら？

# はじめに

これは[Geb Advent Calendar 2016](http://qiita.com/advent-calendar/2016/geb)の24日目の記事です。
今日は困った時の相談窓口の話。

# Gebで何かに困った時の相談窓口
困ったらこのあたりに質問を投げてみましょう。公式・非公式と一応つけましたが、Gebの中の人が実際に運営しているものは公式と表記しています。

## 英語の窓口
### Gebのユーザーメーリングリスト（公式）
本家のユーザーメーリス。英語ができるならここに質問するのがいちばんかたいです。ちなみに誰かが投げた質問への回答にもTIPsが多く含まれているので、購読しておくのをオススメします。
https://groups.google.com/forum/#!forum/geb-user

### Gebの開発メーリングリスト（公式）
Gebにコントリビュートしたいのけど困りごとができた。という時はこちらです。
https://groups.google.com/forum/#!forum/geb-dev

### stack overflow（非公式）
こちらに質問を投げてもよくコミッタの人が拾ってくれてます。でも本家のメーリスの方が圧倒的に回答早いです。コードをたくさん貼り付けるならこっちの方がわかりやすいかな？という印象です。
http://stackoverflow.com/questions/tagged/geb

## 日本語の窓口（非公式）
### 日本Seleniumユーザーコミュニティのメーリングリスト
そのものズバリではないのですが、Geb使いの人が何人か見ています。日本語で質問したいならここで。
https://groups.google.com/forum/#!forum/seleniumjp

### 日本SeleniumユーザーコミュニティのSlack
こちらもGebそのものズバリではないのですが、Slackチャットで相談できます。複数のGeb使いを観測しています。私も出入りしています。
https://seleniumjp.herokuapp.com/

# おわりに
おそらく精度の高い回答を得たいのであれば、本家のメーリスが良いと思います。中の人自身、英語が母語ではなかったと記憶しているので、あまり気負わず相談しちゃいましょう！
そうはいっても英語ハードル高いよって思うこともあるかもしれません。そんな時は日本語窓口もどうぞー。
[Mackerel] ERROR <command> Error while updating host specs: API error. status: 404, msg: api request failed

packerで作成したAMIからインスタンスを立ち上げたところ、そのホストがmackerelのhostsリストに出てこないというのがあった
ログをみるとmackerel-agentは起動しているが、mackerel.ioとのやりとりがうまくいってなさそうだった

```
$ less /var/log/mackerel-agent.log

...

2016/12/24 14:52:23 ERROR <command> Error while updating host specs: API error. status: 404, msg: api request failed
```

設定を確認しても問題なしと出る

```
$ sudo /etc/init.d/mackerel-agent configtest
 * Testing configuration of mackerel-agent                    [ OK ]
```

エラーメッセージを見てもよくわからない感じだったので雑に検索したところ同じメッセージに遭っているポストを見つけた

- [:-): Error while updating host specs: API error. status: 404, msg: api request failed, 劇場版アイカツスターズ！ を見てきた(2回目), 椅子を洗った, 散歩 - ヨタの日々(2016-08-19)](http://www.area51.gr.jp/~rin/diary/?date=20160819)

原因がわかった

> ホストID: Mackerelは各ホストをホストIDで識別します。

packerとmackerelを一緒に使うときはこの辺をケアしておく必要があった

## 原因

- packerでAMIを作ったとき
  - シャットダウン時にそのホストを退役させてしまっている
  - しかしホストIDファイル(`/var/lib/mackerel-agent/id`)が残ってしまっている

退役済みのホストIDファイルをもつAMIを作ってしまっていた

## 対応

#### とりあえずの対応

`/var/lib/mackerel-agent/id`を消して再起動

```
$ sudo rm /var/lib/mackerel-agent/id
$ sudo /etc/init.d/mackerel-agent restart
```

無事にhostsに出てきた

#### 正しい対応

packerでAMIを作る際にホストIDファイルを消しておく
CakePHP3 Find使い方

#Finderをカスタマイズ
コントローラーでFindのMethod名を入力
findの最初のパラメータにMethod名を決める。

##find('XXX')に名前を指定した場合、コントローラーはTableに「findXXX」名のMethodを追加して実装する必要があります。
例）タグしたBookmark情報を取得したい場合taggedと言う名前を入力した場合
コントローラーはBookmarksTableに「findTagged」名のMethodがあるか探して実行する。

コントローラーは単純にTableのデータ取得Methodを呼ぶだけ。　
実際データを作る役はTableが担当。Method名もfindXXX形式になるので見やすい。
以下のソースはCakePHP公式サイトから参考

```php:BookmarksController.php
    public function tags() {
        $tags = $this->request->params['pass'];
        $bookmarks = $this->Bookmarks->find('tagged', [
            'tags' => $tags
        ]);
        $this->set([
            'bookmarks' => $bookmarks,
            'tags' => $tags
        ]);
    }
```

#モデル（Table)に上記の名前でMethod定義

```php:BookmarksTable.php
       public function findTagged(Query $query, array $options){

        return $this->find()
            ->distinct(['Bookmarks.id'])
            ->matching('Tags', function($q) use($options) {
           if(empty($options['tags'])){
               return $q->where(['Tags.title IS' => null]);
           }
           return $q->where(['Tags.title IN' => $options['tags']]);
        });
    }
```

こんな感じで実装すればコントローラーは簡単、実際ロジックはTableで実装するため見やすくなりそう
以下参考
http://book.cakephp.org/3.0/ja/index.html
js シーザー暗号(ROT13)

##お題
アルファベットに対してのシーザー暗号（ROT13）の関数をつくる

[*シーザー暗号](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%BC%E3%82%B6%E3%83%BC%E6%9A%97%E5%8F%B7) Wikipedia
シーザー暗号は単一換字式暗号の一種で、平文の各文字を、辞書順に3文字分シフトして暗号文を作る暗号。現代でもシフト数を13にした方式としてROT13が使用されることがある。

```script.js
function rot13(str) {
//write your code
}
rot13("URYYB JBEYQ!");
```

##出力結果　例

```script.js
("SERR CVMMN!") // "FREE PIZZA!"
("SERR YBIR?") // "FREE LOVE?"
("GUR DHVPX OEBJA QBT WHZCRQ BIRE GUR YNML SBK.") // "THE QUICK BROWN DOG JUMPED OVER THE LAZY FOX."
```

##主に使ったもの
[charCodeAt()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt)
[fromCodeAt](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode)
[map()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
split()
join()
[ASCII](https://ja.wikipedia.org/wiki/ASCII)

##考え方
・split()で文字列を一文字切り離す。
・切り離した文字ひとつひとつにmap()で同様の処理を繰り返す。
・処理する文字を変数に入れて、大文字のアルファベットであるかどうか判定する。
　ASCIIにて、Aは65、Zは90。(x < 65 || x > 90)
　当てはまらないものはfromCodeAtで返す。
・大文字のアルファベットで
　(x < 78)はfromCodeAtで+13して返す。
 残りはfromCodeAtで-13して返す。
・最後にjoin('')で一緒にしておわり。

##コード

```script.js
function rot13(str) {
  return str.split('')
    .map.call(str, function(char) {
      x = char.charCodeAt(0);
      if (x < 65 || x > 90) {
        return String.fromCharCode(x);  
      }
      else if (x < 78) {
        return String.fromCharCode(x + 13);
      }
      return String.fromCharCode(x - 13);
    }).join('');  
}
rot13("SERR PBQR PNZC");
```

##大文字小文字対応のコード

```js
function rot13(str) {
  var i =[]; 
  i = str.split('');
  return i.map.call( i,function(char) {
      x = char.charCodeAt(0);
      if ((65 <= x && x < 78) || (97 <= x && x < 110)) {
        return String.fromCharCode(x + 13);
      }
      else if ((78 <= x && x <= 90) || (110 <= x && x <= 122) ) {
              return String.fromCharCode(x - 13);
      }
    return String.fromCharCode(x);  
    }).join('');  
}
rot13("Uryyb Jbeyq!");
```


##正規表現を使ったコード

```js

function rot13(str) { 
  return str.replace(/[A-Z]/g, (L) => String.fromCharCode(65 + (L.charCodeAt(0) - 65 + 13) % 26));
}
```

###他にもコードが浮かんだ方、コメントお待ちしてます。
2016年末版Web画面で作成するページのプレビューを同一ページ内で安全に行う方法

なんかタイトルがややこしくなってしまいましたが、例えば[このようなBootstrapを利用した画面デザインツール](http://jirokun.github.io/EPD/dist/)で実現しているプレビュー画面と、デザイン画面を実現する方法を紹介します。右側が設定パネル、中央に表示されている箇所がプレビュー画面です。

デザイン画面とプレビュー画面を同一のページに組み込もうと思うとデザイン画面のCSSがプレビューにも影響してしまい、
かなり気をつけて作らないと思った通りのプレビュー画面になりません。

この機能を実現する方法は3つあります。

1. iframeを使用する
2. Shadow DOMを利用する
3. CSS modulesを利用する

## iframeを利用する
iframeを利用する方法は比較的昔から取られている方法です。間違いなく親フレームのCSSの影響を排除することができます。
しかし、親フレームからiframeのエレメントを操作しなければいけないので、操作が煩雑になることが難点です。

上記のデメリットを克服するために、React.jsの[react-frame-component](https://github.com/ryanseddon/react-frame-component)を使えば下記のように親ページにレンダリングしているかのように使用できます。React.jsを使ってアプリを作っているのであればおすすめのライブラリです。

```js
var Header = React.createClass({
  render: function() {
    return (
      <Frame>
        <h1>{this.props.children}</h1>
      </Frame>
    );
  }
});

React.render(<Header>Hello</Header>, document.body);
```

このライブラリで楽は出来るようになるものの、D&Dをしたくなった場合なども考えると、辛い選択肢ではあります。

## Shadow DOMを利用する
Shadow DOMを利用すればiframeを用いなくても良くなります。本当であればこれを使いたい。
しかし、[Can I use](http://caniuse.com/#search=shadow%20dom)を見れば分かる通り壊滅的な状況です。これが使えるようになるのはまだまだ先のよう。ブラウザを限定できるならありかもしれません。

## CSS modulesを利用する
先程紹介した[Bootstrapを利用した画面デザインツール](http://jirokun.github.io/EPD/dist/)を作成したことにはなかった選択肢です。
CSS modulesを利用するとグローバルに定義されるCSSのクラス名をいい感じにかぶらないようにしてくれます。
ただし、かぶらないようにしてくれるのはクラス名だけなので、タグに対してスタイルが設定されていると影響を受けてしまいます。つまりかなり気をつけてスタイルを設定した画面でのみ、実現可能な方式です。

例えばBootstrapのCSSを読んでいた場合には、それだけでBootstrapの影響を受けてしまいます。
また、デザイナーさんと協業する場合にCSS modulesが受け入れられるかも気になります。

## 結論
運用フローなどの問題はあるものの、
特定のページでのみプレビューを表示したいのであればCSS Modules、
様々なページでプレビューを表示したいのであればiframeといったところが結論でしょうか。

はやくShadow DOMがすべてのブラウザでサポートされるようになって欲しいです。
Webpackを用いて、Railsにreactの導入


## 前提
SPAではなくて、DOMの操作をjavascriptでやらなければいけない箇所でのみ、導入。主に検索ページのみを考える。

検索ページでは、SEOを考慮するため、SSRもやってみる。

## 導入方法の検討

クックパッドさんのブログにまとめらている
http://techlife.cookpad.com/entry/2016/07/27/101015


おそらく手軽にやるには、react-railsなのかな？と思いましたが、
今後の発展（SPA）等、もしくは削除を考えるとrailsと切り離して導入したいと思って、webpackを用いて導入しました。

## 導入
### npmを使ってパッケージのインストール

（私は）railsのroot directory配下にpackage.jsonを作成しました。

```
$ npm init
```

トランスコンパイラのbabelだったり、reactをインストール

まずはreact。saveをつけて、package.jsonを更新。

```
$ npm install --save react react-dom
```

webpackと、開発環境で起動し、随時トランスコンパイルしてくれるdev serverもインストール

```
$ npm install --save-dev webpack webpack-dev-server
```

トランスコンパイラのbabel系絡みをインストール。jsxを使いたいのでbabel-preset-reactも。こちらは開発環境に必要なものなので、--save-dev

```
$ npm install --save-dev babel-loader babel-core babel-preset-react babel-preset-es2015
```


### webpack.configファイルの作成
入力ファイル（jsxファイル等）の指定や、出力ファイルの指定をここで行う。
私の環境では、{Rails.root}/src/javascripts/startup/bundle.jsxに大元の記述をしました。
出力ファイルはSSRをするので、railsの世界に入れるため、app/assets/webpack配下に配置しました。

```webpack.dev.js
const path = require('path');
const webpack = require('webpack');

module.exports = {
  entry: {
    "webpack-bundle": './src/javascripts/startup/bundle.jsx',
  },
  output: {
    path: 'app/assets/webpack',
    filename: '[name].js',
    publicPath: 'http://localhost:8080/' // webpack-dev-serverのURLを指定する
  },
  module: {
    loaders: [
      {
        test: /\.js[x]?$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        query:{
          "presets":["react","es2015"]
        },
      },
    ],
  },
};
```

### package.jsonの編集
scriptsのところに、以下のように実行コマンドを追記。

```package.json
"scripts": {
  "webpack": "webpack --config webpack.config.prod.js --progress --colors",
  "dev": "webpack -w --config webpack.config.dev.js"
}
```

### webpackの起動
```
npm run dev
```

## Server Side Renderingの設定
こちらは、Gemfileにreact_on_railsを追加
https://github.com/shakacode/react_on_rails

```
gem 'react_on_rails'
```

### Initializerの編集

```
bunlde install
rails generate react_on_rails:install
```
config/initializers/react_on_rails.rbを編集する。
主に自分の環境に合わせて以下を編集

```react_on_rails.rb
config.generated_assets_dir = File.join(%w(app assets webpack))
config.webpack_generated_files = %w( webpack-bundle.js )
config.server_bundle_js_file = "webpack-bundle.js"
```

### 実装
あとはrailsのviewで、react_componentメソッドを使い、prerenderをtrueとすれば、SSRとなる。

```index.html.slim
= react_component("Main", props: {data: @data}, prerender: true)
```

上記のように、SSRしたいところだけに設置できるので、まあお手軽かなと。