OmniAICreator/Qiita-1.07M huggingface dataset:
髙﨑さん、草彅さん、𠮷田さん、あなたの名前はこうして化ける

Unicodeの普及でこれまでJIS第1・第2水準では入力できなかった多くの人名が表記できるようになりましたが、実際に使ってみると「化ける」ケースはまだまだあります。では、それらの文字は何がどうまずくて化けているのでしょう。その理由は一通りではありません。日本語文字セットへの収載状況、Unicodeでの表現、その2軸でいくつかに分けて見てみましょう。

用語
---
※**IBM拡張文字**⋯JIS X0208-1978（“旧JIS”, “JIS78”）を拡張する形でIBMが自社マシン用に追加した漢字と記号。代表は「**髙**」。115〜119区という本来のJISコードの規格外の句点位置だがシフトJISでエンコーディング可能。日本語版Windowsにも採用され、この領域を含むシフトJISエンコーディングは**Windows-31J**, **CP932**, **MS_Kanji**と呼ばれてShift_JISの亜種とされる（かなり雑な説明）。
※**第3・第4水準漢字**⋯JIS X0213-2000（“JIS2000”）で拡張された漢字領域。IBM拡張文字とは異なり、句点に加えて**面**という第3の桁を用意することで拡張した。シフトJISエンコーディングもそれに合わせて拡張したものを用意したが、このエンコーディングはIBM拡張文字に対応できないので実際にはほとんど実用されていない。ISO-2022-JPも拡張されているが、やはり実装例は少ない（同じく雑な説明）。
※**追加面**⋯16ビットで各国の文字規格を収容するのが無理と判明したUnicodeも面を増やして拡張された。UTF-16エンコーディングでは32ビットのサロゲートペアという表現方法を使うため、追加面の文字はサロゲートペア文字と呼ばれることが多い。

JIS第1・第2水準に含まれない文字の分類
---

<table>
<thead>
<th rowspan=3></th>
<th colspan=2>IBM拡張文字に含まれる</th>
<th colspan=4>含まれない</th>
</tr>
<tr>
<th>含まれない</th>
<th colspan=3>第3・第4水準漢字に含まれる</th>
<th>含まれない</th>
</tr>
<tr>
<th colspan=3></th>
<th>JIS2004追加文字</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<th>基本多言語面<br>CJK統合漢字</th>
<td>「髙」ほか84文字<br>★1</td>
<td>「﨑」「彅」ほか276文字<br>★2</td>
<td>「㐂」ほか多数<br>★2 ★3</td>
<td>「繫」ほか9文字<br>★4</td>
<td>「杮」ほか多数<br>★5</td>
</tr>
<tr>
<th>追加面<br>（サロゲートペア文字）</th>
<td></td>
<td></td>
<td>「𠀋」ほか302文字<br>★2 ★3 ★6</td>
<td>「𠮟」1文字<br>★4★6</td>
<td>「𠮷」ほか多数<br>★5 ★6</td>
</tr>
<tr>
  <th>CJK互換漢字</th>
  <td>「羽」ほか11字<br>★1 ★7</td>
  <td>「塚」ほか16字<br>★2 ★7</td>
  <td>「琢」ほか59字<br>★2 ★3 ★7</td>
  <td></td>
  <td>多数<br>★5 ★7</td>
</tr>
</tbody>
</table>

化けどころ
---
**★1: IBM拡張文字**
WindowsでシフトJIS保存したテキストやISO-2022-JPエンコードしたメールが他環境でデコードできません。古くはWindowsの「①」がMacで「㈰」に化けていたあれ。

**★２: 第3・第4水準漢字**
ISO-2022-JPの拡張（ISO-2022-JP-3）でエンコーディングできてしまうのでMuleなどの環境からこのISO-2022-JP-3のメールが送れてしまうのですが、デコードできる環境が少なく化けたり読めなかったり。Windowsのメーラーは大体無理。

**★3: IBM拡張文字に含まれない**
WindowsはAPIをUnicode版と非Unicode版の2セット用意しており、日本語環境だと非Unicode版APIはシフトJIS（もちろん正確にはIBM拡張文字を含む亜種であるWindows-31J）で文字列を扱います。古いアプリほど非Unicode版APIを使っているので、IBM拡張文字に含まれない文字が「?」に化けます。

**★4: JIS2004追加文字**
第3・第4水準漢字が10文字増えただけですが、Windows XP以前の標準搭載フォントが字形を持っておらず豆腐になります。
そのせいもあって、この10文字をはじくミドルウェアが販売されていたり。 http://itpro.nikkeibp.co.jp/article/NEWS/20071207/289050/

**★5: 第1〜第4水準にもIBM拡張文字にも含まれない**
つまり日本語の文字ではないとされているわけで、日本語フォントに字形が含まれていないことが多く豆腐になりがちです（フォント次第）。しかし「𠮷」は日本の人名で普通に使うだろ⋯
ちなみに分類表ではまったく触れていませんが、JISには補助漢字（JIS X0212）という文字集合も定義されており、補助漢字には含まれているという字もこの分類に放り込んであります。「杮（こけら）」なんか。

**★6: 追加面**
UTF-16を使うプログラミング環境、Javaとか.NETとかJavaScriptとかWindows API（Unicode版）とかだと、追加面の文字だけ2文字で1文字扱い（雑な説明）なので、正しい取り扱いを入れていないと

- 文字が分断されて壊れる
- 文字数カウントがおかしい
- 検索結果がおかしい
- カーソルの動きがおかしい

など発生します。また、MySQLのUTF-8が追加面文字をエンコードできないという問題があります。

**★7: CJK互換漢字**
互換漢字とは平たく言うと、似た字が収載されているので本来Unicodeに収載されるべきではなかったが、別字として収載いる各国文字コード体系があるため互換のために収載しているという位置づけの漢字です。
互換漢字はUnicodeテキストを**正規化**する際に統合漢字のコードに置き換えるというルールになっています。
その正規化処理により、人名を正しく入力していたはずがテキスト処理の結果標準字体に置き換わってしまっているということが起こります。

解説・資料
---
- http://d.hatena.ne.jp/miau/20110919/1316427760
- http://www.asahi-net.or.jp/~ax2s-kmtn/ref/index.html
- https://seiai.ed.jp/sys/text/cs/
asm.jsからWebAssemblyへの移行とその問題

# 目的

これは WebAssembly Advent Calendar 2017 23日目の記事です。

昨年、haskellのインタプリタのhugsをemscriptenを用い[さまざまな困難](http://slides.com/junjihashimoto-1/emscripten#/)がありましたが、printfデバッグで無事javascript([web版](https://junjihashimoto.github.io/hugs-js/), [nodejs版](https://www.npmjs.com/package/emhugs))にしてきました。

その後、firefox quantumによって上記のjavascriptは申し分ないほど高速化されたのですが、WebAssemblyによってさらに高速化できないか確認したくなり、今回asm.jsからWebAssemblyへの移行を行いました。

# asm.jsからWebAssemblyへの移行とその問題

これがasm.jsからWebAssemblyへの[移行に必要だった変更（PR）](https://github.com/junjihashimoto/hugs-js/pull/2)でした。

まとめると下記の5つです。

1, dlopenで読み込むshared libraryがjsからwasmになっている。
2, [Module['locateFile']](https://kripken.github.io/emscripten-site/docs/api_reference/module.html#Module.locateFile)でwasmの読み込むパスを指定する。
3, wasmファイルのなかではEM_ASMできない。
4, wasmのロードではすべてのシンボルが解決できてないといけない。
5, emscriptenの吐き出すhtml(wasmをロードする関数が入っている)がasm.js版と違うので更新が必要。

## dlopenで読み込むshared libraryがjsからwasmに

asm.jsからwasmになり、関数テーブルのフォーマットが変わりました。
関数テーブルはWebAssemblyオブジェクトのtableになり、従来のsignature（関数の型のようなもの）ごとに異なる配列であった関数テーブルよりスリムになりました。
内部の関数の構造がことなり、従来のshared libraryと互換性がなくなり、asm.jsとwasmは両立はできません。
wasmの形式のshared libraryに切り替えましょう。

## wasmを読み込むパスの管理

shared libraryを使う側のファイルを```-s WASM=1```をつけてコンパイルするとjsとwasmの両方のファイルが出力されます。しかし、```node "jsの置いてあるディレクトリ"/hoge.js```のように実行してもwasmファイルを読み込んでくれません。

APIリファレンスにありますが、[Module['locateFile']](https://kripken.github.io/emscripten-site/docs/api_reference/module.html#Module.locateFile)を設定しましょう。

## shared libraryでEM_ASMが使えない

EM_ASMはC言語の中に埋め込まれたjsを呼び出す関数ですが、wasmの中では外部のjsの関数は呼べますがjsは評価できないので使えません。shared libraryなのにemscriptenの世界のアセンブラであるjsが呼べないという何とも拡張性のないものになってしました。
必要に応じて外部のjsで下記のようなEM_ASMをエミュレートする[関数](https://github.com/junjihashimoto/hugs-js/blob/master/hugs98-Sep2006/src/libem.js)を用意しました。
実行時にevalされるので速度はもとのEM_ASMより遅いと予想されます。

```javascript
function em_asm_0(exp){
  eval(Pointer_stringify(exp));
}
function em_asm_1(exp,arg0){
  var $0=arg0;
  eval(Pointer_stringify(exp));
}
```

## wasmのシンボル解決

asm.jsのときは実行時にシンボル解決して、使ってない関数のシンボルが解決できなくても問題ありませんでした。しかし、wasmになってwasmファイルをロードするときにすべてのシンボルが解決できるかチェックするようになりました。実行する前にチェックするのでデバッグしやすくなるため悪くない動作ですが、asm.jsのときとは違うのでシンボル解決のデバッグを今回行いました。

## 初期化方法

webでemscriptenのファイルを読む方法がasm.jsとwasmで違いますが、生成されたhtmlをみて直しましょう。

# ベンチマーク

web版はfirefox quantumで起動時間を見ました。chromeだとwebassembly.compileを使っていないのにエラーがでて起動できませんでした。起動時間はwasmにすると遅くなりました。
アセットのほうが多いためwasmにした効果がまったく出てないです。

```
# asm.js版
https://junjihashimoto.github.io/hugs-js/
Finishまで7.61s
# wasm版
https://junjihashimoto.github.io/hugs-js/wasm/
Finishまで9.03s
```

nodejs版はasm.jsとwasmでインタプリタの起動時間を見てみました。
wasmの方は半分の時間で起動できました。

```
# asm.js版
$ time ./node_modules/.bin/runhugs ../shyougi-app/Shyougi.hs
123

real    0m9.799s
user    0m11.281s
sys     0m2.203s
# wasm版
$ time ../hugs-js/bin/runhugs ../shyougi-app/Shyougi.hs
123

real    0m5.789s
user    0m6.141s
sys     0m1.688s
```

# まとめ

haskellのインタプリタであるhugsをasm.jsで作っていたものをwasmへ移行しました。
shared libraryに関する問題がありましたが、無事解決できました。
ブラウザでは移行後起動が遅くなりましたが、nodejsでは半分の時間で起動できるようになりました。
今となって後悔しているkamiのこと

クリスマス期間になると喜ぶ人もいれば悲しむ人もいる。そんな極端な季節の中で、自分が作った[`guregu/kami`](https://github.com/guregu/kami)というWAFについて真面目に考えた。`context`の正しい使い方や、kamiのAPIで後悔していることを晒そう。

### kamiを作ったきっかけ

まずはkamiの歴史について簡単に説明する。GunosyでアプリのAPIサーバーをRailsからGoに少しずつ書き直していたが、モノリシックだったmodelsとhandlersパッケージが大きくなりすぎて分かりにくくなってしまった。大きいパッケージを複数の小さなパッケージに分けようと思った。しかしユーザーのセッション情報などは様々なパッケージにどう共有したらいいでしょう？

当時使っていたGojiというWAFでは、リクエストごとに`Env`という`map[string]interface{}`が付いていた。 これを使えば、どんなパッケジーにHTTPハンドラーやミドルウェアを入れても`Env`にあるデータの共有ができた。 しかし文字列のキーは被りやすいし、各ハンドラーで`interface{}`から無理やり変換するのも気持ち悪いと思った。

Go 1.5が出た頃に`x/net/context`というパッケージが登場した。今は標準化されて`context`になっている。`context`はgoroutineのキャンセル処理を管理する機能と、”リクエストスコープ”のデータをmapのように扱う機能が付いている。`context`のデータ共有機能を使ったら、Gojiの`Env`の問題を解決できる。

このcontextパターンで`interface{}`の気持ち悪さから逃れる。

```go
package user

import "context"

// 共有したいデータ。これをcontextに入れる。
type User struct {
	ID int 
	// ...
}

// userKeyは小文字なので他のパッケージはuserKeyを使えない。
// つまり、このパッケージだけはcontextの中のUserがいじられる。
// 他のパッケージと被ることもない。
type userKey struct{}
      
// contextに入れる
func NewContext(ctx context.Context, u User) context.Context {
	return context.WithValue(ctx, userKey{}, u)
}

// contextから出す
func FromContext(ctx context.Context) (User, bool) {
	u, ok := ctx.Value(userKey{}).(User)
	return u, ok
}
```

Gojiの一部に`context`や違うルーターやURLベースのミドルウェアの仕組みを適当に足して、kamiが生まれた。

### 後悔その１・標準ライブラリとの互換性を破った

早速本題に入ろう。標準ライブラリのHTTPハンドラーはこうなっている。

```go
type HandlerFunc func(ResponseWriter, *Request)
```

しかしGo 1.7までは`*http.Request`に`context.Context`が入っていなかった。

kamiのハンドラーはこうなっている。

```go
type HandlerFunc func(context.Context, http.ResponseWriter, *http.Request)
```

これでcontextは使いやすくなるが、kamiのために書いたハンドラーとミドルウェアは他のWAFで使えなくなってしまう。

当時は破るしかなかったと思うが、Go 1.7が出た瞬間にkamiがレガシーソフトになってしまった。Go 1.7が出るまでにkami 2.0を作って標準に従えばよかった。後悔している。

### 後悔その２・contextの許せないアンチパターンを提供した

`kami.Context`か`*kami.Mux.Context`を変えることによって、全てのリクエストのベースコンテキストを設定できる。つまり、リクエストスコープじゃないデータを簡単にcontextに入れられる。`*sql.DB`とかモデルのレポジトリを入れるために用意してしまった。今やこのcontextの使い方はアンチパターンとして認識されている。やっぱりリクエストの事前にcontextをいじるのはアウトだ。後悔している。

### 後悔その３・contextを自動的にcancelしなかった

Go 1.7以来、`*http.Request`にある`context.Context`は自動的にcancelされる。しかしkamiのデフォルトではcancelされない。リクエストが終わったらcancelするという仕組みはとても便利。たとえば途中で切れたリクエストで無駄なDBクエリーをしないためなどに使える。フラグにしなきゃよかった。後悔している。

### 後悔その４・APIに`interface{}`の乱用

これはGojiを真似てやったが、kamiのHandle系API（`kami.Get`, `kami.Post`など）は`kami.HandlerType`の引数を受け取る。`kami.HandlerType`は実は`interface{}`で、実行時に無理やり`kami.HandlerFunc`に変換される。`http.HandlerFunc`や`http.Handler`とか色々な型を渡せる。変換できない場合は起動時にパニック。

Goはせっかく型があるので正しく使おう。`net/http.Handler`のように、全てを一つのインターフェスにまとめればよかった。後悔している。

### 後悔その５・Gojiに依存しすぎた

kamiのLogHandlerとAfterwareはそのまま`github.com/zenazn/goji/web/mutil.WriterProxy`を使っている。その長いパスをわざわざインポートしないといけないユーザーは可哀想に思うようになった。`kami.WriterProxy`にすればよかった。申し訳ない。後悔している。

### 後悔その６・新しいバージョンの提供が難しかった

kamiを作った当時はバージョン管理が大変だった。ビルドするたびにGitHubからHEADをダウンロードするユーザーが多かった。互換性のないv2をプッシュしたら、たくさんの人に迷惑かけてしまうことになると思った。ビルドを壊せないために、イマイチなAPIを残すしかなかった。結局は進化出来ないライブラリになった。後悔している。

## 最後に

かなり暗い記事になったが、私は後悔＝学習体験だと思っている。今でもkamiを使っているし、作ってよかったと思う。ただしアンチパターンを使わないように気をつけてほしい。
kamiで失敗したことを全て熟考して、近いうちに新しいkamiを出したい。
皆さんの意見を待っています！
eclipse　プロジェクト記述ファイル (.project) がありません。

<h1>私の事例</h1>
eclipseで作成したworkspeceをGoogleDriveにアップロードして管理していました。
そのworkspaceをいつもと違うPCで作業をするため環境構築をし新たなeclipseに入れたところ
<img width="391" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/224919/b02aa1fc-5fc9-32ff-d69d-db7fa4fbe7f4.png">

本来であれば「.classpath」「.project」となるはずが勝手に変わっていました。
これがプロジェクト記述ファイル (.project) がありません。というエラーの原因でした。

私の友人から教えてもらったことはファイルをメモ帳で開き
<img width="450" alt="cap.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/224919/a67977db-1635-975c-d9ad-adde1567dcbb.png">

ここから

<img width="449" alt="cap2.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/224919/560bc467-d562-bec9-42a5-b55f51e15446.png">

このように変えるだけです。


<img width="188" alt="cap3.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/224919/eaaeae3b-b97d-f806-2183-b052baad9859.png">

これをもうひとつの「_project」のファイルにも同じ作業をしたら完了です！
Apache2.4.6にmod_layoutを導入する

apache2.2系にmod_layoutを導入する記事はあったが、2.4系にmod_layoutを導入する方法が
見つからなかったので、作業をメモ。結論から言えば、2.2系と変わらないようです。

# 環境
virtualbox : 5.0.16
CentOs: 7.4.1708

# 準備
httpdとhttpd-develをインストール
$ sudo yum install -y httpd httpd-devel

httpd-develがないと、mod_layoutのmakeでaspxコマンドがないと言われる。

$ httpd -v
Server version: Apache/2.4.6 (CentOS)

# mod_layoutインストール
$ cd /usr/local/src
$ wget https://fossies.org/linux/www/apache_httpd_modules/old/mod_layout-5.1.tar.gz/
$ sudo tar xvf mod_layout-5.1.tar.gz
$ cd ./mod_layout-5.1
$ sudo make
$ sudo make install

※　warningが出るが、無視。
・・・・・
chmod 755 /usr/lib64/httpd/modules/mod_layout.so
[activating module `layout' in /etc/httpd/conf/httpd.conf]
・・・・・
インストールできました。

httpdリブート
$ sudo systemctl restart httpd

インストール確認（layoutモジュールがあるか）
$ httpd -M | grep layout
layout_module (shared)

あとは、header.html等を作成すればOKです。confファイルで.htaccessの許可を忘れずに。


# 参考
https://qiita.com/motomiya326/items/ce0b19bcf9c9574ac156
pythonプログラマ限定　特許等の知的財産についての質問があれば答えるよ

弁理士のcofです。弁理士は、あまり知名度はございませんが、一応知的財産の専門家です（弁理士法1条）。
このような使い方がよいのかどうかわからないけれど、投稿してみます。
以前投稿した知的財産関連の記事が意外と多くの人に閲覧されているので、多少興味を持っている方がいるのかと思いまして本記事を記載いたしました。

もし、特許、意匠、商標、著作権等の知的財産でわからないことがあったらこの記事のコメントで質問してください。
わかる範囲で答えます。ただ、あまりにも回答に負荷がかかるような質問（この技術って特許性がありますか等の個別具体的な質問など）については答えないこともあります。また、回答までかなりのお時間をいただく場合がございます。ご了承ください。

pythonに限定したのは、自分はほとんどpythonしかわからないので、細かい話になった時に例を出しやすくするためです。この要件についてはあまり厳密にお考えにならなくても結構です。
AWSのハンズオン作ってみた

# なんのために？

会社の内部で「クラウドエンジニアを育成しましょう」というわけでハンズオン部分を担当しました

# 要するにどういうやつ？

テーマは「変遷」です。
クラウド技術って進化速いですよねー
Re:Invent でもいっぱいでましたし。
そういう進化についていくにはやっぱり「何がおいしいの？」を理解しないとダメだと思うんですよね。
人間って必要性がないものに対して強烈な興味をもたないですし。

まぁそういうことです。クラウドの進化によって我々エンジニアがどういった恩恵を得てきたのか。
そういうのを知ってもらいたくてけっこう頑張って作りこみました。

## 具体的には？？？

作ったアプリは以下の構成図みたいなやつです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/105030/91bf33fb-f75f-c291-1779-80573b241c4a.png)

Angularで作ったSPAの静的コンテンツを専用バケットでホスティングし、CloudFrontで配信するという御馴染みの構成です。
んでデータを管理するバックエンドアプリケーションとしてREST-APIにつなぎこむという感じです。

実際のアプリは↓こちら
![image.png](https://qiita-image-store.s3.amazonaws.com/0/105030/11c7aa2b-1205-9862-40c3-5f3b351ea1ae.png)
※GIFはPNGに自動変換されちゃうのか。。。


第二回で CloudFormation 化 & ElasticBeanstalk お試し回を実施。
第三回で最近流行りの ServerlessFramework に仕様変えずに乗っける、ということをやりました。
サーバーレス化した時のアプリ構成は↓以下の図のような形です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/105030/6f8e93a2-ffeb-31c6-2024-30a845a58ebb.png)

DynamoDBが増えてますが、増やしました。第一回ハンズオンでDynamoDBがなかったのはコンテンツ作成リソースの都合です。orz

# 苦労したとこ

筆者まだまだペーペーのへっぽこですので知らないところも多く、なんだかんだコンテンツ作成に時間かかりました。
アプリ動かねー
CloudFormationこけてるー
SPAうまく動かねー
ベストプラクティスなんやねんー
みたいな・・・

ひたすらググってなんとか解決。
第二回でCloudFormationのテンプレートを虫食いにしといて穴埋め問題形式で課題だしたりしたんですが、
割と受講者の皆さん苦しんでたようですね。
でもあれ読んで理解して初めてわかる機能もあるかもしれません。
個人的にはインスタンスプロファイルとかテンプレートを自分で書いて全体像がはっきりしてきた、というのがあります。

# 作ってよかったこと

日付変わってますが、本日（＝２０日）ソリューションアーキテクトアソシエイトを取得してきました。
やっぱこんだけコンテンツ作ってきてるとなんだか簡単に思えました。。。
得点率87%でした。
勉強は試験日当日に模擬試験やってスマホでなんか適当に公式から落としてきたPDFを途中まで読んだだけ。
※ちゃんとやりましょう。。。

# コンテンツ運営

来年まで考えてつくりこんでみました。
まずハンズオン資料はGitbookで作成し、ビルド、S3＋CloudFront構成で受講者に公開。
CloudFrontのTTLは３秒に設定。
バケットは２つ用意しておき、資料更新の度にCloudFrontのオリジンを切り替えて運用しました。

フロントとバックエンドのつなぎ込みがダサい作りになっちゃってたのでこの辺りのかっこいい作りを体験してもらえればよかったんですがね＞＜

でももうお金かけたくないのでfirebase でデプロイできるようにちょろっと改造しときました。。。
~~AWSへの裏切り！~~

来年からは
npm run build
firebase deploy
でコンテンツ更新完了です。
ぶっちゃけ座学資料もGitbook化したいなぁと内心思い中。
思ってるだけです。


記事は以上になりますー
乱文失礼しましたー
Laravel ValetでWordPress開発環境を構築する

## 背景
phpの開発環境が出来たので、ついでにwordpressをサクッと入れてみようと思いました。[VCCW開発者の方のブログ](https://capitalp.jp/2017/02/07/wp-cli-valet/)を読むとどうやら簡単らしい。

## 必要な２つの手順
###・[WP-CLI](http://wp-cli.org/ja/)をインストールする
###・Valet用の[WP-CLI コマンド](https://github.com/aaemnnosttv/wp-cli-valet-command)をインストール

## 発生した問題
何か起きるたびにfish側の問題なのかそれとも他の要因なのか、何か問題が起きるたびによく分からない。。。
### ・該当のコマンドがインストールできない
`wp package install aaemnnosttv/wp-cli-valet-command`
を叩くと、`PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted`と怒られ、メモリが足りない模様。
調べてみると同じ現象の人を発見。

[Allowed memory size of 134217728 bytes exhausted](https://github.com/aaemnnosttv/wp-cli-valet-command/issues/14)
全く同じ問題。
`increased memory_limit to 512M`で解決とのこと。
どこのphp.ini触るのか調べると、`/usr/local/etc/php/7.0/conf.d/php-memory-limits.ini`とあったのでdone.

### ・mysqlが起動できない
さてこのまま無事終わるかと思うと、`wp valet new hello`を叩いてみると、以下の問題が発生。

`ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)`

おいおい。またかよ、MySQLで何で問題が…
ただ今回は簡単で、
`sudo mysql.server start`
これで解決しましたとさ。

おしまい
nem-sdk を使ったアプリケーションを速攻作る。

アドベントカレンダー全然間に合わないマンなので、急いでアプリケーションを作りました。

<img width="300" alt="スクリーンショット 2017-12-18 1.05.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/69007/f9cc0da2-be84-527e-c6ac-006d671a76b5.png">

取りあえず動くところまで作っただけなので、react としてはクソ適当な実装になってます。週末 redux 入れてきれいにします。

[him0/nem-joya: ごーん](https://github.com/him0/nem-joya)

まだ完成していないので、年末までには出す。

# 環境
NodeJS (v8.9.0)
create-react-app (1.4.3)
yarn (1.3.2)

## Webpack 使えば、フロントでちゃんと動くよ

```bash
$ mkdir nem-application
$ create-react-app nem-application
$ yarn add nem-sdk
```

ES6 で、NEM-SDK を利用する場合は今感じで、インポートして使う

```js
import nem from 'nem-sdk';
```

Web API からブロック高を取得するのはこんな感じになる。

Web API を利用する場合は、port 指定で、`nem.model.nodes.defaultPort` を指定する。

```js
const objects = nem.model.objects.create('endpoint');
const apiEndpoint = objects(nem.model.nodes.defaultMainnet, nem.model.nodes.defaultPort);

nem.com.requests.chain.height(apiEndpoint).then(response => {
  this.setState({ blockHeight: response['height'] });
});
```

Websocket でブロック高をストリーミングで取得する。

Websocket を利用する場合は、port 指定で、`nem.model.nodes.websocketPort` を指定する。

Websocket が接続されて、新しいブロックが来ると callback が実行される。

address の指定は、transaction のストリーミングをする際に、指定したアドレスに関係するトランザクションのみを取得するために指定する必要がある（負荷対策？）。

```js
const address = 'NBBNC2K72UDIN5HMRAEUWJ4F22RZPQL2LYONUDET';
const websocketsEndpoint = objects(nem.model.nodes.defaultMainnet, nem.model.nodes.websocketPort);
const websockets = nem.com.websockets;
const connector = websockets.connector.create(websocketsEndpoint, address);

connector.connect().then(() => {
  websockets.subscribe.chain.blocks(connector, response => callback);
});
```

## 初期値は、API で更新は、Websocket でするのが良さそう

ストリーミングの API が流れてくるのは、新しいブロックが確定したときなので、まずは、Web API の方が取得 -> Websocket で流れてきたら、更新するという方針が良さそう。

ブロック高取得している実装を参考にしてもらうと良いかも。

## Websocket でトランザクションを検知

2017-12-18 の時点で websocket で unfonfirmed のストリーミングに繋いでみたが全然流れてくる気配が無かった
（NIS のソースコードが公開されていないのでこういうときに推論になってしまうのが、NEM の良くないところ）。

```ｊｓ
connector.connect().then(() => {
  websockets.subscribe.account.transactions.recent(connector,  response => callback);
  websockets.subscribe.account.transactions.unconfirmed(connector, response => callback));
});
```

今回は、ブロックに取り込まれたトランザクションがわかればよかったので、chain/heigh のストリームに含まれる、transaction を見る感じで対応した。

```js
websockets.subscribe.chain.blocks(connector, response => {
  if (response['transactions'].some(tx => tx['recipient'] === this.address)) {
  // いろいろ
  }
});
```

## Web サーバにステイトレスにする工夫するとブロックチェーンでやる意味が少し出てくる

サーバで情報保持しようと思ったら自前でストレージ用意するか、AWSか何かにお金をかけることになるのですが、ブロックチェーンだと勝手に利用者がストレージの代金を払ってくれるので良いですね。しかも、永久的に消失しないストレージという点もよいですね。

最終的には、あと何回叩くと108回なのかカウントしたいが、そのあたりをDBで対応するのではなく、nem のブロックチェーンでカウントするようにしたい。具体的には、指定のブロック以降に何回トランザクションがあったのかをそのカウントにベースにしたい。

## モザイクで、動くXXXっての出てきてるけど...

結局トランザクションの内容を見ればいいだけの話なのですよねー

開発してる人はわかると思うけど、結局ブロック高取るのと特定のアドレスのモザイクの所持状態取得するの同難易度で、意味ないなーと思うとやる気でない。

やるとしたら、鐘叩いたらもらえる108のトークンとか作って配ってもいいかな？要望あるならやりますけど、どうだろう。

やるなら、サーバサイドでも、ブロックチェーン監視する形になりますね。

## 遅れてごめんなさい

年末までには、体裁整えて遊べるようにしておきます。煩悩消し去ってこ。

実装更新したら続編書きます。
pythonで漢数字をアラビア数字に変更する

漢数字をアラビア数字に変換する必要があり、ググってみたもののピンとくるものがなかったので書いてみた。
["〇","一","二","三","四","五","六","七","八","九"].index("五")が5となることを利用したアルゴリズムである。リストの内部の順序に依存している点で結合度が高いプログラムではあるが、比較的短めに書ける点が利点である。


```py
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

KANJI1=["〇","一","二","三","四","五","六","七","八","九"]
KANJI2=["〇","十","百","千"]
KANJI3=["〇","万","億","兆"]

def lessthan10000(string):
    ans = 0
    for k2 in KANJI2[-1:0:-1]:
        if not k2 in string:
            continue
        k1,string = string.split(k2)
        ans += KANJI1.index(k1) * (10**KANJI2.index(k2))
        if not string:
            break
    if string:
        ans += KANJI1.index(string)
    return ans

def morethan10000(string):
    ans = 0
    for k3 in KANJI3[-1:0:-1]:
        if not k3 in string:
            continue
        over, string = string.split(k3)
        ans += lessthan10000(over)*(10**(4*KANJI3.index(k3)))
        if not string:
            break
    if string:
        ans += lessthan10000(string)
    return ans

string = "三十五兆八千億四百二十一万三千三百二十二"
print(morethan10000(string))
```

懸念点:
「壱」等の文字には対応していないが、多少の修正で対応できると思われる。
lessthan10000とmorethan10000とに共通のコードが多く含まれているのが気持ち悪い。この辺うまく書けそうだがうまい手が思いつかない。
ブラウザで動く言語を作ろうとする

# PeerCastプログラミング配信 Advent Calendar 2017 20日目の報告

JSON文法で書くLisp、LSONのインタプリタをJavaScriptで実装し、端末エミュレーターであるmatterでREPL対話ができるようにしました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/35206/fc7eb62d-44a9-5023-9cca-14902a520db4.png)

次はバックグラウンドでプログラムを動かし続けられるようになれば良いと思います。

## リンク

* [PeerCastプログラミング配信 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/7144)
* [lson](https://github.com/plonk/lson)
DIとDIコンテナに関する簡単な基礎まとめ

初めまして。まだプログラマー歴2年未満の若輩ですが、少しずつ自分の勉強した内容をアウトプットさせていただきます。
間違いなどありましたら是非ご指摘の方よろしくお願い致します。

とりあえず、投稿のテストも兼ねて、自分が今まで何となく使っていたJavaフレームワークの基幹システムであるDI(それを実装したDIコンテナ)について、簡単に勉強した内容を纏めさせていただきます。

#DIとは？
依存性の注入(Dependency Injection)の略。
IOC(Inversion of Control:制御の反転)の原則を実現するソフトウェアデザインパターン。
あるクラス(仮にインターフェイスクラスと呼ぶ)に必要となるクラス(仮にコンポーネントクラスと呼ぶ)を設定する事(この設定動作を「インジェクションする」ともいう)。
DIを用いることで、ロジックを構成するインスタンスの生成と依存関係をインターフェイスクラスから分離することができる。

#DIの背景
アプリケーション開発の規模が大きくなってくると、１つのロジックを複数のコンポーネントクラスを組み合わせながら実装する事が多くなる。
そうなってくると、クラスの結合度が段々と高くなっていき、部分的な実装の差し替えによる変更コストが高くなる。

```Java
// ユーザーに関する処理を行うインターフェイスクラス
public class UserServiceImpl implements UserService {

	// データ永続化に関わるコンポーネントクラス
	private UserRepository userRepo;
	private AddressRepository addressRepo;

	/* コンストラクタ */
	public UserServiceImpl() {
		this.userRepo = new UserRepositoryImpl();
		this.addressRepo = new AddressRepositoryImpl();
	}
}
```

このようなクラスを実装する場合、事前にコンポーネントクラス(UserRepositoryImplとAddressRepositoryImpl)が揃っている必要がある。
もしもこれらが未完成であった場合、ダミークラスを利用することになるだろうが、開発規模が大きくなるとダミークラスの差し替え一つにも
変更コストが大きくなっていく。

このようなクラスの結合度を低くする方法として、DIの考え方での実装を行ってみる。
具体的にいうと、インターフェイスクラス内部でのコンポーネントクラスのインスタンス化をやめ、コンポーネントクラスのインターフェイスを引数で受け取る事が挙げられる。

```Java.UserServiceImpl
	/* コンストラクタ */
	public UserServiceImpl(UserRepository userRepo,AddressRepository addressRepo) {
		this.userRepo = userRepo;
		this.addressRepo = addressRepo;
	}
```

```Java.UserService呼び出し処理
	UserRepository userRepo = new UserReposiotryImpl();
	AddressRepository addressRepo = new AddressRepositoryImpl();
	UserService userService = new UserServiceImpl(userRepo,addressRepo);
```

これにより、UserServiceImpl内部を変更することなく、呼び出し側でダミーとコンポーネント実装クラスの差し替えが可能となる。
ただ、上記の実装でも、結局インターフェイスクラスに対する各コンポーネントクラスの設定は手動で行うことになり、変更コストは大きいまま。
できれば、これらの設定も全て自動化してしまいたい。それを実現してくれるのがDIコンテナとなる。

#DIコンテナとは
DIを自動で行ってくれる基盤をDIコンテナという。
インターフェイスの呼び出し元クラス(呼び出し元クラスと呼ぶ)は、上記のように手作業でインターフェイスクラスの設定や実装を行うのではなく、
DIコンテナを経由して、コンポーネントクラスを設定された状態のインターフェイスクラスのインスタンスを取得することができる。
勿論、コンポーネントクラスがさらに別のコンポーネントクラスに依存していた場合、それに対する設定も行ってくれる。

#実装例
```Java
// SpringのDIコンテナ機能による実装
// 事前に、DIコンテナに関する設定を全て完了させている
public class UserServiceImpl implements UserService {

	@Inject
	private UserRepository userRepo;

	@Inject
	private AddressRepository addressRepo;
}
```

#DIコンテナを活用するメリット
依存性の解決：インターフェイスクラスとコンポーネントクラス間の依存性を解決できる
スコープ制御が可能：コンポーネントクラスのインスタンス生成から破棄までのタイミングをそれぞれ個別に設定できる。
あるコンポーネントクラスはシングルトンオブジェクトとして使い回し、あるコンポーネントクラスは毎回新規生成するといった制御が可能となる
AOPの提供：DIコンテナからコンポーネントクラスを取得する際に、一律で共通処理を挟み込むことができる
その他、ライフサイクル制御が可能etc...

#備考
インターフェイスクラスとコンポーネントクラスの関係は相対的な物で、あるクラスにとってはインターフェイスクラスであるクラスが別のクラスにとってはコンポーネントクラスであることは十分に考えられる。
Ancient C探訪記：演算子編

**おことわり**： この記事では「1975年頃のC言語」仕様を解説します。2017年現在のC言語仕様とは異なるため、あなたのC言語ライフには役立たないことを予めご承知おきください。

（本投稿は [Ancient C探訪記](https://qiita.com/yohhoy/items/6631443736ab779d3fbb) シリーズの一部です。）

お次は「演算子(Operators)」です。どんどん行きましょう。~~雑な進行~~。

# Ancient Cの演算子
## 複合代入 =op
"[C Reference Manual][cman]" §7.14 Assignment operators 以下の §7.14.2 〜 7.14.11 から引用します。Ancient Cの複合代入(compound assignment)は **イコール(`=`)の後ろに演算子を配置** する構文です。

> 7.14.2 lvalue =+ expression
> 7.14.3 lvalue =- expression
> 7.14.4 lvalue =* expression
> 7.14.5 lvalue =/ expression
> 7.14.6 lvalue =% expression
> 7.14.7 lvalue =>> expression
> 7.14.8 lvalue =<< expression
> 7.14.9 lvalue =& expression
> 7.14.10 lvalue =^ expression
> 7.14.11 lvalue = | expression
> The behavior of an expression of the form `E1 = E1 op E2`; however, `E1` is evaluated only once. Moreover, expressions like `i =+ p` in which a pointer is added to an integer, are forbidden.

```c:ancient-assign.c
int x = 42;

x =/ 2;  /* x = x / 2; と等価 */
x =- 4;  /* x = x - 4; と等価 */
```

実はこの構文は致命的な問題を抱えています。`x=-1`という表記が、複合代入演算(`=-`)と、符号(`-`)明示した値(`1`)の代入(`=`)とで曖昧になってしまいます。空白文字を入れて`x= -1`と書かない限り、最長マッチにより`=-`と解釈されたようです。

ご存知の通り、標準規格（ANSI C、C90）では "イコール(`=`)の前に演算子を配置” する構文に変更されています。この構文ではAncient Cのような曖昧さは生じません。[^chist]

[^chist]: これは後にDennis Ritchie氏自身が誤り(mistake)であったと認めています。"[The Development of the C Language](https://www.bell-labs.com/usr/dmr/www/chist.html)"より引用します; "In B and early C, the operator was spelled `=+` instead of `+=`; this mistake, repaired in 1976, was induced by a seductively easy way of handling the first form in B's lexical analyzer."


## 単項演算子 +
Ancient Cには 単項演算子`+` が存在しません[^op-add]。単項演算子(Unary operators)としては、`*`, `&`, `-`, `!`, `~`の5種類のみが定義されます。

[^op-add]: “単項演算子`+`”は `+17` のように正符号を明示するものです。単項演算子とは別に、算術加算の2項演算子`+`（例：`1+2`）はAncient Cにも存在しています。


## sizeof 演算子
"[C Reference Manual][cman]" §7.2.10 sizeof expression より引用します。Ancient Cにおけるsizeof演算子は、式(expression)のみが対象となります。

> The `sizeof` operator yields the size, in bytes, of its operand. When applied to an array, the result is the total number of bytes in the array. The size is determined from the declarations of the objects in the expression. This expression is semantically an integer constant and may be used anywhere a constant is required. Its major use is in communication with routines like storage allocators and I/O systems.

標準Cにおける `sizeof ( 型名 )` のように、型名(type-name)からサイズを直接取得できません。

適当に明日以降につづきます。

[cman]: https://www.bell-labs.com/usr/dmr/www/cman.pdf
CloudFrontにおけるオリジンからのHTTP 5xxステータスコードのキャッシュ挙動 

好きなAWSサービスはCloudFrontのコマコウです。
(本記事は、2017年12月20日時点のCloudFrontの仕様です。)

# 要点
- CloudFrontはオリジンからのHTTP 5xxステータスコードを処理する際に、エッジロケーションのオブジェクト有無で挙動が異なる
- キャッシュの有効期限が切れても、エッジロケーションはオブジェクトを保持し続けることはある
- エッジロケーションにオブジェクトが無い場合：CloudFrontのカスタムエラーページ設定に従う
- エッジロケーションにオブジェクトが有る場合：エッジロケーションのオブジェクトをレスポンスし続ける

# 背景
CloudFrontがオリジンからのHTTP 5xxステータスコード処理する際に、エッジロケーションに保持していたオブジェクトをビューワーにHTTP 200ステータスコードで応答し続けると問題があるシステムはあります。例えば、動的サイト・APIサービスでCloudFrontを利用している構成は注意が必要です。

# 環境
今回は、LAMP環境で、RDS/EC2(WEBサーバ)/ELB/CloudFrontを利用した環境を例とします。

# CloudFrontの挙動
##エッジロケーションにオブジェクトが無い場合
1. ビューワーがリクエストする。
2. エッジロケーションがオリジンにリクエストをする。
3. オリジンが5xxエラーをエッジロケーションにレスポンスする。
4. CloudFrontのカスタムエラーページの設定に従い、ビューワーにレスポンスする。
カスタムエラーページが未設定(デフォルト)の場合、5xxステータスコードをビューワーにレスポンスする。5分間に渡り、エッジロケーションは 5xxステータスコードをキャッシュする。
![figure-1.png](https://qiita-image-store.s3.amazonaws.com/0/58822/d3db8c93-b839-e722-b30c-e1703ac2d236.png)



##エッジロケーションにオブジェクトが有る場合
1. ビューワーがリクエストする
2. オブジェクトの有効期限が切れてない場合は、エッジロケーションがオブジェクトをビューワーにレスポンスする。キャッシュの有効期限が切れている場合は、オリジン(ELB・WEBサーバ)にリクエストする
3. オリジンが5xxエラーをエッジロケーションにレスポンスする
4. カスタムエラーページのエラーキャッシュ最小 TTL の期間(デフォルトで5分)、エッジロケーションはビューワーに対して、オブジェクトの有効期限が切れていても、エッジロケーションに保持しているオブジェクトをレスポンスし続ける。エラーキャッシュ最小TTLを経過後のリクエストは、再度オリジンにリクエストを行う。
5. 再度オリジンにリクエストされたオブジェクトが、5xxステータスコードをレスポンスすると、エッジロケーションに保持しているオブジェクトをレスポンスする。
6. 1~5を繰り返えします。ビューワーにはエッジロケーションからオブジェクトが200ステータスコードでレスポンスされますので、表面上は正常に動作しているようにみえます。
![figure-2.png](https://qiita-image-store.s3.amazonaws.com/0/58822/ba0763fb-8a73-538b-280b-2be86a66dc49.png)


#対策案
CloudFrontが、オリジンからの5xxステータスコードのレスポンスを、ビューワに 200ステータスコードでレスポンスさせない対策について検討しました。各環境によって、最善な方法は異なると思われます。(無作為にインバリデーションを行うと、エッジロケーションから、よしなに200ステータスコードでレスポンスされていたオブジェクトが、5xxステータスコードでレスポンスされますので、サービスダウンする可能性があります。)

1. デプロイ時にCloudFrontのインバリデーション
基本的な処理ですが、デプロイ後にインバリデーションを行い、エッジロケーションに保持しているオブジェクトをクリアにする。

2. オリジン(ELB/WEBサーバ)の5xxエラーを監視モニタリング
オリジンでHTTP 5xxステータスコードを検知したら、CloudFrontから応答しているレスポンスの確認を行う。5xxステータスコード対策後に、インバリデーションを行う。5xxステータスコードが頻繁に出ないようにエラーハンドリングしておこうね...

~~3. Lambda@Edgeを利用して、オリジンからHTTP 5xxステータスコードを応答したレスポンスに対して処理を加える。~~
~~こちらの対策は、発想段階なので、2017年度の冬休みの宿題とします。~~
※追記
(2017年12月21日時点)
Lambdaのドキュメントによると、 **CloudFront オリジンレスポンスはオリジンが 400 以上の HTTP ステータスコードを返した場合に発火しない** とのことです。
Lambda 関数をトリガーできる CloudFront イベント
http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-cloudfront-trigger-events.html

#参考
上記の挙動は、公式ドキュメントに詳細に記載されております。
CloudFront がオリジンからの HTTP 4xx および 5xx ステータスコードを処理してキャッシュに保持する方法
http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/HTTPStatusCodes.html
Air Hockey Game with cocos2d-x #1

# You will know
- How to enable multitouch
- How to support both retina and non-retina displays
- How to load images and sounds
- How to play sound effects
- How to create sprites
- How to extend the Cocos2d-x Sprite class
- How to create labels and update them

# Game configurations
- It must support multitouch since it's a two player game
- It must be played on large screens since it's a two player game
- It must support retina displays because we want to cash in on that
- It must be played only in portrait mode because I built the art in portrait

# Creating game project
1. Open the terminal and create a new Cocos2d-x project called AirHockey that uses C++ as its main language. 
  **cocos new AirHockey -p com.Almond.AirHockey -l cpp -d /Users/Almond/Desktop/AirHockey**

2. Once the project is created, navigate to its **proj.ios_mac** folder and double-click on the **AirHockey.xcodeproj** file. 

3. Select the top item in **Project Navigator** and making sure the iOS target is selected, edit the information by navigating to General/Deployment info, setting the target device to iPhone and Device Orientation to Portrait and Upside Down.
Ancient C探訪記：リテラル編

**おことわり**： この記事では「1975年頃のC言語」仕様を解説します。2017年現在のC言語仕様とは異なるため、あなたのC言語ライフには役立たないことを予めご承知おきください。

（本投稿は [Ancient C探訪記](https://qiita.com/yohhoy/items/6631443736ab779d3fbb) シリーズの一部です。）

どんどん行きます。リテラル(Literals)／定数(Constants)です。なお、Ancient Cでは“リテラル”という用語は利用されません。


# Ancient Cのリテラル/定数
## 整数(Integer)定数
"[C Reference Manual][cman]" §2.3.1 Integer constants より引用します。Ancient Cでは “10進数(decimal)” と “8進数(octal)” のみが有効です。16進数(hexadecimal)は **存在しません**。

> An integer constant is a sequence of digits. An integer is taken to be octal if it begins with 0, decimal otherwise. The digits 8 and 9 have octal value 10 and 11 respectively.

ちょっと（かなり？）変わった仕様として、8進数リテラル中に登場した 文字`8` と 文字`9` は、それぞれ8進数の値 `10` と `11` として解釈されます[^weird-octal]。ちょっと仕様がアグレッシブ過ぎるのでは...

```c:ancient-octal.c
int x = 0123; /* 10進数の値 83 */
int y = 09;   /* 10進数の値 9  */
```

なお、当然ながら標準C（ANSI C／C99）では8進数リテラルが文字`8`や`9`を含むことはできません。

[^weird-octal]: つまり、それぞれ10進数の 値`8` と 値`9` に相当します。OK？


## 文字(Character)定数
"[C Reference Manual][cman]" §2.3.2 Character constants よりテーブルを引用します。4種の制御文字 BackSpace(`\b`), NewLine(`\n`), CarriageReturn(`\r`), HorizontalTab(`\t`)、8進数エスケープ文字(`\ddd`)とバックスラッシュ(`\\`)がサポートされます。またAncient C（厳密には同Manual）では、文字コードとしてASCIIコードを前提としています。

> ```
> BS   \b
> NL   \n
> CR   \r
> HT   \t
> ddd  \ddd
> \    \\
> ```

標準C（ANSI C／C99）ではこのほかに、16進数エスケープ文字(`\xhh`)、シングルクオート(`\'`)、ダブルクオート(`\"`)、クエスチョン(`\?`)と3つの制御文字：Bell(`\a`), FormFeed(`\f`), VerticalTab(`\v`)が追加されます。

2017年現在、これらの制御文字にお目にかかることはほぼありませんが、FormFeed(`\f`)文字はPlain TextなRFCファイルに含まれていたりします。


## 文字列(String)
"[C Reference Manual][cman]" §2.4 Strings より一部を引用します。文字定数で使えるエスケープ文字に加えて、文字列リテラル中でのダブルクオート(`\"`)もサポートされます。

> In a string, the character `"` must be preceded by a `\` ; in addition, the same escapes as described for character constants may be used.

適当に明日以降につづきます。

[cman]: https://www.bell-labs.com/usr/dmr/www/cman.pdf
[ios]Webviewにプログレスバーを表示させる

WebViewを使って、Railsで作成したアプリケーションを表示させたいので、まずはWebViewを使ったことがなかったので、メモ。下記の記事を参考に、やってみました。
https://qiita.com/on0z/items/9768d2bccc29cc4e1851


環境
・xcode9
・swift4


storyboard上で、navigationcontrollerを使用しないと、アプリが落ちるので要注意です。
プログレスバーを表示させるのが、思ってたより簡単でした。
ただ、コードを見てみると、Viewの設定は簡単であっても、ローディングの表示が難しそうでした。
で、調べてみると、
・WkWebViewを使用すると、①title②URL③estimatedProgress(ローディングの状況)④loadingを監視することができる。
・その監視方法として、「KVO（Key-Value Observingの略）」がある。

あとは監視した値によって、プログレスバーを更新すれば完了。
ただ、やっぱり動的に何かするというプログラミングの基本ができていないので、勉強を進めます。

```swift:sample.swift
import UIKit
import WebKit

class WebViewController: UIViewController,WKNavigationDelegate {

    
    @IBOutlet weak var webView: WKWebView!
    var progressView = UIProgressView()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.tabBarController?.tabBar.isHidden = true
        //監視の設定
        self.webView.addObserver(self, forKeyPath: "loading", options: .new, context: nil)
        self.webView.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil)
        
        //プログレスバーを生成(NavigationBar下)
        progressView = UIProgressView(frame: CGRect(x: 0, y: self.navigationController!.navigationBar.frame.size.height - 2, width: self.view.frame.size.width, height: 10))
        progressView.progressViewStyle = .bar
        
        self.navigationItem.title = "Title"
        
        self.navigationController?.navigationBar.addSubview(progressView)
    
        
        load()

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "estimatedProgress"{
            //estimatedProgressが変更されたときに、setProgressを使ってプログレスバーの値を変更する。
            self.progressView.setProgress(Float(self.webView.estimatedProgress), animated: true)
        }else if keyPath == "loading"{
            UIApplication.shared.isNetworkActivityIndicatorVisible = self.webView.isLoading
            if self.webView.isLoading {
                self.progressView.setProgress(0.1, animated: true)
            }else{
                //読み込みが終わったら0に
                self.progressView.setProgress(0.0, animated: false)
            }
        }
    }

    func load() {
        // 表示するWEBサイトのURLを設定します。
        let url = URL(string: "xxxxxxxxxx")
        let urlRequest = URLRequest(url: url!)
        // webViewで表示するWEBサイトの読み込みを開始します。
        webView.load(urlRequest)
    }
    

    deinit{
        //監視の解除
        self.webView.removeObserver(self, forKeyPath: "estimatedProgress")
        self.webView.removeObserver(self, forKeyPath: "loading")
    }
    
}

```
LeakCanaryのアラートを調査する


# ご挨拶
この記事は[ピクシブ株式会社 AdventCalendar 2017](https://qiita.com/advent-calendar/2017/pixiv) 21日目の記事です。


今年の5月に中途入社した@verno3632と申します。前職ではインフラエンジニアをやりながら、趣味でAndroidアプリを書いていました。非公式アプリを続けていたらいつのまにか入社していました。
現在では[pixivコミック](https://comic.pixiv.net/)というサービスのチームでAndroidアプリを作っています。KotlinとかDaggerとかArchitecture Componentsとか興味あるものからとりあえず入れてみてます。


今回はLeakCanaryの話です。

# LeakCanary
https://github.com/square/leakcanary

言わずと知れたSquareのライブラリで、入れておくとアプリ実行時にメモリリークを検知して通知してくれます。入れてて当然ですよね？

Logcatを見るまでもなく、Android上だけでどこから何が漏れているのかわかるので非常にありがたい。
ですがシンプルな画面なため詳しい調査には情報が足りないよということがあります。


以下は実際にあったメモリリークです。
![Screenshot_20171220-215815.jpg](https://qiita-image-store.s3.amazonaws.com/0/2743/97280e25-38a3-c9fd-2d90-ffffb7b59f5a.jpeg)



わかんないよ。

クラス名がリーク元・先として表示されるので、そのクラスを元にあたりをつけていくわけですが、自分で書いたわけではないコードのクラスだったりすると検討がつきません。
ということで調べてみましょう。

# Heap Dumpを取得する
メモリの調査をするならまずHeap Dumpです。
最近のAndroidStudioでは[Android Profiler](https://developer.android.com/studio/profile/android-profiler.html)のおかげで簡単にDumpを取ることができるようになりました。

LeakCanaryでは[HAHA](https://github.com/square/haha)という、これまたSquareのライブラリを使って、Dumpをとっています。
初回起動時にファイル書き込み権限を求められるのも、リークを起こした際に時が止まるのもDumpをとってファイルに吐いているためですね。

Dumpファイルはhprofなので取り出して他ツールで読むことができます。

ファイルの保存場所は、Logcatに以下のようなログが流れてくるのでそこを参考にします。

```
hprof: heap dump “/storage/emulated/0/Download/leakcanary-${package}/hogehoge.hprof” starting...
hprof: heap dump completed (12MB) in 3.456s objects 789012 objects with stack traces 0
```

ディレクトリごとまるっと持ってきた方が早いかもしれません。

```sh
adb pull /storage/emulated/0/Download/leakcanary-${package}
```

# DumpファイルをAndroid Studioで読み込む
hprofをAndroid Studioで表示するには、プロジェクト直下の`captures`ディレクトリにファイルを置きます。
`captures`は各種snapshotを置いておくディレクトリで、[Layout Inspector](https://developer.android.com/studio/debug/layout-inspector.html)で撮ったキャプチャなどもここに入ってきます。

`View > Tool Windows > Captures`を開くと左のWindowから`captures`以下が見えます。

![スクリーンショット 2017-12-20 23.04.50.png](https://qiita-image-store.s3.amazonaws.com/0/2743/75565d96-8e88-a83e-ffb2-85b58a81b6ea.png)


# リーク元を調べる
hprofファイルを選択すると[HPROF Viewer/Analyzer](https://developer.android.com/studio/profile/am-hprof.html)が開きます。

![スクリーンショット 2017-12-21 12.16.29.png](https://qiita-image-store.s3.amazonaws.com/0/2743/65e58813-795e-13f0-eb1e-998d26d6b82a.png)


まず最初にリークしているインスタンスを探しましょう。
右のWindowの`Analyzer Tasks`を実行するのが早いですが、`KeyedWeakReference`のクラスから探すのもありです。`KeyedWeakReference`はLeakCanaryが検知したリーク先への参照を持っています。

次にリーク元を探します。
インスタンスを選択すると下のWindowの`Reference Tree`にそのインスタンスに関する参照が表示されます。
一番下の方にある`referent`を見ると、どこから参照されているかがわかります。

![スクリーンショット 2017-12-20 23.29.20.png](https://qiita-image-store.s3.amazonaws.com/0/2743/67d76f7b-5fb2-dae8-b866-36e68c098696.png)

`RefWatcher`はLeakCanaryからの参照なので問題ありません。`weakActivity`から漏れていますね。
数値計測用に入れていた3rd partyのSDKからでした。


# おわりに
LeakCanaryを使ってメモリリークを撲滅し、Picasso/Glideなどのライブラリで画像を扱うことによりOutOfMemoryは以前より格段に減りました。これからも計測・調査を続けてよりよいアプリを作っていきましょう。


[ピクシブ株式会社](https://www.pixiv.co.jp)では、クリエイターに向けてサービスを作っていきたいアプリエンジニアを募集しています！

明日は @yensaki です。お楽しみに！
[web]INTER-Mediator勉強会2017-#6

<p>INTER-Mediator勉強会2017-#6 に参加してきたので報告する。</p>

<p>タイムテーブルは以下の通り。</p>

<pre><code>18:00 ~ 開場・交流会
19:00 ~ プレゼン
『クライアントサイドでの書式指定』
『Docker for Macを使ってINTER-Mediatorを試用する』
21:00 ~ クロージング
21:00 ~ 有志による忘年会
</code></pre>

<p>今年度は地方での開催が何度か行われた。自分は、残念ながら参加できなかったのだが、来年こそは地方での勉強会に開催できたらと考えている。</p>

関連情報
<a href="https://inter-mediator.com/ja/">INTER-Mediator</a><br />
<a href="https://cocoa-kanto.connpass.com">Cocoa勉強会 BUKURO.swift (connpass)</a><br />
<a href="https://atnd.org/groups/cocoa-study">Cocoa勉強会 BUKURO.swift (ATND)</a><br />
<a href="http://cocoa-study.peatix.com">Cocoa勉強会 BUKURO.swift (Peatix)</a><br />

【Cocoa練習帳】
<a href="http://www.bitz.co.jp/weblog/">http://www.bitz.co.jp/weblog/</a><br />
<a href="http://ameblo.jp/bitz/">http://ameblo.jp/bitz/</a>（ミラー・サイト）<br />
<a href="https://t.co/6P3h2jtbRk>note</a><br />
<a href="https://qiita.com/m_yukio>Qiita</a><br />
プリンシプルオブプログラミングを読んで（1）

# きっかけ
1. Amazonで半額セールをしていたので技術書を何冊か購入していたがじっくりと読む機会が無かった。
2. 私が勤めている株式会社gumiでは勤続数年毎にリフレッシュ休暇というものを5日間とる事ができ、今年2回目のリフレッシュ休暇が貰える年だった。
3. ずっとアプリの開発や運用に追われて、それなりに頭の中がごちゃごちゃしていた。
4. よし、リフレッシュ休暇取ろう！（先週金曜日）→上司に理解してもらえ、休暇を取る事ができた！
5. ただ観光にふけってるだけと思われたらなんか悔しいので、ちょっとは向上しようとしてますよアピール。

という思考の流れで、「プリンシプルオブプログラミング」を読んで共感を得た内容や、得られない内容をまとめてみようかと思いました。
この本を選択したのはアプリ開発・運用でおかしくなった自分の実装スタイルを、この本を読んで修正したいな、というのが理由です。
でも観光もしてたので全部読めたわけではなく、気が向けば続編を書こうと思います。
## プログラミングは製造ではなく設計
なんかかっこいいと思った。
プログラミングは設計行為であり、その設計に沿って、ビルド（製造）されたものは動く。
## コードはできるだけ早く書き始めるべき
コードを書かないと不明確な部分だらけだからだそうです。
実装時に疑問が出るのは実装前にそれらを洗い出せていないからだと思ってた。
## コードはシンプルに
はい。
つい色々な機能を詰め込んでしまいます。
そういうコードは読みにくく、修正しにくく、修正に時間がかかり、もしくは手をつけたくないと、悪い事だらけになりますよね・・・
## コードは頭の良さをアピールする場ではない
トリッキーなコードを書かれても困ります。
## 今不要なら今書くな
「将来使うかもしれないから〜」という機能を実装したものの、日の目をみた記憶がない私としては凄く分かりますw
今必要なことに時間を割こう。
## コードのコピペ厳禁
はい・・・。
複数箇所に似たようなコードがあると、修正が必要な時に修正漏れが発生する危険がありますし、「似たような」コードなので、どこに修正を入れるべきか全部きっちり把握して修正しなければならないという疲れる作業を強いられてしまいます。
## 意図が伝わるようなコードを書く
コードは一度実装したらそれっきりということはなく、修正や機能追加が必要となる時期が必ずあります。
そのとき必ず人がそのコードを読むので、動作を把握しにくいコードはその作業の妨げになってしまいます。
## コードは読みやすさ優先
読みやすければコードの改善もしやすいという事です。
（そういうコードを書ける人のコードに改善する余地があるのかは別ですが）
## コメントは書く
理想はコメントが無くても理解できるコードを書く事。
だが、コードは「what」「how」があっても「why」は表現できないため、後でそのコードを読む人のためにもコメントを書きましょう、ということ。
コメントで説明しなくてもよい、分かりやすいコードを目指しつつ、それでも表現できない部分にはコメントを書く。
## 適切なメソッド名をつけられたということは正しく設計されている証
これ、苦手なので毎回頭を悩ませてます。
書籍の中で、どうすればいいか書かれてましたので、今後取り組んで行きたいと思ってます。
1. 名前にはより多くの情報を詰め込むようにする。
2. 複数の名前の候補を挙げて、そこから選んでみる。
3. 命名後、「他の意味と間違えられる事はないだろうか？」と何度も自問自答してみる。
4. 名前は「効果」と「目的」を説明する。「手段」には言及しない。
5. 名前は検索可能なものにする。極端な例でいうと、英数字1文字の名前は検索した時にコード全体にヒットしてしまうのでNG。

# 以上！
現時点で2章まで。残りはまた読みつつ書いてみたいと思います。
温泉に入ったり、お城を見て回ったり、マッサージしてもらう隙間をぬって何度か読み返しましたが、それなりに頭がスッキリした気分になれました（身体もすっきり）。
全部で7章まであるので、続きはまた後日あげれたらいいなと思い、そろそろ寝たいと思います（2017年12月20日 23:50）。
エントリー駆動開発をやってみた。

初めて、エントリー駆動開発なるものを実施したので、その結果について。

ちなみに作った作品はこちら。
金庫プラス
https://hacklog.jp/works/51818

鍵を開けるには、四則演算に回答しないと開かない金庫。

# とりあえずエントリー

何を作ろうか悩んでいたけど、詳しくはエントリーしてから考える事に。
とりあえず、木を切った状態でHacklogには登録
![かまぼこ板](https://qiita-image-store.s3.amazonaws.com/0/189829/5187eb8d-e688-831c-505a-df07bf934521.jpeg)

少しでも楽に塗装しようとスプレーで着色。
結果として、塗料使った方が速かったと後悔。

ちなみにこの辺りから、ソフト面の開発もスタート。
![塗装](https://qiita-image-store.s3.amazonaws.com/0/189829/20a85976-13c1-c35a-10dc-558091e9bd35.jpeg)

釘打ちのためハンマーが行方不明だったので購入。
お金ないのでダイソー大活躍。
ちなみに木もダイソー
**※一応の鋸はしっかりとしたのを使ってます**
![ハンマー購入](https://qiita-image-store.s3.amazonaws.com/0/189829/bb698c5c-38de-7204-a49f-65ddcdf7dac3.jpeg)


この時点で、MA2017締め切り数日前の状態
中身の仕組みが決まりきらず、これ以上組み立てられない状態
![組み立て中](https://qiita-image-store.s3.amazonaws.com/0/189829/d4972f7f-b2d9-3d94-15dc-018dc52d5cab.jpeg)

締め切り当日
システムとの連動はできていない状態で応募
電気系はほぼ完成だけど、全体の組み込みは終わっておらず
全く動かない状態。。
![とりあえずできた事にしとく](https://qiita-image-store.s3.amazonaws.com/0/189829/4586de4b-7300-56f5-d719-b07035ad84d1.jpeg)

# システム部分の変更
当初は、ESP32のArduinoで進行
色々あり、[Android Things](https://developer.android.com/things/index.html)に変更
結果として、Beacon受信、Firebase連動などが簡単に。
**※Androidの資産が使えるのは便利ですが、β版のためかなり不親切なOSでした。。**


# 届かない部品
金庫のロック機構が決まらず、最後まで苦戦。
サーボから始まり、最終的には、電磁石型ソレノイド決定。
お金がなかったため、AliExpressで購入([電磁石ソレノイド](https://ja.aliexpress.com/item/20-15-suction-2-5KG-25N-mini-electromagnet-solenoid-12v-electromagnet-12-volt-small-electro-magnet/32815809960.html))
モータードライバから、ブレッドボード、ジャパーピンまで購入。

届くのが先か、バトルが先かのチキンレース

**※ちなみに発表２日前にすべての機材は揃いました**


# バトル当日
直前になぜか飲み会が多数入り、前日しか時間が取れない状況に。。
徹夜を決意して、最後の組み立てを実施。
![ねじ止め](https://qiita-image-store.s3.amazonaws.com/0/189829/9dea308f-5380-429e-6c73-c754192cc50d.jpeg)

夜中５時に釘打ちをしたのは良い経験。
![ねじ止め](https://qiita-image-store.s3.amazonaws.com/0/189829/667aa630-3e1b-be14-78d8-aababdd56b8d.jpeg)


Android Thingsがバカなのか、私がバカなのか、明け方６時にOSが飛ぶ。
仮眠時間だと思い、OSを再インストール。。

そんなこんなで朝７時ぐらいには完成
![動いてる](https://qiita-image-store.s3.amazonaws.com/0/189829/487691b8-3012-1a3a-62a9-e684326def67.jpeg)

なんとかデモも行けた。
![動いてる](https://qiita-image-store.s3.amazonaws.com/0/189829/d44612fe-73eb-137e-ffb9-494d8873e787.jpeg)

こんな感じで動作
![動いてる](https://qiita-image-store.s3.amazonaws.com/0/189829/021cec02-b704-d154-8990-1e1c2984c6af.jpeg)

# やって見て
出来上がった時の達成感はすごい。
あと、なんかすごい自信がつく。
でも、作品としては残念な感じ。
実際、発表後、実際に子供に使ってもらうと、感じることがいっぱいあった。
それを踏まえてブラッシュアップするときっともっと良いものになってたと思う。

たぶん次はやらない。
電子マンガサービスについて振り返る


この記事は
「DeNA IPプラットフォーム事業部 Advent Calendar 2017」
21日目のエッセイです。

# はじめに

「[マンガボックス](https://www.mangabox.me/)」というマンガを投稿したり読んだりするアプリ・ウェブサービスがあります。

自分はこのサービスにリリース初年度から3年強、サーバーサイドのエンジニアとして関わってきました。実は2017年12月から異動して最早関わっていないのですが、故に一区切りついた人の目線で唯一の振り返り記事を書いてみます。

紹介できるTwitterアカウントなど持っていませんが、それ自体が自己紹介みたいな感じでお察しの人生を送っています。

# 電子マンガサービスとは何か

「電子書籍」や「電子コミック」という言葉はよく聞くのですが、「電子マンガ」というフレーズはあまり聞かないなと思いつつ、自分はやはり「電子マンガ」のサービスをやっていたなと思っています。自分にとって「書籍」や「コミック」は物理的に製本された数十〜数百ページの紙のまとまりを想起させる言葉であって、それらを電子化したものを扱うサービスであれば「電子書籍（コミック）サービス」と名乗って良いと思いますが、マンガボックスに関していえばこれはやはり明確に「電子マンガサービス」ではないかと思うわけです。

すなわちマンガボックスとは既存の製本化されたコミック（単行本）を電子化したものを販売するストアではありません。正確にいえばストアだけを提供するサービスではありません。そもそも、リリース当初のコンセプトは[週刊漫画誌アプリ](http://www.itmedia.co.jp/news/articles/1312/04/news120.html)なのです。リリース当初の記事を紹介してなんだか「振り返り」っぽいぞ、とテンションが上がってきたのですが、おそらくレッドブル（シュガーフリー）を先ほど飲んだせいです。2013年当時、そして更に近年加速する傾向として、コミックが安定して売れ続けているのに、漫画雑誌が大胆に売れなくなっている状況があります（以下画像参照）。

![スクリーンショット 2017-12-19 23.54.26.png](https://qiita-image-store.s3.amazonaws.com/0/51198/cb1ebc80-396f-7cd9-3c38-f774a71a3209.png)
公益社団法人 全国出版協会「日本の出版統計」
http://www.ajpea.or.jp/statistics/ から引用

※ちなみにこのグラフは紙の売上であって、リンク内に記述のあるように

>電子コミックは3割近い伸びを示しており、紙と電子を合わせたコミック市場全体ではプラスで過去最大の規模になった。

と電子は盛り上がっている状況です。

これは何を示唆するのかというと、人類はコミック（単行本）ではマンガを読み続けている一方で、漫画雑誌は読まなくなったということです。マンガというコンテンツは、漫画雑誌での連載を入り口にして世に発表されることが多いです。一般的には漫画雑誌上でコミックが出るよりも先に読みたい作品があって、その目当ての作品を読みつつ、新連載が始まったマンガ作品もついでに読むか、なんだこれ面白いやんけ、とハマっていって、周囲に広めるなりコミックでも買っちゃうなりして、という暇人のループによって支えられている文化だと思っています。

しかし、スマホの台頭によるカジュアルなエンタメ体験の多様化や通信可能量の増大、日本人の個人主義化やコスパ厨の隆盛などの時流があり、あとおそらくUSJや脱出ゲームイベントなどが好調でやっぱりリアルなエンタメだよなとか言う若者がいたりもして、人類はわざわざ漫画雑誌で「マンガ」という概念に向き合わなくなったのでした。彼らはマンガを捨てつつ、コミックという形で人に聞いたのか書店で見つけたのかはわかりませんが、特定の作品を愛でる方向に進化していったのです。

こうなると、雑誌連載という形で一定の読者数を確保した上で作品として育っていく流れをもったマンガ文化に危機が訪れます。人々は誰かが育てて面白いことが判明した作品や映画化決定した作品しかマンガを読まなくなってしまいます。ただ、コミックの売上が一定あるのはとてもチャンスであって、つまり人類はまだコミックは読むので、売れるコミックになりうる新しいマンガ作品が生まれる、既存の漫画雑誌に替わった土壌を作れば良いのです。

そうした経緯をもって、マンガボックスは「無料で読める漫画雑誌アプリ」として2013年に創刊されました。大多数の人が慣れ親しんできただろうマンガ文化を、いまの時代に合わせて存続させるために、今時のユーザーでも新作（新連載）に触れやすい環境を作り、ひいては次世代のメガヒットマンガを生む。そんな人類の夢を背負ったサービスがマンガボックスだったのです。

そして、そうした新しいマンガ作品が生まれる土壌として、マンガ文化を新規開拓していくサービスのことを、自分はリスペクトと自負をもって「電子マンガサービス」と呼んでいます。序論みたいな話をしましたが、以上とします。ここまで読んだ人は偉いです。良いお年をお迎えください。

さて、明日は永遠の恩人 [@yoichiro0903](https://qiita.com/yoichiro0903) さんがAndroidアプリ開発の話をするみたいです！

# 結論

長々と書きましたが、マンガボックスではサーバーサイドのエンジニアを募集しています。

- アーキテクチャ設計や言語選定から関わるエンジニアリングをしたい方
- マンガに関わる仕事に興味がある方

など、「ちょっと興味ありそう」「もっと色々聞いてみたい」という方も是非[こちら](https://www.wantedly.com/projects/97773)からご応募いただければ幸いです。

マンガにハマった青春時代を思い出しながらも、いつからマンガをちゃんと読まなくなったんだろう、なんて寒空の下で小さく呟いた貴方をお待ちしております。
C/C++: 複数ライブラリ間の間接的な依存を最小限にしよう

## はじめに

いまさらな感はあるし基本的なことではあるのだが、C/C++ でライブラリを作る時の外部(公開)ヘッダ・内部ヘッダや、複数ライブラリ間の依存関係について整理してみる。

## ライブラリの外部(利用者向け)ヘッダと内部ヘッダ

![ExternalAndInternalHeader.png](https://qiita-image-store.s3.amazonaws.com/0/114219/eb753a61-c0c1-c7f7-e58b-a5e01cb539c1.png)


図のように、ライブラリの外部(利用者向け)ヘッダと内部ヘッダの違いを意識して分けたほうがよい。

- 外部ヘッダ: ライブラリ利用者向けの公開ヘッダ
- 内部ヘッダ: 自分のライブラリをコンパイルするときだけに必要なヘッダ

外部ヘッダには利用者が必要な最小限の情報のみが含まれるようにし、実装を隠蔽したほうがよい。
これはなんとなく書いていてもなかなかできず、意識的にやらないと難しい。前方宣言、インターフェイス、pImpl などの設計/実装テクニックを使うことになるだろう。実行効率や設計の複雑度とのトレードオフになることも多いので、ケースバイケースで判断することになる。

ソースツリー上ではフォルダを分けるのが管理しやすい。例えば

- `include/`: 外部ヘッダ
- `src/`: ソースファイル(`*.c`/`*.cc`/`*.cpp`) および内部ヘッダ

といったように。



## 複数ライブラリ間の間接的な依存関係

![ModuleDependency.png](https://qiita-image-store.s3.amazonaws.com/0/114219/5cbc29bd-1603-b314-cb45-4f42fb9217a6.png)

上の図で、

- モジュールAはライブラリB に依存している
- ライブラリBはライブラリCに依存している
- モジュールAはライブラリCに **間接的に** 依存している

という関係である。ここで、3番目の間接的依存関係には2種類ある。

1. ライブラリBの公開ヘッダでライブラリCのヘッダを `#include` しているケース
    - モジュールAはライブラリBのヘッダだけでなく、ライブラリCのヘッダも必要となる
1. していないケース
    - モジュールXはライブラリCのヘッダは必要としない
    - (リンク時にはライブラリCが必要となる)

2 にはいくつかのメリットがある。

- 利用者(A)のコンパイル時に下位ライブラリ(C)のヘッダが不要 (これは上に書いたことそのまま)
- 下位ライブラリ(C)を変更/バージョンアップしてもバイナリ互換が保たれる
    - ライブラリBは再コンパイルする必要があるかもしれないが、Aはその必要はない
    - 大きなプロジェクトの一部であれば、再コンパイルの時間が節約できる
- 下位ライブラリ(C)のコンパイルオプションを、(直接Cを知らない)モジュールAのコンパイル時に引き継がなくてよい。
    - `-DENABLE_XXX=1` のようにコンパイルオプションでヘッダの内容が変わるケースなどは非常に危険だが、ライブラリ内部に隠蔽してしまえば影響範囲が限定できる

2 を実現するためには、先に述べたようにメモリや実行効率の低下を伴うテクニックが必要になることも多いので、必要性に応じてどこまでやるか判断するべき。

### header-only ライブラリ

C++ の場合ヘッダだけで提供されるライブラリというのもあり、それはそれでメリットデメリットがあるのだが、本項では触れない。

## まとめ

C/C++ のライブラリを作るときは、外部(利用者)に公開すべき情報なのか、内部だけで必要な情報なのかを意識して、別のヘッダファイルとして分けよう。
Emacs trampで多段SSHをpemキー使いながら、接続先でsudoする話。

Emacsのtrampでpemキー使って多段SSHし、接続先でsudoします。
サーバ、ローカルPCともLinuxを想定しています。

# trampとは何か

っていう話ははしょります。
ざっくりいうとローカルマシンのEmacsでsshで繋いでリモートファイルをいじる便利なやつです。

# ネットワーク構成
以下のように、踏み台サーバを介した後に対象のアプリサーバにつなぎ、sudoすることを考えます。

![スクリーンショット 2017-12-20 23.02.59.png](https://qiita-image-store.s3.amazonaws.com/0/142812/029687e4-fc10-087a-1c72-586cd1b576f3.png)

問題は

* trampは公開鍵（pemキー）認証に対応していない。
* 対象のサーバではsudo権限がほしいが、接続先で権限を変えることが出来ない。

pemで認証して踏み台しつつ、sudoするってのは、ググってもでなかったのでここで共有します。
接続先でapacheとか編集したいよね..

# sshの設定から。
trampだけで公開鍵認証は使えないので、一旦ssh/configに設定を書き、sshでつながるようにします。
<code>.ssh/config</code>の設定を以下のように行います。

``` config
Host bastion
  HostName 172.0.0.0
  User myuser
  IdentityFile /path/to/key1.pem

Host app
  HostName 192.0.0.0
  User myuser
  IdentityFile /path/to/key2.pem
  ProxyCommand ssh -W %h:%p bastion
```

ProxyCommandにて踏み台を介す設定です。

こうして以下のように疎通をとります。未知の接続先なら一旦接続していたほうが後々便利です。trampで初回接続しようとすると、yes/noきかれるところで止まっていまいます。

``` shell
$ ssh app
ECDSA key fingerprint is ...
Are you sure you want to continue connecting (yes/no)? yes 脚注
[myuser@app ~]$
```

# emacsの設定

以下のように<code>.emacs.d/init.el</code>を設定します。

``` lisp
(require 'tramp)
(setq tramp-default-method "ssh")
```

# trampでの接続

で、以下のように<code>C-x C-f (find-file)</code>してappに接続します。

```
/ssh:app:
or
/app:
```

通常ユーザ（ここではmyuser）でログインできることを確認。

# sudoになる

上記の通り入力すると/home/myuserのdiredが開いているはずなので、その状態で<code>C-x C-f</code>すると以下がミニバッファに出ます。

```
/ssh:app:/home/user/
```

これを以下のように編集

```
/ssh:app|sudo:app:
```

こうするとrootユーザでログインできてます！
確認は<code>C-M-!</code>から<code>whoami</code>を入力するとrootと出ればOK。