OmniAICreator/Qiita-1.07M huggingface dataset:
Github Pages で .htaccess の代わりに javascript のみでURLの rewrite を実現してパーマリンクを有効にする

## 目的

Github Pages でパーマリンク（整形された動的URL）を使えるようにする。Github Pages では `.htaccess` などによるURLの `rewrite` ができないので、同等の機能を javascript のみで実現する。

## 必要なもの

- javascript のみ

※ Jekyll は使わない。

## 仕組み

1. パーマリンクによる無効なURLを一旦 `404.html` で受ける（Github Pages のデフォルト仕様）
2. `404.html` に仕込んだ javascript で、クエリストリング付きの有効なURLに変換して目的のページ `post.html` にリダイレクト
3. リダイレクトされた目的のページ `post.html` で、historyAPI の `replaceState` を使ってURLを最初にリクエストされたパーマリンクに変換

#### 基本構成と各ファイルがやっていること
```
--
 |-- index.html
 |-- 404.html（無効なパーマリンクを有効なURLに変換してリダイレクト）
 |-- post.html（リクエストされたURLをパーマリンクに再変換）

```

## サンプル

実際に GitHub Pages で[サンプルサイト](https://h-kuwayama.github.io/ghp-rewrite/)を公開中。

パーマリンクでの遷移を実現するためにやっていることは

- 404.html
- post.html

内に記述した下記 javascript のみ。


```js:404.html

/*
 * （JS部分のみ抜粋）
 * パーマリンクをクエリストリング付きのURLに変換してリダイレクト
 */

// リダイレクト先のファイル名
var redirect_file_name = 'post.html';

// リダイレクトで使用するパラメータキー
var parameter_key = 'post_id';

// パーマリンクの取得
var path_name = window.location.pathname;

// クエリストリング付きのURLに変換してリダイレクト
var match_condition = new RegExp(redirect_file_name.replace('.html', '') + '/[a-z0-9-_]+$');
if (permalink = path_name.match(match_condition))
{
  location.href = path_name.replace(permalink, '') + redirect_file_name + '?' + parameter_key + '=' + permalink[0].replace(/post\//, '');
}
```

```js:post.html

/*
 * （JS部分のみ抜粋）
 * クエリストリング付きのURLをパーマリンクに再変換
 */

// ファイル名
var file_name = 'post.html';

// パラメータキー
var parameter_key = 'post_id';

// URLを取得
var path_name = window.location.pathname;
var query_string = window.location.search;
var base_dir = path_name.split(file_name)[0];

// パーマリンクに再変換
var match_condition = new RegExp(parameter_key + '=[a-z0-9-_]+$');
if (parameter = query_string.match(match_condition))
{
  parameter_value = parameter[0].split('=')[1];
  history.replaceState(null, null, base_dir + file_name.replace('.html', '/') + parameter_value);
  document.title = parameter_value + ' | Github Pages Rewrite';
}

```

詳しくは[こちらのサンプルソース](https://github.com/h-kuwayama/ghp-rewrite)から。

## 問題点

- リダイレクトが実行されるので明らかな遷移感がある
- `replaceState` が走る前に一瞬変換前のURLが見える（ときもある）

`mod_rewrite` などWEBサーバのリライト機能と完全に同等というわけではなく、結果として同じことができている、ということ。


## その他

Github Pages は拡張子なしのURLを受け付けるので、`canonical` でURLの正規化さえしておけば固定ページのリライトを意識する必要はなさそう。



```:どちらも同じリソースを表示する
/contact.html
/contact
```


## さいごに

`Jekyll` の `redirect_from` のほうがスマートですが、ワイルドカードや正規表現を使ったリダイレクトルールが作れなかったので無理やりこの方法を試してみました。
もっといい方法があればどなたかご教授ください。

そもそも `S3` や `Firebase` などリライトが可能なサービス使えよ、っていう話ですが、やっぱり CI や Pipeline の設定なしでそのまま本番デプロイできる Github Pages は便利だな、と思うので。
Github さんには rewrite 機能を json で設定できるなどの追加サービスを期待したいです。

以上です。
素のReactアプリをFirebaseにデプロイする

create-react-appでつくったReactアプリをFirebase Hostingにデプロイします。
npmではなくyarnでやります。

# アプリのベースをつくる

react-appを作成します。
yarnは最新版にしておきます。

* yarn - https://yarnpkg.com/ja/docs/install#windows-stable
* create-react-app - https://facebook.github.io/create-react-app/docs/getting-started

```bash
> yarn create react-app アプリ名
> cd アプリ名
> yarn
```

アプリにfirebaseのHostingを設定します。
WindowsではPowerShellで実行します。
firebaseのプロジェクトはconsoleであらかじめつくっておきます。

* firebase - https://firebase.google.com/docs/hosting/quickstart?authuser=0

```base
> yarn global add firebase-tools
> firebase login
> firebase init
```

init時に聞いてくる質問のうち、「publicのindex.html使う？」に対しては、「build」にします。
また、「index.htmlを置き換える？」に対しては、「No」にします。

ログはこんな感じです。

```
Before we get started, keep in mind:

  * You are initializing in an existing Firebase project directory

? Are you ready to proceed? Yes
? Which Firebase CLI features do you want to setup for this folder? Press Space to select features, then Enter to confi
rm your choices. Hosting: Configure and deploy Firebase Hosting sites

=== Project Setup

First, let's associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add,
but for now we'll just set up a default project.

i  .firebaserc already has a default project, skipping

=== Hosting Setup

Your public directory is the folder (relative to your project directory) that
will contain Hosting assets to be uploaded with firebase deploy. If you
have a build process for your assets, use your build's output directory.

? What do you want to use as your public directory? build
? Configure as a single-page app (rewrite all urls to /index.html)? Yes
? File build/index.html already exists. Overwrite? No
i  Skipping write of build/index.html

i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...

+  Firebase initialization complete!
```

作成されたfirebase.jsonに以下を追加します。(create-react-appのドキュメントに記載してあります)

```
    "headers": [
      {
        "source": "/service-worker.js",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "no-cache"
          }
        ]
      }
    ]
```

# デプロイする

いきなりビルドしてデプロイします。

```
> yarn build
> firebase deploy
```

おしまい。

ローカルで実行する場合、yarn startで十分ではありますが、ビルドしたアプリを実行する場合はfirebase serveを使えます。

```
> firebase serve
```
未成熟な開発組織の開発/進捗/課題管理ツールを変更する(その1 事前準備)

# 未成熟/成熟について
## 前職(成熟)
### 開発プロジェクト規模
- １5０人程度(自分の所属する部だけで)
- ハードも絡んだ製品だったので完全にウォーターフォール
- 大体設計2ヶ月、実装２ヶ月、テスト２ヶ月、別部署によるテスト３ヶ月みたいなスケジュール

### 開発環境
- win7(デスクトップ) + 16:9のディスプレイ2枚
- コード管理はCVSだったりSVNだったり
- コミニュケーションはOffice365 + Skype
- 実装チケットや障害チケット等の管理はJIRA

タスク管理等もJIRAでチケット切って行っていた人もいた
組織が完全に固まっているので新しいツールの導入が非常に難しい状況(完全にそれで回っちゃっているので)
実装チケット、バグチケット、タスク等も全てJIRA上で管理
チケットのステータスに変化があるとoutlookにメールが飛んでくる
完全にJIRAを中心に開発が回っていた

## 現職(未成熟)
- 10人程度
- その中で実装できるのが私含めて３人
- 組織自体はめちゃくちゃ若い(自部署全員が２０１８年入社)
- 完全にweb系
- 開発規模はまちまちなのでスケジュールもばらつき大きい
- 直近の小規模なものであれば設計2週間、実装2週間、テスト１ヶ月(他部署による受入テスト等も含めて)みたいなスケジュール

### 　開発環境
- MacBookPro + 4Kディスプレイ
- コード管理はgithub
- コミニュケーションはほぼSlack
- 障害管理はredmine、実装チケットはgithubのissue

実装期間中の実装チケットはgithub issueで管理
テストで発見したバグはredmineに起票される
週一の定例でチケットの進捗確認
決まった開発フローが無いので迷走気味

# 変更するきっかけ
- 上司「redmine正直イケてないし、使いづらいから乗り換えたい」
- 私「JIRAは？」
- 上司「この規模で使うにはちょっと高い」
- 私「要件としては何が欲しい？」
- 上司「進捗確認がしやすいようにガントチャートが欲しい」

う〜む、じゃあTrelloにプラグイン入れて使ってみるか…というのが始まり
Backlogとかも一応は候補だったが、Trelloの方が部内に使っている人が多く、学習コストが小さいため、最初はTrelloを選択
対象とするプロジェクトの規模は、マネージャー１人、実装３人、テストケース作成１人、要件定義〜リリースまで３ヶ月程度の小規模なもの

# 導入したもの
- Trello
- [Elegantt for Trello](https://elegantt.com/)
- [Card Color Titles for Trello](https://chrome.google.com/webstore/detail/card-color-titles-for-tre/hpmobkglehhleflhaefmfajhbdnjmgim)
- Agile Tools(Power-Up Tools)(生産性ポイントを使いたかった)
- ボードには[Todo,Assign,Start,Review,Done]の5つのリストを用意
- ラベルは[実装,実作業,テスト,バグ]を用意

# ここまで作ってみて
- ガントチャートがすぐできるのは便利
    - ただ、リストを横軸にしたガントチャートしかできないのが不便
    - メンバーを横軸にしたガントチャートを見るには有料会員しかできない？
- バグ管理はredmineの方が優れているかも…
    - メンバーのタスク管理はTrello、バグ管理はredmineとして使い分けるのがいいかも
    - 幸い、zapierで双方向に連携ができるみたいなので、redmineで起票されたらTrelloにカード作成するみたいな感じでうまいことやれるかもしれない
- 生産性ポイントはかなりいいかも
    - メンバーに1週間に消化できる生産性ポイントを設定することで、一人一人の力量を定量的に判断しやすくなる(かも)
    - タスクをSSS〜Fランクみたいにランク付けすることでゲーム感覚でタスク消化できるようになる(かも)


## 今後
これいいじゃん！って感じから、ひとまず急造した段階なので、まだ使っていない状態
来週から実際に使ってみるので、感想や改善点、ダメだった点などは別記事にまとめようと思います
VirtualBox + vagrant + Amazon Linux でディスク容量を増やす

今、仕事では表題の環境で開発を進めているのですが、ディスク容量に関して少々ハマったので記事として残しておきたいと思いました。
バージョンは
Amazon Linux AMI release 2017.03
です。
## Amazon Linuxの初期容量少なすぎ問題
Amazon Linuxのディスク容量は、何も設定をしないと少なすぎて使い勝手が悪いと思います。

```
$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
devtmpfs         489M   76K  489M    1% /dev
tmpfs            498M     0  498M    0% /dev/shm
/dev/sda1        7.8G  1.2G  6.6G   15% /　←ここ
vagrant          466G   56G  411G   12% /vagrant
```
マウントで何とかすれば良いじゃん、とかあると思うのですが
今回はディスク容量を増やすやり方を考えていきます。（単にマウントについての理解力が乏しいとも言える）

## ホストOSでディスクの拡張＆差し替え

```
//vagrantを一時停止
$ vagrant halt
//vagrantのディスクパスへ移動
$ cd /path/to/VirtualBox\ VMs/test_default_1543062925384_69936/
//vdi形式にクローン
$ VBoxManage clonehd "box-disk001.vmdk" "clone-disk1.vdi" --format vdi
//容量を拡張。ここでは100GBに
$ VBoxManage modifyhd clone-disk1.vdi --resize 102400
//拡張したディスクをvmdk形式にクローン
$ VBoxManage clonehd "clone-disk1.vdi" "box-disk002.vmdk" --format vmdk
```
以上の作業が終了後、次はVirtualBoxを開いてください。
上記の作業をおこなったゲストOSの設定をクリックし、ストレージを選択してください。
そうすると、下の画像のように表示されると思います。「コントローラー:SATA」の隣にあるプラスマークアイコンのうち、右側のアイコンをクリックするとポップアップが表示されるので「既存のディスクを選択」をクリックしてください。
<img width="775" alt="スクリーンショット 2018-11-24 21.59.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/258256/58f5a07d-0506-fe76-0e8c-9eb555a51d1b.png">
そして、先ほど作成したbox-disk002.vmdkを選択すると、先ほどの画面にディスクが追加されます。
最後に、デフォルトのディスクを選択して、下のマイナスフロッピーアイコンをクリックして除去して下さい。
（最後にOKをクリックして設定を反映させるのを忘れずに！）
<img width="773" alt="スクリーンショット 2018-11-24 22.11.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/258256/7ec13025-520f-eb30-5a1a-c4420a570578.png">

## ゲストOS側の作業
### ハマりポイント１　ーーあれ、容量増えてない
上記の作業は、適当にググると正直すぐわかりました。
ただ、これから多少ハマった箇所があります。
まずは、dfコマンドをおこなっても容量が増えたことが確認できなかったことです。

```
$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
devtmpfs         489M   76K  489M    1% /dev
tmpfs            498M     0  498M    0% /dev/shm
/dev/sda1        7.8G  1.2G  6.6G   15% /
vagrant          466G   59G  408G   13% /vagrant
```
どうやら、この後色々と設定しなければならないらしい。。。

### ハマりポイント２　ーーボリュームの作成方法が出来ない
パーティションをイジり、ボリュームを作成すると容量が増えるらしいというのが分かりましたが、その設定が出来なかった。
具体的には、`pvdisplay`コマンドなどdisplay系(？)のコマンドが全く使用出来ませんでした。
これ、何でなんですかね？？未だに理由が分かりません。。。

### 解決策
上記の状態に陥り、うーん困ったなと思っていたのですが、根気よく探すと別の方法もあるみたいでした。それが以下のやり方です。

```
$ sudo resize2fs /dev/sda1
```
たったこれだけでした。そして、改めてdfコマンドをすると。。。

```
$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
devtmpfs         489M   76K  489M    1% /dev
tmpfs            498M     0  498M    0% /dev/shm
/dev/sda1         99G  1.2G   98G    2% /　←増えてる！
vagrant          466G   59G  408G   13% /vagrant
```
ちゃんと増えてる！！！
これで重いファイルもどんどん扱えますね！
HLS や MPEG-DASH の時間的な変化をグラフで理解する。

# 概要

近年では HLS (HTTP Live Streaming) や MPEG-DASH など HTTP 上で Streaming を実現する手法が広く用いられています。
それらの動作原理は難しいものではありません。
特に On-Demand の場合、 Server は静的なファイルを返しているだけです。

しかし、生配信の場合には Just In Time で処理を行うため少しだけ難しくなります。
生配信の際の動作を　Encoder から Player まで全体通して想像するのは少し難しいように思います。
また、そういったことを図示している資料をあまり見たことがありません。
そこで、この記事では生配信の際の動作の流れを簡単な図で説明し、関連する事柄について少し述べたいと思います。

なお、 HLS や MPEG-DASH の仕様の説明はしません。

# 前提

Pull 型の HLS や MPEG-DASH で生配信を行う場合について言及します。
HLS Push や On-Demand は含まれません。

# 図と説明

<img width="798" alt="スクリーンショット 2018-10-22 21.39.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/78005/acd8016c-ec02-ab5f-43e7-fb3a32df0288.png">

横軸は実時間、縦軸は Timecode （映像上の時間経過）です。

カメラの出力や PLAYHEAD が 45 度右上がりの直線を描いているのは実時間の経過と同じだけの映像が供給されていることを表しています。

一方で Packager の Output や Player の Input は階段状のグラフになっています。
それは映像を適当な長さ（2秒〜10秒程度）の Chunk (TS や fMP4) に分割して配信するからです。
例えば Chunk の長さを 5 秒に設定した場合、パッケージャは 5 秒間の映像を受信し終えたときにその Chunk を Playlist に出現させます。
従って 5 秒間は出力の変化しない状態があり、その後突然 5 秒進む、そしてまた 5 秒間何も変化しない、という動きをします。
新しい Chunk が Playlist に現れても直ちに Player がそれを受信するわけではありません。
Player の実装によってある程度の差はありますが、 Player は概ね Chunk 長の半分程度の間隔で　Playlist を再取得し、そのタイミングで Playlist に新しい Chunk があればそれを Download します。
従って Player の Input 地点では Packager の Output から概ね Chunk 長以内の遅延が発生しています。

Player の Input は階段状ですがやや傾きをつけています。
それは Chunk を Download する時間があるからです。
この傾きが 1 より小さくなる (傾斜がゆるくなる) と　PLAYHEAD が Input に追いついてしまい、いわゆる Buffering 画面 [^buffering] になってしまいます。（厳密には、単に Download できれば良いだけでなく Decode の遅延もあります。）
Player は多少の映像を溜めている状態を保つ事で安定して再生を継続できます。

[^buffering]: 「読み込み中」を示唆する表示をそう呼ぶようです。

# 配信遅延

生配信の場合に遅延（カメラで像を捉えてから、それが Player の画面に映されるまでの遅れ）の短さは重要です。
遅延の要因はネットワークの速度や CDN の性能だったり、あるいは Packaging 前の上流部分の物理的な距離や伝送 Protocol の種類、機器の性能など様々あります。

また、本稿の図からわかるように Chunk の長さも遅延に関係しています。
一般に Chunk を短くした方が遅延は短くなります。
配信遅延を重要視する動画サービスが Chunk を短めにするのはそのためです。

最近では LHLS や CMAF などのより低遅延な配信を実現する仕組みも出てきています。
Chunk の末尾まで準備が整うのを待たずに Chunked Transfer Encoding で転送しよう、というのが基本的な枠組みのようです。

# QoS

Player へ安定して映像を届けるには Packager Output の階段状のグラフが形を崩してはいけません。
実時間よりも速度を落とすと再生が止まってしまったり、逆に速度が上がってしまうと Player は映像を飛ばしてしまいます。
それは Packager の直接の出力だけでなく Reverse Proxy や CDN 上でもそれが保たれなければなりません。
特に Reverse Proxy や CDN が独立した複数の Node (Edge) を持っている場合には、更新の遅れている Node によって Player 上では Playlist が巻き戻ったように見えてしまう恐れがあります。
従って Reverse Proxy や CDN のキャッシュ更新時間は Chunk 長に対して十分に短い必要があります。

HLS や MPEG-DASH は HTTP 上で動きますが、汎用的な HTTP の監視ツールでは十分に品質をチェックできているとは言えません。
Response Status が 200 でなおかつ Body の中身が静的に正しいと評価されても、時間の流れに沿って正しく動作しているかはわからないからです。
最近では HLS や MPEG-DASH に対応した監視ソリューションも広まりつつあるようです。
Sass を気軽にインストール

# 前提
- ちょっと CSS や HTML を書いて試したい
- でもだんだん CSS の量が増えてきて「Sass/SCSS使いたいなあ…」と思い始めた

といった方向け（つまり自分向け）の記事です。

# 環境
- yarn 1.12.3
- sass 1.15.1

# TL;DR

## ディレクトリ構成
```
index.html
src
 └ main.sass
build
 └ main.css
node_modules
yarn.lock
package.json
package-lock.json
```
## sass をインストール
```
$ yarn add --dev sass
```

## ウォッチコマンドを定義
```json
{
  "dependencies": {},
  "devDependencies": {
    "sass": "^1.15.1"
  },
  "scripts": {
    "sass-watch": "sass --watch src/main.sass build/main.css"
  }
}
```

## package.json で定義したスクリプトを実行
```
$ yarn run sass-watch
yarn run v1.12.3
warning package.json: No license field
$ sass --watch src/main.sass build/main.css
Sass is watching for changes. Press Ctrl-C to stop.

```

# 備考
sass のインストールは Yarn でも npm でもどちらでも良いと思います。いずれにせよ、 `.sass` ファイルを更新するたびにコンパイルが走ってほしいのでウォッチコマンドを定義しておくのが吉です。
あと、npm のパッケージにありがちなんですが、だいたい `-g` オプションつけてグローバルでインストールしろって言ってくると思いますが、ありゃあ無視した方が良さげです。**ディレクトリやプロジェクトごとに使いたいバージョンも変わってくる**ので、基本的には `package.json` 内に閉じ込めておく方が管理が楽かと思います。

# 参考文献
https://sass-lang.com/install
https://sass-lang.com/guide
SVGアニメーション作成

#SVGアニメーション作成
SVGアニメーションがずっと上手く設定できなくて悩んでいたけど、
急に理解できたのでメモ書き。

##HTML側記述例

```
<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="768" viewBox="0 0 1024 768">
  <path d="M690,0c172.1,66.9,151,140.4,334,207V0H690z">
    <animate
      id="open"
      attributeName="d"
      begin="indefinite"
      dur="800ms"
      fill="freeze"
      keyTimes="0; 0.5; 1"
      calcMode="spline"
      keySplines=".43,.07,.71,.41; .3,.56,.64,1.02"
      values="M690,0c172.1,66.9,151,140.4,334,207V0H690z;
              M0,0c723.3,241.9,416.7,592.6,1024,768V0H0z;
              M0,0c-54.8,945.6-263.8,938.6,1024,768V0H0z" />
    <animate
      id="close"
      attributeName="d"
      begin="indefinite"
      dur="800ms"
      fill="freeze"
      keyTimes="0; 0.5; 1"
      calcMode="spline"
      keySplines=".43,.07,.71,.41; .3,.56,.64,1.02"
      values="M0,0c-54.8,945.6-263.8,938.6,1024,768V0H0z;
              M0,0c723.3,241.9,416.7,592.6,1024,768V0H0z;
              M690,0c172.1,66.9,151,140.4,334,207V0H690z" />
  </path>
</svg>
```

- idはjsから操作する際に使用。
- attributeNameはアニメーション対象の属性を指定。
- beginで開始タイミングを設定。(jsから指定する際などはindefiniteを設定)
- keyTimesは時間配分の設定。
- calcMode="spline"を設定することでアニメーション間のイージングを設定可能になる。
- keySplinesでアニメーション間のイージングを設定。
- valuesでアニメーションの動きを指定する。今回はパスを指定している。色なども設定可能。


##javaScript側の設定
```
$(btnOpen).on('click', (e) => {
  //svg openのアニメーションスタート
  $('#open')[0].beginElement();
});

$(btnClose).on('click', (e) => {
  //svg closeのアニメーションスタート
  $('#close')[0].beginElement();
});
```
HTML側で設定したanimateのどれを起動させるかによってアニメーションを使い分ける。
参考
https://developer.mozilla.org/en-US/docs/Web/API/SVGAnimationElement

###注意点
頂点の数があっていないとアニメーションが上手く動かない。
イラストレーターで同じ数のアンカーから作成したもの同士であれば比較的きちんとアニメーションしてくれるので作成時に注意が必要。
GrowiをDockerでたてる

# 概要
人気のWikiプラットフォームであるGrowiをDockerで構築する

# 環境
環境は自宅サーバー上のCentOSの仮想マシンをたてて、その上にDockerでGrowiを構築していく。

|Software  |version  |
|---|---|
|CentOS | 7.5|
|Docker | 18.09.0
|Docker-Compose|1.18.0|

# dockerインストール
Dockerのレポジトリを登録してyumでインストール

```bash
$ curl -O https://download.docker.com/linux/centos/docker-ce.repo
$ mv docker-ce.repo /etc/yum.repos.d/
$ yum install docker-ce
```

インストールが正常にできているか確認してサービス起動

```bash
$ docker --version
Docker version 18.09.0, build 4d60db4
$ systemctl start docker
```

# docker-composeインストール
```bash
$ yum install docker-compose
```

インストールが正常にできているか確認

```bash
$ docker-compose --version
docker-compose version 1.18.0, build 8dd22a9
```

# Growi構築
Dockerを使う準備ができたので、続いてGrowiを導入していく
今回は/opt/docker以下に作っていく。

```bash
$ mkdir -p /opt/docker
$ cd /opt/docker
$ git clone https://github.com/weseek/growi-docker-compose.git
$ cd growi-docker-compose
```

docker-compose.ymlを編集していく。
サーバーの外からもアクセスできるようにしたいので、127.0.0.1は削除する。
また、PASSWORD_SEEDも適当なものに変更する。


```vim:docker-compose.yml
version: '3'

services:
  app:
    build:
      context: .
      dockerfile: ./Dockerfile
    ports:
#      - 127.0.0.1:3000:3000    # localhost only by default
      - 3000:3000
    links:
      - mongo:mongo
      - elasticsearch:elasticsearch
    depends_on:
      - mongo
      - elasticsearch
    environment:
      - MONGO_URI=mongodb://mongo:27017/growi
      - ELASTICSEARCH_URI=http://elasticsearch:9200/growi
#      - PASSWORD_SEED=changeme
      - PASSWORD_SEED=tekitounapassword
```

そして起動
3000番ポートで稼働していることが確認できる

```bash
$ docker-compose up -d
$ docker ps
CONTAINER ID        IMAGE                      COMMAND                  CREATED              STATUS              PORTS                    NAMES
8c1e392248e6        growidockercompose_app     "/docker-entrypoint.…"   13 seconds ago       Up 12 seconds       0.0.0.0:3000->3000/tcp   growidockercompose_app_1
4e1dfda152dd        mongo:3.4                  "docker-entrypoint.s…"   About a minute ago   Up 13 seconds       27017/tcp                growidockercompose_mongo_1
26bb1b3fafaf        elasticsearch:5.3-alpine   "/docker-entrypoint.…"   About a minute ago   Up 13 seconds       9200/tcp, 9300/tcp       growidockercompose_elasticsearch_1
```

ブラウザでアクセスすると初回画面にリダイレクトされるので、ユーザー情報を入力する。
ここに登録したアカウントは管理者権限が自動的に付与される。

<img width="1198" alt="スクリーンショット 2018-11-24 22.18.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/245430/63ed3f06-db9c-01a0-35ba-f01b52eeedf9.png">


アカウント情報を入れるとgrowiの設定画面に遷移して、wikiとして利用できるようになる
<img width="1081" alt="スクリーンショット 2018-11-24 22.21.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/245430/a17286ad-5265-4327-d712-f556d2f2946e.png">

# まとめ
Wikiサイトとして人気のあるGrowiをDockerで構築した。
ありがたくもdocker-compose.ymlがgithub上にあるので、数コマンドで簡単に構築できた。
次回は、Growiのファイルアップロード先としてS3を連携する記事を書く。
cobra / pflags でフラグをパースせずに args に残す

`docker run` のように，コマンドの引数に別のコマンドを引き渡して内部でいい感じに実行する系のやつ．

## `FlagSet.SetInterspersed`
[`FlagSet.SetInterspersed`](https://godoc.org/github.com/spf13/pflag#FlagSet.SetInterspersed) を使う．

```go
cmd := &cobra.Command{
	// snip.

	// 何らかのコマンドが渡されてることを保証する（not required だが，大抵は必要なはず）
	Args: cobra.MinimumNArgs(1),
}

// ref: https://godoc.org/github.com/spf13/pflag#FlagSet.SetInterspersed
// `Flags()` or `PersistentFlags()` はユースケースによっていい感じに使い分ける
cmd.Flags().SetInterspersed(false)
```

cobra（pflags）はデフォルトだと引数とオプションがごちゃごちゃ（`interspersed`）に渡ってきてもちゃんとパースされる．なのでこれを off にすることで，最初の flag じゃない引数より後ろは flag としてパースされなくなる．

実装は [pflags の flag.go](https://github.com/spf13/pflag/blob/v1.0.3/flag.go#L1081-L1085) にあって，最初の引数が見つかった瞬間に flag のパースをやめるというもの．

日本語だと意味不明だけど，だいたい :point_down: みたいな挙動になる．

```shell-session
$ # intespersed: true (default)
$ # args == []string{"run", "qux", "quux"}
$ fooctl --verbose run --bar=42 qux --baz quux

$ # intespersed: false
$ # args == []string{"run", "--bar=42", "qux", "--baz", "quux"}
$ fooctl --verbose run --bar=42 qux --baz quux
```

`SetInterspersed(false)` でも，上の例だと `run` より後ろ（`--verbose`）は正しくパースされる．もちろん，未定義のフラグならエラーになる．


## UnknownFlags?

[`cobra.Command` に `FParseErrWhitelist.UnknownFlags`](https://godoc.org/github.com/spf13/cobra#FParseErrWhitelist) というものがあるが，これは単に未知のフラグを無視するようになるだけなので，今回は関係ない．


## 余談

`docker run` は `run` で `SetInterspersed(false)` をしている．
https://github.com/docker/cli/blob/v18.09.0/cli/command/container/run.go#L52-L53

一方，ほぼ同一の interface を持つ `kubectl run` は interspersed が `true` のまま．
https://github.com/kubernetes/kubernetes/blob/v1.12.2/pkg/kubectl/cmd/run.go#L166-L193

pflgas は `--` 以後の引数はパースしないので，そうやってコマンドを渡す．
`yarn run` とかとおなじ，わりと一般的な挙動ではある．

```shell-session
$ # args == []string{"curl", "http://example.com/ping"}
$ kubectl run ... --image buildpack-deps:18.04-curl -- curl http://example.com/ping
```

interspersed を切るかどうかは，その CLI がどんな UX を提供したいかによって判断すると良さそう．
サーマルプリンタで印刷する: レンダリングサービス編

## 0. 前回までのあらすじ

サーマルプリンタをLinuxから印刷できるように[セットアップ](https://qiita.com/yuyakato/items/7d4db1c567d952a7ac91)し、Raspberry Piから文字、画像を[テスト印刷](https://qiita.com/yuyakato/items/3309b0ede886c2698526)し、画像を印刷するための[印刷サービス](https://qiita.com/yuyakato/items/24666dff3ea1a6a86672)を構築しました。
これまでの記事については『[目次](https://qiita.com/yuyakato/items/288962fbc39446644668)』をご覧ください。

## 1. レンダリングサービスをセットアップする

[印刷サービス](https://qiita.com/yuyakato/items/24666dff3ea1a6a86672)によってPNG画像を簡単にサーマルプリンタで印刷できるようになりましたが、文字を印刷するためにわざわざ画像化するのは幾分面倒です。
そこで、HTMLをPNG画像に変換する「レンダリングサービス」を実装しました。
レンダリングサービスは、Docker、Node.js、Chromiumブラウザなどを使って実装しています。
ソースコードは https://github.com/nayutaya/thermal-printer/tree/master/service/rendering をご参照ください。

```text
# thermal-printerリポジトリをclone済みの場合は、以下の3行は不要です。
pi@raspi-3bp$ mkdir -p ~/repo/github.com/nayutaya
pi@raspi-3bp$ cd ~/repo/github.com/nayutaya/
pi@raspi-3bp$ git clone https://github.com/nayutaya/thermal-printer.git

pi@raspi-3bp$ cd ~/repo/github.com/nayutaya/thermal-printer/
pi@raspi-3bp$ git pull
pi@raspi-3bp$ git checkout service-rendering-v1.0.0
pi@raspi-3bp$ git branch -v
* (HEAD detached at service-rendering-v1.0.0) 9e4fe25 Merge pull request #10 from nayutaya/issue#8_add_chrome_extension
  master                   9e4fe25 Merge pull request #10 from nayutaya/issue#8_add_chrome_extension

pi@raspi-3bp$ cd ~/repo/github.com/nayutaya/thermal-printer/service/rendering/
pi@raspi-3bp$ ./build_image.sh
pi@raspi-3bp$ ./run_service.sh
pi@raspi-3bp$ docker ps
CONTAINER ID        IMAGE                               COMMAND                  CREATED             STATUS              PORTS                    NAMES
3fac97d75973        thermal-printer/service/rendering   "/bin/bash --login -…"   26 seconds ago      Up 23 seconds       0.0.0.0:3031->8080/tcp   thermal-printer_service_rendering
3798bbbc7239        thermal-printer/service/printing    "uwsgi --module=app …"   2 weeks ago         Up 2 weeks          0.0.0.0:3030->8080/tcp   thermal-printer_service_printing
```

## 2. レンダリングサービスでHTMLを画像に変換する

レンダリングサービスはWebサービスとして動作しており、`3031/tcp`で待機しています。`GET /`を送信することで動作を確認することができます。

```text
pi@raspi-3bp$ curl http://localhost:3031/
{"time":"2018-11-24T12:54:51.707Z"}
```

`POST /render_html`に対してパラメータ（画像の幅、HTML）を含むJSONを送信することで、HTMLを画像に変換することができます。

```text
pi@raspi-3bp$ cd ~/repo/github.com/nayutaya/thermal-printer/service/rendering/
pi@raspi-3bp$ cat hello.json
{
  "width": 576,
  "html": "<html><body><div style=\"font-size: 64px;\">Hello World<br/>こんにちは世界</div></body></html>"
}

pi@raspi-3bp$ curl \
  --request POST \
  --header "Content-Type: application/json" \
  --data-binary @hello.json \
  http://localhost:3031/render_html > hello.png

pi@raspi-3bp$ file hello.png
hello.png: PNG image data, 560 x 148, 8-bit/color RGBA, non-interlaced
```

ChromiumブラウザによってHTMLがレンダリングされ、PNG画像として出力されます。上記の出力例は以下の通りです。

![hello.png](https://qiita-image-store.s3.amazonaws.com/0/58479/38338e41-a412-4424-1797-9c8a9f856186.png)

レンダリングサービスで生成したPNG画像を印刷サービスに渡すことで、結果としてHTMLをサーマルプリンタで印刷することができます。

```text
pi@raspi-3bp$ curl \
  --request POST \
  --header "Content-Type: image/png" \
  --data-binary @hello.png \
  http://localhost:3030/print
```
Vue.jsのコンポーネントのtemplateで複数要素を書いていつもハマってしまう

タイトルのとおりで、久しぶりにVue.jsを書くといつもハマってしまうのでメモ。

mycomponentというコンポーネントを作ります。

```html
<div id="app">
    <mycomponent></mycomponent>
</div>
```

コンポーネントのtemplateで、無意識に次のように複数要素を書いてしまいます。

```javascript
Vue.component('mycomponent', {
  template:`
    <h1>component</h1>
    <b>hello</b>
  `
})

var app = new Vue({
  el: '#app'
})
```

で、なんでhelloがでないんだーとなる。

![2018-11-24_21h59_28.png](https://qiita-image-store.s3.amazonaws.com/0/47737/1ca17970-a2db-12cd-304b-94f4aeb0b305.png)

ルート要素は単一でないといけないので、\<div>などで囲う必要があります。

```javascript
Vue.component('mycomponent', {
  template:`
    <div>
        <h1>component</h1>
        <b>hello</b>
    </div>
  `
})

var app = new Vue({
  el: '#app'
})
```

ちゃんと出ました。

![2018-11-24_22h00_37.png](https://qiita-image-store.s3.amazonaws.com/0/47737/8d9b360c-e028-10ae-d387-5a9646522b32.png)

[「基礎から学ぶ Vue.js」](https://cr-vue.mio3io.com/)の「SECTION 22 コンポーネントの定義方法」にしっかり書いてある！
[FileMaker]ボタンアイコンをSVG形式で自作する

[昨年](https://qiita.com/kmcoos/items/ad1895f4a61f0da94bf0)のカレンダーに初参加させていただきましたので、2018年こそ良いネタ書くぞと意気込んでポチッとしましたが、
性懲りも無く、どこに需要があるか分からない小ネタを投下します:sweat_smile:


##FileMakerのボタンアイコン
FileMaker 14以降、ボタンにアイコンが設定できるようになりました。
![スクリーンショット 2018-09-28 23.55.15.png](https://qiita-image-store.s3.amazonaws.com/0/155008/7117dc18-22d2-01c1-07a4-62f17a3e5b40.png)

デフォルトで用意されているアイコンもあるのですが、自分で好きなアイコンを使いたい場合は、左下の ＋ プラスボタンからアイコンファイルを登録することができます。
![スクリーンショット 2018-09-28 23.55.49.png](https://qiita-image-store.s3.amazonaws.com/0/155008/35294856-b5c7-c0f6-1e96-f88f5ffdac3a.png)

登録できるのが、PNG形式 か SVG形式の2種類。
PNG形式は簡単ですが、アイコンの大きさや色を変える等が効かないので、レイアウト作る際にちょっと物足りなさを感じます。
SVG形式だと、そういった変更も自由自在にできるので、**画像作成のソフトを使わずに**作れないものかと試行錯誤してみました。

##Icon Maneger
http://www.indats.com/KnowledgeCenter/
無料なので勝手に紹介してしまっていますが、アメリカはソルトレイクシティのInDats社のサイトにあるこちらのツールをまずは黙ってダウンロード。
もうこれだけで事足りるかもしれません。
たくさんのSVGアイコンがFileMaker向けに最適化された形で入手できます。
InDats社様、素敵なツールを公開していただき、ありがとうございます。

##フリーのSVGアイコン素材
「SVG アイコン フリー」とかって検索すると、素材をゲットできるサイトがいくつか出てきます。
SVG形式のファイルをテキストエディタ等で開くとこんな感じ。
<img width="986" alt="スクリーンショット 2018-11-04 18.20.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/155008/fc82452b-5bc6-5a83-e3a6-3eb9ef8bda68.png">

なーんか頭痛くなってきそうな文字の羅列がいっぱいです。
このファイルをFileMakerに登録すれば事足りそうなんですが、読み込みできなかったり、拡大・縮小や色変更ができない場合があるので、FileMaker向けに最適化したSVGファイルに変換してやります。

先ほどの**Icon Maneger**の方に登録していきます。
<img width="999" alt="スクリーンショット 2018-11-04 18.23.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/155008/5dcdfa3e-028e-0bb4-0c6b-781677bd7af5.png">
**Utility_Icon**というレイアウトに移り、レコード作成で追加していきます。
**PathData**のフィールドに、テキストエディタで開いているSVGのpathのd値をコピペします。

`<path class="st0" d="hoge hoge">`
pathが複数あれば、一つ目のpathから最後のpathの " まで丸ごとコピーすると上手くいきます。（いかない時もある...）

<img width="993" alt="スクリーンショット 2018-11-04 18.45.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/155008/2e937eef-4186-fe62-18a1-370478e78e70.png">


**Generated_SVG**のフィールドに自動計算で値が入ります。
右上の**X、Y、Width、Height**のフィールドも同じように設定していきます。
だいたい初めの方に定義されてます。

`viewBox="0 0 512 512"`

右から順番に入れます。
<img width="996" alt="スクリーンショット 2018-11-04 18.47.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/155008/b056a7b7-712a-2cf7-ff71-b4383dcb1fb4.png">

左上のプレビューにアイコンが表示されました！
あとはNameとTagsに適当な値を入れておけば、Icon Managerへの登録は完了です。
Favoriteのフラグを立てておけば、後でまとめてエクスポートしやすいですよ。


同じように、画像データからも変換ツール等でSVG形式へ変換して、パス値を取ってこれればアイコン化できます。

わざわざこんな面倒くさいことやんなくても・・・とも思いますが:sweat_smile:
画像データをレイアウトに貼り付けるよりも、SVGアイコンの方が表示も速かったりすんのかな？という淡い期待からよく使う画像はアイコン化させています。
ただし効果検証はやってません。完全に自己満の世界です。。。
SORACOM Technology Camp2018

2018/11/22@大崎ブライトコア

https://technology-camp2018-fall.soracom.jp/timetable.html

# 開会宣言（From yaman）
- IoT=技術の総合格闘技


# IoTソリューションの開発/導入検討の進め方
今井雄太氏（ソリューションアーキテクト）
- IoT=モノ、コトのデジタル化

##### IoTの導入事例、相性のいい事業
- 農業、漁業、監視
- 工場可視化
- コンシューマ
- 決済端末
- 動態管理

##### IoTの難しさ
- 適切なモデル化
- デバイス側のプログラム
- ストレージ
- デバイスへのメッセージング

##### 所感
- 人的リソースの無駄を解決するのが基本的なニーズ
- ソラコムが提供するもの
    - セルラー、LoRaWAN、Sigfox、有線（SIMの認証を使う）、パートナークラウド

##### 活用事例
- 豚舎モニタリングシステム
温度、水の流量管理。
設備の管理にリソースが取られていたため、IoTによって設備不全の自動検知を行う目的で導入。
**使ったもの**
Fannel、 motionboad cloud、openblocksなど

- OPENHOUSE
営業車両の稼働率分析、配置最適化。
レポートを定期的に提示する。
**使ったもの**
Cariot(フレクトの車両管理サービス）

- 工場の電力使用量を可視化
- リアルタイムでスマホで確認。
**使ったもの**
Fannel,IOT.Kyoto,Openblocks

- AGC
製造現場の可視化。
作業者のスマートウォッチ、スマホ、スマートグラスにリアルタイムで送り、
蓄積、分析を自動で行う。
**使ったもの**
androidスマホ、ビーコン、Lagoonとか

- 東急スポーツオアシス
タオルの回収状況を把握。タオルがいっぱいだったら回収する。

##### 事例のポイント
- 課題の解決方法は技術がなくても解決はできる。
- ただし、デジタル化は選択肢が豊富（期間、金額、企業規模とか）
- すべてのパートを自社で行う必要はない
    - いろんなパートナーさんに相談するとよい
- ソラコムはネットワークをメインで技術提供をする。（セキュア、クラウド連携、データ変換とか）

# そのデバイス、そうしたらIoT化できますか
今井雄太氏（ソリューションアーキテクト）
- アーキテクト例、デバイス選定、サービスの選び方、注意点

##### 所感
- ロジックは出来るだけクラウドに寄せましょう。

##### ソラコムのサービス紹介
###### Beams
プロトコル＋暗号化＋データ転送
ソラコムまでの回線は専用線。

###### Funnel
デバイス〜クラウドサービスへデータ直送
いろんなパートナークラウドの自分のアカウントにデータを送ってくれる

###### Harvest
ソラコムの中にデータを蓄積して可視化する。
ただし、Lagoonを使うことによってリソース管理も可能。そして共有も。
コンシューマにデータの管理を可能にさせる時はLagoonを使用。

##### PLC
PLC〜ToshibaFlash Air〜SORACOMAir〜Beams
**難しいところ**
PLCからデータを取り出す方法
**GWでやってること**
- データの取得
- メッセージフォーマット変換
- 平均値、最大値の算出（データ量が多い時は統計処理を入れて送信する）
**気をつけること**
- PLCとの相性
- GWは linuxディストーションのやつだと使いやすい
- フォーマット、欲しい情報によって利用するサービスを検討する

##### 車両のIoT化
車両〜デバイス〜アプリケーション
**気をつけること**
車両にスマホを積んでデータを送信することが多い。
なんでもついてるから。
車載用デバイスだとシガーソケットを使わずに給電できたり、デバイスから車にデータの送信できる。

##### 遠隔監視
重量計、水位計とかのセンサからモニタリング
**難しいところ**
センサごとにIFがあるのでデータの取得が大変


# 今日から始めるセンサデータの可視化
ysk
**データの可視化に必要な決め事**
達成したいコールを決める
ゴールへの仮説を立てる
仮説を証明する

↑ループを素早く、たくさん回す

##### Harvestのデータ構造
SIM(ISMI)に対して紐づくデータ


# SORACOM LTE-M Button の始め方
プリンシパルエンジニア 松井 基勝

##### 所感
これがメインで聴きにきたので非常に勉強になった。
ボタンの押し方によって挙動を変更できる点では工夫のしがいがありそうな気がする。

##### ソラコムLTE-Mボタンとは
全国区のLTE-M接続が可能。
乾電池式なので電池交換すれば使い続けられる。
ボタンプッシュでLamba起動ができる。
ボタンの押し方は３種類（シングル、ダブル、ロング）

##### LTE-Mとは
通信会社（ソラコムボタンの場合はKDDI）のLTEを使用したLPWA規格

##### 使うと便利なデータ
- deviceId：デバイスごとに割り振られるID
- remainingLife：日付or回数
MIN(push回数/1500 or 開始からの日付/365)
- clickType
- placement
場所。自分で書く。自宅とか会社とか車とか。

##### ハマるところ
- ボタン登録直後は向こうになってる。
- ボタンが増えると判別不能に。
- ボタンのリージョンとプロジェクトのリージョンが別になる可能性あり

##### ユースケース
- ルンちゃんボタン
- ナースコール
- SMSを飛ばす
-

##### バックエンドシステム
クリック→VPGに接続し、udpパケットを送信
競プロでよく使うUFO

```
case (foo <=> bar) <=> 0
when 0
  #等しい時
when 1
  # fooのほうが大きい時
else
  # fooのほうが小さい時
end
```
参考
https://qiita.com/jkr_2255/items/51ecffeaf62e15d9a782

解いた問題
https://yukicoder.me/submissions/299460
DOCTYPEを入れたらbodyのheightが0になってしまった

# 開発日誌

## 使用前

```html
<style>
	body {
		height: 100%;
	}
</style>

<body>
	<div style="display: none;">aaa</div>
```

`<body>`の高さ(height)が578pxだったのだが[^1]。

# 使用後

```html
<!DOCTYPE html>
<style>
	body {
		height: 100%;
	}
</style>

<body>
	<div style="display: none;">aaa</div>
```

`<!DOCTYPE html>`を入れたら`<body>`の高さ(height)が0になってしまった[^2]。

# 原因

```html
<!DOCTYPE html>
<html>

<head>
	<style>
		html {
			height: 100%;
		}
		body {
			height: 100%;
		}
	</style>

</head>

<body>
	<div style="display: none;">aaa</div>
</body>

</html>
```

`<html>`も`height: 100%;`と指定しなければならなかった。

`<div>`の高さを画面に対して100%にしたいなら、親全部を`height: 100%`と書かなければならない。書かないと、子を収容する最小限の高さにまで下げられる。

- `<!DOCTYPE html>`はHTML5で作成したと宣言するもの。
- `<!DOCTYPE html>`を入れることで互換モードから標準モードに変わり、厳密に計算されるようになる。

互換モードが素人向きで、DOCTYPEモードがプロ向きと言える。今となってはDOCTYPEを宣言してない個人サイトを探すのが難しかった。

[^1]: Google ChromeのデベロッパーツールやFirefoxの開発ツールで計算された(Computed)高さ(height)を見れる。最小限の記述しかしないせいで&lt;html>の存在に気づかず:persevere:。
[^2]: GitHub先輩のHTMLファイルに書いてあったのを入れてみた。
QuickTime Playerで作成したmovファイルを圧縮するFFmpeg

ブラウザの挙動を録画するときなどにQuickTime Playerは便利なのですが、保存された動画のサイズが大きいというデメリットがあります。
動画の圧縮にはffmpegが便利です。

brewでインストール可能です。

```
$ brew install ffmpeg
```

例えば、`test.mov`というファイルを`test.mp4`に変換するには以下のようにします。

```
$ ffmpeg -i test.mov test.mp4
```

FFmpegの詳細は以下の記事でも紹介しておりますので、興味のあるかたはぜひご覧になってください。
<a href="https://nishinatoshiharu.com/introduce-ffmpeg/" target="_blank">【具体例あり】動画・音声・画像なんでも変換できるFFmpegの紹介と活用例</a>
Node Tokyo 1日目

![Capture.PNG](https://qiita-image-store.s3.amazonaws.com/0/300937/a9f359a5-9483-e7b1-8b3c-bdfe3c84918b.png)

こんにちは! 去年11月19日〜20日、2018年は東京ミッドタウン日比谷にNode Tokyoの会議のために行きました。ですから、今日は私のいくつか学びと経験をシェアしています。たくさんビジネスマンとブロックチェーン開発者とはブロックチェーンについてを議論しました。
Node Tokyo 2018 Conferenceは初めの会議です。将来的には多くのNode Tokyo会議を行われる。
Node Tokyoは２種類の議論がある。
- パネルディスカッション
- キーノート
Node Tokyoの1日目の日程のために： [https://nodetokyo.jp/schedule/](https://nodetokyo.jp/schedule/)

![Image from iOS (3).jpg](https://qiita-image-store.s3.amazonaws.com/0/300937/ea43998d-802f-fb2c-534e-5d51bcf2f426.jpeg)
*Aya Miyaguchi, 「Ethereum Meets Japan」のスピーカー*

最初のキーノートは「Ethereum Meets Japan」についてです。スピーカーはAya Miyaguchiです。Aya MiyaguchiはEthereum FoundationのExecutive Directorです。プラハと日本でイーサリアムの場合を話しました。日本人々はフォーラムや研究を加わることができます。ですから、日本のブロックチェーンのコミュニティは大きくなります。彼らはまた、ブロックチェーンコミュニティを開発するのに役立つことができます。

たくさんのキーノートがあります。でも、一番おもしろかったのキーノートは「ビットコインから価値のインターネットへ」と思いました。

![Image from iOS (2).jpg](https://qiita-image-store.s3.amazonaws.com/0/300937/f368a56a-399d-6bed-f3d2-a4637aabf1c8.jpeg)
*Gabriel Kurman, 「ビットコインから価値のインターネットへ」のスピーカー*

「ビットコインから価値のインターネットへ」のスピーカーはGabriel Kurmanです。Gabriel KurmanはRSKのCo-Founderです。 RSKはビットコインのために最初スマートコントラクトのプラットフォームです。これから、RSKのプラットフォームはプロダクトにのフレキシビリティーとスケーラビリティを考えしているので、RSKは素晴らしいと思いました。
RSKの詳細については、この[リンク](https://www.rsk.co/)をクリックしてください。

「日本の大企業がブロックチェーンをどう見ているか」のパネルディスカッションはブロックチェインが社会に必要な理由を教えました。このパネルディスカッションのメンバーはTatsuto Fujii, FinovatorsのFounding MemberとTadatoshi Senoo、TRENDE Inc.のCEOとKan Notoya、31 VENTURES, Mitsui Fudosan Co Ltd のProject LeaderとMasaharu Uno、Omise JapanのCountry Managerです。彼らはP2Pエネルギー取引と不動産とfintechにおけるブロックチェーンの効果についてを議論しました。
P2Pエネルギー取引について、トレーダーはブロックチェーンを使って支払うことができます。ですから、セントラルユーティリティーや権限が必要じゃないです。
不動産のために、ブロックチェーンでは委託料金とトランザクションを手間が省けることを下げることができます。
さいごにブロックチェーンではフィンテック会社に取引や不正行為の防止に役立ちます。
このトピックは技術とブロックチェーンの未来になると思います。

Node Tokyo 2018の最初の日に学ぶことはたくさんがあります。このトピックが理解しやすいと思うので、興味を持ったのです。ありがとうございました！
emacs-mac で package 入れようとして couldn't connect ... となったとき

## tl;dr

とりあえずこれ打っておけば大丈夫そう

※長いから気をつけて
※macでhost-os(開発マシン)にbrew経由でemacs-mac入れた人が対象

```console
brew upgrade emacs-mac --HEAD --with-gnutls
```

## そもそも何で困ったの？

普段職場でemacs使っているときと同じ感覚で`M-x packages-list-package`でパッケージのリストを開き、ほしいパッケージを`i`で選択して`x`と打ったらタイトルの問題が発生した。どうやら`gnults`とかいうのがちゃんと入ってなかった？のかもしれない

## 参考にしたもの

https://emacs.stackexchange.com/questions/38347/emacs-27-melpa-connection-failure-on-macos

### 参考記事との変更点
* `reinstall`→`upgrade`
* `emacs`→`emacs-mac`
組込み製品向けGitLab運用手順書[CC0ライセンス]

[GitLab Advent Calendar 2018](https://qiita.com/advent-calendar/2018/gitlab) -  1日目の記事です。

# はじめに
組込み製品向けGitLab運用手順書をCC0ライセンスで公開します

# 公開するContents
下方に記載したリンクのプロジェクトに置いてありますので、ダウンロードしてご利用ください。

###内容一部抜粋
---
![一部抜粋.PNG](https://qiita-image-store.s3.amazonaws.com/0/6824/b873bad8-9f9b-6a5a-8da2-384a4c153880.png)
---

###ドキュメントの目次

```
1.	基本方針
1.1.	はじめに
1.2.	ブランチ構成・目的
2.	運用ルール
2.1.	運用ルール詳細
3.	手順
3.1.	概要フロー
3.2.	コマンド操作・GUI操作
3.2.1.	使用ツール
3.2.2.	準備
3.2.3.	開発サイクル中
3.3.	トラブル回避のためのコツ
3.3.1.	Pushする直前には必ずPullする
3.3.2.	履歴の削除・改変(Rebase)を行わない
4.	補足
4.1.	Gitコマンド
4.2.	GitLabでのアクセス管理について
4.2.1.	グループ、サブグループ、プロジェクト、ユーザ
4.2.2.	権限
4.3.	グループごとの初期設定
4.4.	ユーザごとの初期設定
4.5.	設定ファイルの例
4.5.1.	.gitattributes  (for Unity and LFS)
4.5.2.	.gitignore  (for Unity )
``` 
###テスト済み環境
・GitLab , LFS    = GitLab.com [Bronze Plan]
・GUIツール = TortoiseGit  version 2.7.0  (OS=Windows)
・コマンド    = git  version 2.15  (OS=Linux)

###ダウンロード
https://gitlab.com/fknaopen/doc_scm_gitlab

現在のところ、pdfと編集可能なMS Wordのファイルのみ作成しています。
( SourceManagementManual_usingGitLab.docx )　

# ご利用に際して
公開、商用利用、改変等、自由に行っていただいて構いません
間違いの修正や、より良い内容への修正変更を歓迎します。

また、運用手順書の記載内容には一部、意見が分かれる話題も扱っています(Rebaseとか・・・)。　ですが、文書の目的の性質上、意見が分かれる話題であっても、どちらかに極端に倒し込んだ内容にしてあります。
読んで違和感がある場合には、所属する組織の文化に合わせて改変することで解決してしまうことをお勧めします。

# 免責
本手順書のご利用によって生ずるいかなる損害についても責任を負いかねますので、ご了承ください。
Spring Boot with Spring Security の Filter 設定とハマりポイント

## 設定例

Java Configuration で Filter の設定をする際、 `org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter` を継承して２種類の configure メソッドを上書きするのが便利です。

HttpSecurity で認証用の Filter を追加して、WebSecurity では Filter を無視する設定ができます。

```java:SecurityConfig.java

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private static final String[] STATIC_RESOURCES = {
        "/**/css/**", "/**/js/**", "/**/img/**",
    };

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // Filter を Security Filter Chain に追加
        http.addFilter(this.preAuthenticatedProcessingFilter());
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        // Security Filter Chain から除外するパス等を設定
        web.ignoring().antMatchers(STATIC_RESOURCES);
    }

    // Security Filter Chain に登録する Filter は Bean 定義しない
    public AbstractPreAuthenticatedProcessingFilter preAuthenticatedProcessingFilter() throws Exception {
        final SampleAuthFilter filter = new SampleAuthFilter();
        filter.setAuthenticationManager(this.authenticationManager());
        return filter;
    }
}
```

この辺りは他の方の記事やサイトがたくさんあるのでわざわざ書かなくても良いのですが、しばらくハマった事があるので書いておきます。

## ハマったところ

ignore 設定をしても認証の必要がない静的リソース等を含む全てのリクエストで Filter が適用されてしまうというもの。
数日間、暇を見つけては「spring security ignoring not work」等で検索しまくりましたが、ignore 設定の書き方の問題などで、解決策が見つからずでした。

今思えば、StackOverflow にあった[こちらのコメント](https://stackoverflow.com/a/40969780)はまさに解決策だったのですが、気付きませんでした。

## 原因と解決策

原因は Filter クラスに `@Component` アノテーションを付けていた事。
Configuration クラスに `@Bean` を付けるのも同様。
これによって、Security Filter Chain の外にも登録されてしまう。

解決策は当然 Bean として登録させない事。

いくつかのページで `@Bean` がついているサンプルコードが載っているので、結構同じ問題に悩まされる人もいるのではと思いました。
ただ、未確認ですが Spring Boot(starter-web?) を利用しない場合はこの問題には陥らないのかもしれません。

StackOverFlow で `FilterRegistrationBean` から除外する解決策からヒントを得て、何とか解決しましたが、`WebSecurityConfigurerAdapter` のソースから辿っているだけではイマイチ見えてこないわけです。
[Hello World で学ぶ Spring Security の仕組み](https://qiita.com/opengl-8080/items/d4971ec4d2365c85ff99) は大変参考になりました。

あと１日解決できなければ、最悪の手段「Filter 側に if 文追加」もチラついていました（笑

## 参考
[Spring Security – security none, filters none, access permitAll](https://www.baeldung.com/security-none-filters-none-access-permitAll)
[Spring Security filter chain not ignoring specified path [duplicate]](https://stackoverflow.com/questions/46716914/spring-security-filter-chain-not-ignoring-specified-path)
[Hello World で学ぶ Spring Security の仕組み](https://qiita.com/opengl-8080/items/d4971ec4d2365c85ff99)
Voyager データベースとBREADの設定

#Voyagerでデータベース構築とBREADの設定やってみる

Voyagerは公式のマニュアルで動画もあり非常にわかりやすい。
動画をみながらデータベース構築とBREADの設定やってみる。

[Voyagerのインストールにいて書いた前記事はこちら](https://qiita.com/novufo13/items/e48f0de967d34db8c828)

#参考にしたサイト

[Voyager Academy](https://laravelvoyager.com/academy/)
※画像は上記動画のスクショ。

#データベース建てる

![2018-11-24_11h16_57.png](https://qiita-image-store.s3.amazonaws.com/0/315775/abc4ac9c-e149-64cf-c2d2-9e7f91416ac0.png)

動画での設定の通りにproductのデータベースを作る

#BREADの設定

![2018-11-24_11h21_01.png](https://qiita-image-store.s3.amazonaws.com/0/315775/323111cd-6fe4-d619-6527-3aab185e924d.png)

modelを作る必要があるので下記実行

```
PHP artisan make:model Product
```
## Columnの設定

![2018-11-24_11h23_55.png](https://qiita-image-store.s3.amazonaws.com/0/315775/32a5be38-d66d-0b86-0655-13017dca6009.png)

テーブルのカラム設定をしていく。
datatype,Hiddenとか

[Input TypeのOption設定はこれを参照](https://voyager.readme.io/docs/additional-field-options)

## BREADをブラウズする

ブラウズしようとするとpermission　errorがでるので、Usersから権限設定をする。
![2018-11-24_12h08_35.png](https://qiita-image-store.s3.amazonaws.com/0/315775/c6c44f71-9f25-e276-fd36-e92c4d9c30b4.png)

今回は下記のエラーが出た。

```
"SQLSTATE[42S02]: Base table or view not found: 1146 Table 'voyagertest.products' doesn't exist (SQL: select * from `products` order by `created_at` desc)"
```
tableかviewがないとのことだが、phpmyadminで確認するとtableはある。
viewがないみたいなので、作成したmodelに下記を追加する。

`***\XAMPP\htdocs\<プロジェクト名>\app\product.php`を編集

```
class Product extends Model
{
    protected $table = 'product'; //追加
}
```

# 完成
忘れがちなrenderメソッドの使い方まとめ [Rails]

renderメソッドの使い方について曖昧だったので調べてまとめてみました。
間違い等ありましたら指摘していただけるとありがたいです。

##renderメソッドとは？
renderメソッドとはレスポンスの出力をしてくれるメソッドです。
renderメソッドを使うことで、ユーザーへのレスポンスとして送信すべき内容を指定することができます。
コントローラー、ビューで使う事ができます。

##renderメソッドをビューで使う
renderメソッドを使うと、部分テンプレートを指定することができます。
部分テンプレートを使えば、同じHTML構造の部分を共通化することができます。共通化することで、繰り返し書くコードを１回で済ませる・修正するとき修正箇所が少なくて済む、などのメリットがあります。

#####・部分テンプレートの名前

`_tweet.html.erb`のように必ず_から始めます。

#####・ビューファイル内で部分テンプレートを呼び出す時
<%= render partial: ‘tweet’ %>のように、_と拡張子除いた形で呼び出します。
partialは部分テンプレートを明示的に指定するオプションです。

#####・部分テンプレート内で変数を使いたい時
`<%= render partial: ‘tweet’, locals: { tweet: @tweet } %>`
のように、localsオプションを用いて、
`locals: { 部分テンプレート内で使いたい変数: 持っていきたい値 }`
と記述します。

#####・部分テンプレート内で繰り返し処理を行いたい時
`<%= render partial: ‘tweet’, collection: @tweets %>`
とcollectionオプションに@tweetsと複数形の変数渡すと、部分テンプレートでtweetが個別のインスタンスとして呼ばれる変数となり、さらにeach文を使用せずに繰り返し処理も行ってくれます。
`<%= render @tweets %>`
と略して書くことも可能です。

##renderメソッドをコントローラーで使う
railsではコントローラー名とメソッド名からrenderメソッドを記載しなくても自動的にレンダリングするビューを特定してくれます。
デフォルトでは、`”app/views/コントローラー名/メソッド名.html.erb”`という名前のファイルを呼び出します。
それ以外のビューファイルや形式を出力したい際はrenderメソッドで指定してあげる必要があります。

#####・特定のアクションに対応するビューを表示させる時
```tweets_controller.rb
def index
  render action: :new
end
```

とすると同じコントローラー内のnewアクションに対応するviewファイル（views/tweets/new.html.erb）を表示させます。

#####・違うコントローラー内のアクションに対応するビューを表示させる時
```tweets_controller.rb
def index
  render template: "review/new"
end
```
とすると違うコントローラー内のアクションも呼び出すことができます。
上の例ではreviewsコントローラーのnewアクションに対応するビューファイル(views/reviews/new.html.erb)を呼び出しています。

#####・jsonを返す時
以下のように、コントローラーのアクション内で`render json: @tweets`とすると、そのアクションが呼び出された際に、@tweetsの値をjson形式で出力してくれます。

```tweets_controller.rb
class TweetsController < ApplicationController

  def index
    @tweets = Tweet.includes(:user).order("created_at DESC").page(params[:page]).per(5).order("created_at DESC")
    render json: @tweets
  end
end

```
<img width="545" alt="localhost_3000-1.png" src="https://qiita-image-store.s3.amazonaws.com/0/259537/58367aac-251b-8348-d68c-faa0c2e92198.png">





#####・文字列を返す時
以下のようにコントローラーのアクション内で`render text: "文字列"`とすると、そのアクションが呼び出された際に指定した文字列を出力してくれます。

```tweets.controller.rb

class TweetsController < ApplicationController

  def index
    render text: "mojiretsu"
  end
end
```
<img width="324" alt="localhost_3000_と_pictweet4_—_ruby_bin_rails_s_—_80×24.png" src="https://qiita-image-store.s3.amazonaws.com/0/259537/fe62179e-b489-55c8-ed3a-81d4974df771.png">


#####・XMLを返す時
以下のようにコントローラーのアクション内で`render xml: @tweets`とすると、そのアクションが呼び出された際にxml形式で@tweetsの値を出力してくれます。

```tweets_controller.rb
class TweetsController < ApplicationController

  def index
    @tweets = Tweet.includes(:user).order("created_at DESC").page(params[:page]).per(5).order("created_at DESC")
    render xml: @tweets
  end
end
```
<img width="594" alt="localhost_3000.png" src="https://qiita-image-store.s3.amazonaws.com/0/259537/9e7725cf-6c5f-720f-40ce-eec3724f882e.png">
ハッシュの書き方のまとめ〜progate~

#ハッシュの書き方まとめ

ハッシュの書き方のまとめ

ハッシュには以下の3通りの書き方があります。
最後の「キーがシンボルの書き方（省略形）」が一般的なので覚える


```
キーが文字列の書き方
{"name" => "Suzuki","age" => 21}


キーがシンボルの書き方
{:name => "Suzuki", :age => 21}


省略形のキーがシンボルの書き方
{name: "Suzuki",age: 21}
Git Bash（Windows）起動時のディレクトリを変更する

1. 適当なディレクトリにGit Bashのショートカットを作成する

2. ショートカットアイコンを右クリック→プロパティ→作業フォルダー
　　　ホームディレクトリに指定したいディレクトリを入力し、適用ボタン→OKボタン

以上です。
try-finallyよりもtry-with-resourcesを使おう

## try-finallyでのリソースクローズ

tryブロックの中で何らかのリソース（InputStream、OutputStream、BufferedReader等）を扱う場合、Java7以前はfinallyブロックでcloseメソッドを呼び出すことで、tryブロック内の処理が正常終了したか異常終了したかに関わらずリソースが確実に閉じられることを保証していました。以下のような形です。

```.java
protected void copy(String src, String dest) throws IOException {
	InputStream in = new FileInputStream(src);
	try {
		OutputStream out = new FileOutputStream(dest);
		try {
			byte[] buf = new byte[100];
			int n;
			while ((n = in.read(buf)) >= 0) {
				out.write(buf, 0, n);
			}
		} finally {
			out.close();
		}
	} finally {
		in.close();
	}
}
```

また、finallyブロックで例外が発生しないよう更にチェックしたり等もありますよね。

```.java
} finally {
	if (br != null)
		try {
			br.close();
		} catch (IOException e) {
			// 例外処理
		}
}
```

ただし、これらの書き方にはいくつか問題点があります。

## try-finallyでのリソースクローズの問題点
* close処理を色々な箇所で行ったりリソースのnullチェックを行ったり等コードが冗長となる
* tryブロックの中とfinallyブロックの中の両方で例外が発生した場合、finallyブロックの中で発生した例外がスローされる（本来tryブロックの中で発生した例外が知りたいはずだが、その例外は抑制される）

こういった問題に対して、Java7でtry-with-resources構文が導入されました。try-with-resources構文によりこれらの問題は一挙に解決されます。

## try-with-resourcesでのリソースクローズ

tryのすぐ後ろにクローズの対象となるリソースの生成処理を記述します。クローズすべきリソースが複数ある場合はセミコロンで区切ります。

```.java
protected void copy(String src, String dest) throws IOException {
	try (InputStream inputStream = new FileInputStream(src); OutputStream outputStream = new FileOutputStream(dest)) {
		byte[] buf = new byte[100];
		int n;
		while ((n = in.read(buf)) >= 0) {
			out.write(buf, 0, n);
		}
	}
}
```

このように書くことで以下のような挙動になります。

* finallyブロックでcloseメソッドを呼び出さなくても自動でcloseをしてくれるようになる（ソースが簡潔になり可読性が向上する）
* close処理内で例外が発生してもtry文の中の例外がスローされる（本来知りたいはずの例外がスローされる）

これにより「try-finallyでのリソースクローズの問題点」で挙げた問題点が解決されます。

### 教訓
クローズしなければならないリソースを扱う場合は、try-finallyよりもtry-with-resourcesを使おう

### 参考
* [Oracle Technology Network](https://docs.oracle.com/javase/jp/7/technotes/guides/language/try-with-resources.html)
* [Effective Java](https://www.amazon.co.jp/Effective-Java-%E7%AC%AC3%E7%89%88-Joshua-Bloch/dp/4621303252)
プルリクエストの指摘を減らしたいあなたへ

## はじめに

個人的に、ソースコードレビューでの指摘自体は悪いことではなく、むしろプロダクトの後々の品質維持を考えると重要なことだと考えています。また、指摘から学べることも多々あり、有益な指摘をもらうことでエンジニアとしての知識・技術力の向上にも寄与すると考えています。この感覚は、私だけでなく多くのエンジニアで共通の感覚なのかなと思います。
とはいえ、（上記は理解しているものの）あまりにもその指摘数が多いと修正する側の神経がすり減ることもある、というのが現実です。

本記事では、プルリクエストの指摘数が慢性的に多く修正するのが大変、、、、、という方向けに、どのように指摘数を減らしていけば良いのか、を考えてみようと思います。

## 考え方

非常にシンプルです。以下の要領で考えます。

1. 指摘内容を分析する
　　1.1. 指摘内容を抽象化する
　　1.2. 具体的な指摘内容を抽象化したものに振り分ける
　　1.3. なぜそのような指摘を受けたのか原因を深堀りする

2. 対応策を考えてみる

以降で1つずつ見ていきたいと思います。

## 1. 指摘内容を分析する

### 1.1. 指摘内容を抽象化する

まずは指摘内容を抽象化します。自分の経験上、以下のような観点で抽象化できると考えています。
※他の観点があれば、それも追加しても良いかと思います。

* 誤字脱字（タイポ）
* プログラミング知識不足
* コーディング規約違反
* 要件・仕様誤認識
* 影響範囲考慮漏れ

### 1.2. 具体的な指摘内容を抽象化したものに振り分ける

プルリクエストに挙げられた具体的な指摘内容を、「1.1. 指摘内容を抽象化する」で挙げた項目に割り振っていきます（当てはめていきます）。すると、どういった内容の指摘が多いのかが可視化されます。

### 1.3. なぜそのような指摘を受けたのか原因を深堀りする

この作業の最後に、なぜそのような指摘を受けたのか、原因を深堀りしていきます。すると、この時点で、以下のような形で可視化されると思います。
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/23101/f0780de3-2b1b-70ec-05a8-39ac750892c3.png)

上記は、イメージですが、この例では圧倒的に？プログラミングの知識不足が原因で指摘を受けていることがわかります。

## 2. 対応策を考えてみる

指摘内容を分析してみると、上記のように自分がよく指摘をうけるところの傾向が見えてきます。つまり、そこは自分のウィークポイントでもあると考えられます。あとは、そこに対してどのような対策を打つかを検討し、次の機会に活かせることができれば、少しずつではあるもののより質の高いレビューが出せると思います。

## まとめ
タイトルは「プルリクエストの～」となっていますが、この考え方は全ての成果物（設計書、テスト仕様書等）に共通していると思います。また、この考え方は仕事における所謂「問題解決」とも言えます。指摘内容が多くあれもこれも対応しているうちに、俯瞰することを忘れがちになりますが、そういった時こそ一度立ち止まって冷静に分析してみると良いかと思います。

以上です。
プロジェクトメンバーを探す時は最低限コレだけは伝えておこう

プロジェクトマネジメントをやっていると、場合によっては自身でプロジェクトメンバーを探さなければならない時があります（所謂、要員調達というやつです）。最近、プロジェクトメンバーを自身で探す機会があったため、その時の備忘として残しておきます。

### 1. 業務内容
* プロジェクト概要
* 任せたい作業内容（例えば、設計～結合テスト等）

### 2. 求める人材
* MUSTスキル<br />
　　例えば、Java8以上の実務経験〇年以上、Spring Bootの業務利用経験有等
* WANTスキル<br />
* その他<br />
　　例えば、プロジェクトに対して前向きに向き合る、問題を自己解決できる、周りと協調して作業ができる等のビジネススキル的なこと

### 3. 参画希望時期
* いつから参画してもらいたいかを具体的に

### 4. 希望単価
* 人月単価ビジネスの場合は必須

### 5. 作業場所
* 具体的なビル名等でもよいが、伏せておく必要があれば最寄り駅から〇分等の情報

### 6. 契約期間
* いつからいつまでの契約か

### 7. 業務時間
* 9:00～18:00（休憩1時間）　等の情報

### 8. 支払いサイト
* 報酬を支払うまでの期間。例えば、月末締め翌月末払い等の情報。一般的には〇〇日サイトという。意外と忘れがちになる。

### 9. 商流の深さ
* 業務委託等でよくある商流は、実は法律によって深さが決められています（が結構グレーなことが多い）。そのためここも明記しておく必要がある。

以上です。
Docker for WindowsでNo hypervisor is present on this systemが出た時

Docker for Windowsで、以下のようなコマンド（以下のコマンドはあくまで例です）を打った際に、

```
Docker run hello-world
```

以下のようなエラーとなることがあります。

```
docker: Error response from daemon: container xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxe encountered an error during CreateContainer: failure in a Windows system call: No hypervisor is present on this system
```

このエラーメッセージの最後の方に「No hypervisor is present on this system」とあるように、Hyper-VがWindows上にない（有効になっていない）ということを伝えています。

これの解決方法として、以下の手順を踏むことで解決します。

1. BIOSでVirtualization Technologyを有効にする
2. コントロールパネルの「プログラムと機能」でHyper-Vを有効化する


### 参考
http://www.atmarkit.co.jp/ait/articles/1806/25/news026.html

以上です。
php-master-changes 2018-11-23

ちょっと更新遅れたけど、今日（というか昨日というか）は opcache と preloading の処理のリファクタリングがあった！

# 2018-11-23
## nikic: Remove unused do_free parameter from ADD_INTERNED_STRING
- https://github.com/php/php-src/commit/c6009dae346f0e3ba5190996ca1317712071ca27
- ext/opcache で、ADD_INTERNED_STRING() マクロから使われていない引数 do_free を削除

## dstogov: Refactored script creation and classes/functions copying.
- https://github.com/php/php-src/commit/b076a91c5047da3915080bb8a5ebaa36dcef726e
- ext/opcache で、キャッシュデータの情報を保持する構造体 zend_persistent_script 生成時の処理と共有メモリへのクラス/関数のコピー処理をリファクタ

## dstogov: Don't preload functions and classes declared outside of preloaded scripts (e.g. by eval code).
- https://github.com/php/php-src/commit/48b9594227964bc06f59de246b49fe88ef63b692
- preload されたスクリプトの外（eval 経由など）で関数/クラスを宣言された際に preload の対象外とするよう修正