OmniAICreator/Qiita-1.07M huggingface dataset:
出してわかったMacAppStoreの閑古鳥状況

# MacAppStoreにアプリを出してみてわかったこと。

といっても、１年以上前にもあるアプリをだしてはいた（その後リジェクトされた）ので、その時の状態が今も、そう、いまだに閑古鳥が鳴いている。

本日（1/25）「TwitSong」のMac版をリリースしました。
https://itunes.apple.com/jp/app/twitsong-weniteiru-quwoshea/id1197743336?mt=12

その日の夜のカテゴリのページには一番先頭に掲載されています。

![appstore.png](https://qiita-image-store.s3.amazonaws.com/0/4664/8419fb14-4969-ae53-ca46-3d19cd3bb4a6.png)

これは単にリリース日順だからなんですが、このリストの先頭にあるアプリに注目すると、リリース日が約１ヶ月前になってる。

![appstore_old.png](https://qiita-image-store.s3.amazonaws.com/0/4664/ab8e7f46-73ba-3d73-35ef-ac725e1936bf.png)

つまり、アプリが絶対的に少ないのです。と、思われる。

ちなみに、ランキングでみるとこういう状況

![ranking.png](https://qiita-image-store.s3.amazonaws.com/0/4664/21b8b90e-a89b-b72c-99fd-930bd69655d3.png)

一番最後の161位に掲載されています。やはり、単にこの数しかないんじゃないかと推測されます。iOSやAndroidとちがってカテゴリによってはアプリの絶対数が少ないから、リリースしたらすぐランキングに載るんじゃないかと。

普通この手のストアではあの手この手で露出されるように頑張るのだけども、なにしろ数が少ないので、リリース日順に表示されるページだと１ヶ月くらいはリストから外れなさそう。　

残念なのは、露出したからといってゴールドラッシュにはならないところかな。ただ、ユーザーが増えれば、そのチャンスはあるよってことかも。

iTunesのレポートが出たらまた報告します。

追記：
iTunesのレポートによると、ダウンロード＝１。つまり、自分で確認用に購入した数字だけが記録されてました。

つまり、

1. 有料アプリをリリース。
2. 自分で購入する。
3. ランキングに載る

というのが成立するようです。いいんだか、わるいんだか。。
次のダウンロードが記録されるのはいつでしょうか。期待して待つことにします。
技術英語 > It's much easier to just add parentheses to group your code [as you intend the calculation to be carried out]:

@ Introducing Python: Modern Computing in Simple Packages by Bill Lubanovic
(No. 661 / 12833)

> It's much easier to just add parentheses to group your code **<font color=red>as you intend the calculation to be carried out</font>**:

```
>>> 2 + (3 * 4)
```

意訳「括弧を使ってコードをグループ化することで、ずっと簡単に意図したとおりの計算が行われるようにできます」

意訳しすぎかもしれない。
集合と位相

東京大学理学部数学科で2016年Aセメスターに開講された科目「集合と位相」のまとめです。
テスト対策で、授業の劣化です。講義ではしっかり証明もされていますし、図も描かれています。

# 濃度と選択公理
（いつか書く）

# 距離空間

- Def. **距離空間**とは、集合$X$と、$X$上の距離の組。
- Def. **点**とは、$X$の元のこと。

## 距離
- Def. $X$上の**距離**$d: X \rightarrow \mathbb R$とは、以下を満たす写像。
 1. $d(x,y) \ge 0$, $d(x,y) = 0 \Leftrightarrow x=y$
 2. $d(x,y) = d(y,x)$
 3. $d(x,y) \le d(x,z) + d(z,y)$


## 点列、極限

- Def. **点列$\\{x_n \\} \subset X$**とは、写像:$\mathbb N \rightarrow X$。
- Def. **$\\{x_n \\}$が$x$に収束 $\Leftrightarrow$ $\lim_{n \rightarrow \infty} x_n = x$**とは、$\forall \epsilon >0 , \exists N \in \mathbb N, (n \le N \Rightarrow d_X(x_n, x) < \epsilon)$。

## 連続写像

$X,Y$を距離空間、$f: X \rightarrow Y$とする。

- Def. $f$が$a$で連続 $\Leftrightarrow$ $\forall \epsilon>0, \exists \delta>0, d_X(x,a)<\delta \Rightarrow d_Y(f(x),f(a)) <\epsilon$
- Def. $f$が連続 $\Leftrightarrow$ $\forall x \in X, fはxで連続$

- Thm. $f: X \rightarrow Y$が$x \in X$で連続 $\Leftrightarrow$ $\lim_{n \rightarrow \infty} x_n = x \Rightarrow \lim_{n \rightarrow \infty} f(x_n) = f(x)$

- Thm. 連続写像は以下を保つ。
 - コンパクト性
 - 点列コンパクト性
 - 連結性
 - 弧状連結性
 - 可分性

## 点列コンパクト

- Def. $\\{x_n\\}$の**部分列**とは、狭義単調増加自然数列$\\{n_k\\}$によって、$\\{x_{n_k}\\}$と表されるもの。
- Def. $X$が**点列コンパクト**であるとは、$\forall \\{x_n\\} \subset X, \exists \\{x_{n_k}\\} \in \\{ \\{x_n\\}の部分列全体 \\}, \\{x_{n_k}\\}が収束$

## 完備

- Def. $\\{x_n\\} \subset X$が**コーシー列**であるとは、$\forall \epsilon >0, \exists N \in \mathbb N, (n,m \ge N \Rightarrow d(x_n, x_m) < \epsilon)$
- Def. $A \subset X$が**閉**であるとは、$\\{x_n\\} \subset A$のとき$\lim_{n \rightarrow \infty} x_n = x \Rightarrow x \in A$
- Def. $X$が**完備**であるとは、$X$のコーシー列が必ず収束し、閉であること。
- Thm. 完備な空間の部分空間は完備

- Def. **バナッハ空間**とは、完備なノルム線形空間のこと。（ノルムの定義は自分で調べて）

## 有界、全有界

- Def. $diam(X) = \sup_{x,x' \in X} d(x,x')$
- Def. $X$が**有界**とは、$diam(X) < \infty$
- Def. $r>0, x \in X$のとき、$B_r(x) = \\{y | d(x,y) < r \\}$
- Def. $X$が**全有界**とは、$\forall r>0, \exists A \subset X, ( |A| < \infty \land X = \bigcup_{a \in A} B_r(a))$

- Thm. 全有界$\Rightarrow$有界
- Thm. 点列コンパクト$\Leftrightarrow$全有界かつ完備

## コンパクト

- Def. $X$の**開被覆**とは、$\\{ O_\lambda \\}_{\lambda \in \Lambda} \subset \\{開集合全体\\}$で$X \subset \bigcup_{\lambda \subset \Lambda} O_\lambda$となるもの。
- Def. $X$が**コンパクト**とは、任意の開被覆$\\{ O_\lambda \\}_{\lambda \in \Lambda$に対し、$|\Lambda_0| < \infty$かつ$\Lambda_0 \subset \Lambda$で$\\{O_\lambda\\}_{\lambda \in \Lambda_0\\}$が開被覆となるようなものが存在すること。
- Thm. (距離空間において)$X$がコンパクト $\Leftrightarrow$ $X$が点列コンパクト
- Note. 位相空間では、コンパクトと点列コンパクトは独立。

## 例など

### ハウスドルフ距離
$X$が閉な距離空間のとき、$X$の閉集合全体に距離を入れられる。

- Def. $Cl(X) = {閉集合全体}$
- Def. $D: Cl(X)^2 \ni (F,G) \mapsto \inf \\{r \in \mathbb R | B_r(F) \subset G \land B_r(G) \subset F\\} \in \mathbb R$
    - Thm. $D$は$Cl(X)$上の距離。
- Thm. $X$が点列コンパクトならば、$Cl(X)$も点列コンパクト。

### 縮小写像の不動点定理

### 稠密、ベールの定理
pipenv を使ってみたのでメモ

## 概要

* https://github.com/kennethreitz/pipenv 
* `It harnesses Pipfile, pip, and virtualenv into one single toolchain.`
    * virtualenv と pipによるパッケージ管理を、**Pipfile** を介して統合的に扱うようにするためのツールのようだ。
* 乗り換え時の作業メモはこちらに書きました
    * http://subarunari.hatenablog.com/entry/2017/12/30/223343

## pipenvで色々やってみる

* 各コマンドを試したのでそのときの備忘録も兼ねてメモ。
* 実行環境は、 macOS Sierra。

### 1.インストールする。
pipenvは、pipでインストールできます。
いつも通り以下のコマンドを実行してインストール。

```console
$ pip install pipenv
```

### 2. とりあえずpipenvを使ってみる

```console
$ mkdir test1      # 検証用ディレクトリの作成
$ cd test1         # 検証用ディレクトリに移動
$ pipenv install   # 仮想環境 と Pipfile を作成
$ ls -a
.		..		.venv		Pipfile		Pipfile.lock
```	

pipenv実行後に、 Pipfile, Pipfile.lock と、仮想環境の設定が格納される .venv が作成されていることがわかります。
後述する方法でパッケージをインストールすると、Pipfileにその情報が書き込まれます。

Pythonのバージョンを切り替える場合は、以下のコマンドを実行する

```console
$ pipenv shell
```

### 3. 作成した環境に対して、パッケージをインストールする。
`pipenv install [package]` で、作成した仮想環境にパッケージをインストールできます。
パッケージのバージョンを指定してもいいし、省略しても構いません。省略した場合は、最新のバージョンが取得されるのは pip と同じです。

```console
$ pipenv install nose==1.3.7  #　仮想環境向けにパッケージをインストール
$ pipenv shell
$ (test1)(test1) python
>>> import nose
>>> exit()
```
```console
$ python
>>> import nose     # 仮想環境にのみインストールされていることを確認してみる
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named nose
>>> exit()
$ (test1)(test1) exit  # 仮想環境から抜ける
```
```console
$cat Pipfile        # Pipfileを確認してみる
[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true

[packages]          # new!!!
nose = "==1.3.7"
```

### 4. 定義済みのPipfileを用いて、仮想環境の構築とパッケージのインストールを試す

```console
$ cd .. && mkdir test2 && cd test2  # 検証用にディレクトリ作成&移動
$ ls -a
.	.. 
```
```console
$ pipenv run python      # 仮想環境に入ってpythonを実行するのと同義
>>> import nose
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named nose
>>> exit()

$ cp ../test1/Pipfile .  # 定義済みPipfileを持ってくる
$ pipenv install         # 仮想環境の作成とパッケージのインストールを実施
$ ls -a
.		..		.venv		Pipfile		Pipfile.lock
$ pipenv run python
>>> import nose
>>> exit()
```

##　備考：pipenv をバージョン指定で実行する
### バージョンを詳細に指定する
Pythonのバージョンを直接指定できるようになりました。何も指定しなければStableな最新版が入るようです。

```console
$ pipenv --python <Pythonのバージョン>
```

3.6.2で入れたい場合は、以下のように記述できます。`3.6`といった指定もできます。その場合、 `x.y.z` の部分は最新が取られるようになります。

```console
$ pipenv --python 3.6.2
```

### 2系か3系かを指定する
下記コマンドでそれぞれバージョンを指定して実行できます。とりあえず2系・3系の環境を作りたい場合は、ざっくりこの指定で良いのではないでしょうか。

```console
$ pipenv --two # 2系の環境を作成する
$ pipenv --three # 3系の環境を作成する
```

## `The 'python3' command exists in these Python versions` が出た場合
リリース当時に遭遇しました。pyenvで、2系・3系の複数バージョンをインストールしていたため、下記のようなメッセージが表示され、処理が中断されたことがありました。3系のバージョンが複数あって、対象を1つに絞れないという情報を提供してくれています。2系でも同様。

```console
$ pipenv --three
Creating a virtualenv for this project...
pyenv: python3: command not found
The `python3' command exists in these Python versions:
  3.4.2
  3.4.3
```

この場合は、`pyenv local [version]` などでバージョンを指定することでとりあえず解決できるが、果たしてこれで良いのだろうか・・・。
`pyenv install` で初期化した場合は、 system のバージョン(pyenvとは無関係)を参照しているようで、その場合は当然ながら上記エラーは発生しません。
「次世代FWについて」(社内LT用)

![f_f_business_62_s512_f_business_62_1bg.png](https://qiita-image-store.s3.amazonaws.com/0/160535/b4dbdb00-7000-b4f0-a05b-1e2b29880f86.png)
#概要
- ファイアーウォール機器を扱うベンダーが各々謳っている「次世代ファイアウォールとは」？
- いまいち定義が明確ではないようなので、自分なりにまとめてみます。
- 以下、次世代ファイアウォール＝NGFW(Next Generation Firewall)

#FWとは？
- FW=「信頼できるネットワーク」と「信頼できないネットワーク」
2つのネットワーク間の通信を制御するための機器やソフトウェア。

#従来FWの基本的動作
- IPアドレス(L3)、ポート番号(L4)で通信を制御。　
- ⇒例)192.168.1.0/24のセグメントのホストから192.168.2.0/24へのFTP(ポート20/21)禁止
- ACLとの大きな違いはステートフルインスペクション機能

次に簡単にFWの歴史をまとめます。

#FWの歴史（ざっくり）

- 1980年代：ルータのACLによるパケットフィルタリングが確立されていたが、「インターネットの普及」によりセキュリティの脅威が増加。
- 1990年代前半：サーバにソフトウェアをインストールするソフトウェア型のFWが誕生
- 1990年代後半：専用ハードウェアを使用したハードウェア型のFWが登場。これ以降の主流に。
- 2000年代：統合型FWであるUTM登場。（アンチウイルス、URLフィルタリング機能等。）
- 2007年：アプリケーションを可視化/制御する新技術を搭載したNGFWの登場。

とルータの機能であるパケットフィルタリングから始まり、インターネットの普及が進むにつれ多種多様なセキュリティ脅威から進化を遂げてきました。

#では本題に
- NGFW＝アプリケーションコントロール(L7)の機能を実装したFW。
またの名を「L7FW」。

- 従来型FWは上記の通り、ポート、IPアドレス、セキュリティを確保。
しかしアプリケーションの種類までは判別できない（例.Skype,facebook,Dropboxなど)
つまりコンテンツレイヤでの制御、把握はできない。
⇒アプリケーションを介したサイバー攻撃や情報漏えいの危険性

- NGFWは、各アプリケーション固有のトラフィック情報などを解析する機能によりトラフィック内のアプリケーションを識別し可視化、制御することが可能。
例えば、WEB閲覧を許可＝80番ポートを許可した状態で同じポートを利用するアプリケーションを識別し制御することが可能。
⇒リスクの高いアプリケーションやWebサイトとの通信を制御できる

- 各ベンダーが保持するシグネチャ（=アプリケーション識別のためのデータベース）でアプリケーション識別

- サンドボックス機能やディレクトリサービスとの連携によるユーザの識別
なども統合している機器などもある。

#UTMとは何が違うのか？

補足ですがNGFWとUTMの違いについては以下。

- UTM（Unified Threat Management）
IPS、アンチウィルス（AV）、URL フィルタリング、およびアンチスパム等の機能を備えたファイアウォール

- NGFW(Next Generation Firewall）
アプリケーションコントロールの機能を備えたファイアウォール

しかし近年では両方のソリューションがほぼ同じ中核機能を提供するようになったので、NGFW≒UTMと考えて良い。
というよりもともと明確な定義で分けられたものではないらしいので、
ベンダーによっての呼び方の違いくらいの感じ。

#まとめ
わかりやすく纏めると、

- NGFW=「従来のFWのもつ機能に加え、アプリケーションコントロール機能を備え、また様々なセキュリティ対策を１台で統合的に実現できるアプライアンスである。」

以上、とても簡単にまとめました。
Qiitaデビューの手始めにMarkdownの練習をする

ご挨拶
この度はてなブログでの執筆をしていくこととなりました。
よろしくお願い致します。

Qiitaと併用していこうと思ってまして、
はてなの方には主にポエムとか雑感を、
Qiitaにはプログラムとか書いていこうと思っています。
ちゃんと続くかわかりませんが、あまり気負わずやっていきたいと思います。

手始めに、最初の投稿がてら、Markdownの練習をしていきたいと思います。
はてなブログでもQiitaでも、さらに職場ではConfluenceやBitbucketを使っているのですが、
いずれもMarkdown記法で書くことができるようになっています。
それぞれで若干使える文法に差があるものの、
ある程度統一的な文法で書くことができるので、
覚えたいと思ってます。
はてなブログと比較しながら書いていこうと思います。
[はてなブログ版はこちら](http://sunadiary.hatenablog.com/entry/2017/01/26/015910)

## 見出しを出す
```
# をつけると見出しになる
```

# 見出し１
## 見出し２
### 見出し３
#### 見出し４
##### 見出し５
###### 見出し６
####### 見出し７（これは出ない。６まで設定可能）

## リンクをつける
```
[表示文字](URL)でリンクになる
```
[Yahoo Japan](http://www.yahoo.co.jp/)

## 段落や改行をつける
単純に改行すると
改行になる（brタグ）（Qiitaは改行されない）

末尾に半角スペースを2つつけると  
さらに1行改行になる（1度だけ）

## 引用文
```
> をつけると引用文になる
```
> こんな感じ
> はてなブログと結構見た目に差がある

## 強調
```
*文字列*もしくは_文字列_
**2段階**
***3段階***
~~打消し線~~
```
*一段階*
**二段階**
___三段階___
~~打消し線~~

## コード挿入
```
`インラインコード`  
``pre記法``
```コード記法```
```

`<strong>インラインコード</strong>`

``<strong>pre記法。HTMLタグがそのまま書ける</strong>``

```java
public class Test {
    private String message = "初めのバッククォートの後ろにPG言語名を書くと、シンタックスハイライトを入れてくれる";
}
```
基本はコード記法（バッククォート3つ）で良さげでしょうか。
Qiitaの場合前後に改行が必要。

## リスト
「*」「+」「-」を使用するとリストになる

```
* テスト
    * テスト
        + テスト
            - test
```

* テスト
    - テスト
        + テスト
            - test

記号の前のタブの数でインデントできる。
はてなブログはタブでなくスペースなので、書き方が少し違う。
あとQiitaの場合コード挿入と同様前後に改行が必要。

```
1. 「数字ドット」
1. を入れると
1. 数字のリストになる
```

1. 「数字ドット」
1. を入れると
1. 数字のリストになる
    1. インデントも可能（また1からの採番になる。はてなと表示が異なる）

## チェックボックス
```
- [ ]でチェックボックスが出ます
```
- [ ] チェックボックス

前後にspaceが必要。はてなではできない？

## テーブル記法
```
| 左寄せ | 右寄せ | 中央寄せ |
|:------|-------:|:-------:|
| 1-1   |     1-2|   1-3   |
| 2-1   |     2-2|   2-3   |
```
| 左寄せ | 右寄せ | 中央寄せ |
|:------|-------:|:-------:|
| 1-1   |     1-2|   1-3   |
| 2-1   |     2-2|   2-3   |
  
## 水平線
```
---や***で水平線になる
```
---
***

## ひとまずまとめ
他にもいろいろあるのですが、
とりあえずよく使いそうなのをピックアップして
試してみました。

Qiitaは一部が改行やスペースを空けなければ反映されなかったりするところで
ちょいちょいひっかかりそうですが、そのうち慣れるでしょうか。
SlackのメッセージをHUBOT+AquestalkPiを用いてRaspberryPiにしゃべらせる

# SlackのメッセージをHUBOT+AquestalkPiを用いてRaspberryPiにしゃべらせる
## 1. はじめに
どうもISAOXです。
以下の投稿記事でSlack上でBOTに命令を出せば遠隔のRaspberryPi(以下RPi)のスクリプトを実行できるようになりました。
この記事の環境もこれをベースにしてます。参考下さい。

* [GitHub + Slack + RaspberryPiを用いたHUBOT開発環境の構築](http://qiita.com/IsaoNakamura/items/c6be85cf99d93c8d50a2)

なので、今回はこの遠隔のRPiに喋らせてみようと思います。
しゃべらせることができれば、リポジトリの更新通知などを音声で知らせたり、自宅警備員として侵入者に警告を発したりなど用途は広がりそうです。

## 2. 前提条件
この記事の前提条件は以下です。

* インターネットに接続したRaspberryPi(Raspbian)がある。
* RPi上でHUBOTを起動できる環境にしている
* Slackを利用している + Slack上でHUBOT用のBOTを追加している。

## 3. RPiにしゃべらせる道具の準備
株式会社アクエストさんの[AquesTalk Pi](http://www.a-quest.com/products/aquestalkpi.html)がすごく簡単にRPiを日本語でしゃべらせてくれます。
漢字もいけます！すごい！
インストール方法は株式会社アクエストさんの[N.Yamazaki's blog](http://blog-yama.a-quest.com/?eid=970157)を参考にしました。
AquesTalkPiをインストールしたRPiで以下のように命令すればしゃべります。
`./AquesTalkPi "私はラズパイちゃんです。よろしく。" | aplay`

なので、AquesTalkPiを実行するShellスクリプトを用意してRPi上に配置します。
しゃべらせる文字をこのShellスクリプトに引数で渡す仕様です。

```talkpi.sh
#!/bin/sh
cd /home/pi/aquestalkpi
./AquesTalkPi $@ | aplay
cd /home/pi
```

## 4. RPi上のHUBOTがShellスクリプトを呼ぶ準備
RPi上のHUBOTが読み込むcoffeeスクリプトに『talkpi』という文字列が来たら上記Shellスクリプトを呼び出す命令を追記します。
追記したらRPiを再起動するなどしてHUBOTが最新のcoffeeスクリプトを読み込んでおくようにしておきましょう。

```test.coffee
  robot.respond /talkpi (.*)/i, (msg) ->
    arg = msg.match[1]
    @exec = require('child_process').exec
    command = "sudo -u pi sh /home/pi/GitHub/StudyRPi/Hubot/iotbot/my_exec/talkpi.sh #{arg}"
    msg.send "Command: #{command}"
    @exec command, (error, stdout, stderr) ->
      msg.send error if error?
      msg.send stdout if stdout?
      msg.send stderr if stderr?
```
## 5. Slack上のBOTにしゃべってもらうように命令する
Slack上でBOTに以下のようにしてRPiにしゃべってもらうように命令します。
するとBOTが反応しRPiのShellスクリプトを実行してしゃべってくれました！
![Picture](https://github.com/IsaoNakamura/StudyRPi/blob/master/Hubot/image/sc_talkpi_hello.png?raw=true)
※上のスクリーンショットはSlack上の『DIRECT MESSAGES』上で入力しているので頭に指定するBOT名は省略してます。

## 6. 最後に
チャットツールであるSlackはテキストベースで会話をします。
このテキストを音声化できればコミュニケーションの幅が広がると考えてます。
音声化できることでどういう用途、UXができるか皆さんも考えてみてください。
コアダンプファイルの出力先ディレクトリとファイル名の変更

[したいこと]
　プロセスのコアダンプファイルの出力先ディレクトリとファイル名を変更したい

# 一時的に変更する場合(OS再起動で変更は破棄される)
以下のファイルにコアダンプファイルの出力先とファイル名を設定する
[設定ファイル]
　/proc/sys/kernel/core_pattern
[設定例]
　$ echo "/hoge/core_%e_%p" > /proc/sys/kernel/core_pattern
[参考リンク]
　[Man Page of CORE](https://linuxjm.osdn.jp/html/LDP_man-pages/man5/core.5.html)

# 永続的な変更をする場合(OS再起動しても有効)
以下のファイルにコアダンプファイルの出力先とファイル名を設定する
[設定ファイル]
　/etc/sysctl.conf
[設定例]
　以下の行を追加
　kernel.core_pattern=/hoge/core_%e_%p
[設定を有効にするには]
　以下のいずれかを実行する
　1. OS再起動
　2. # /sbin/sysctl -p

- [ ] ただし、RHEL6の場合は、自動バグ報告ツールがkernel.core_patternを勝手に書き換えるため、/etc/abrt/abrt.confファイルのDumpLocationパラメタを設定する

[参考リンク]
　[sysctl コマンドの使用](https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/s1-proc-sysctl.html)
　[RHEL6で、起動時に kernel.core_pattern パラメーターが上書きされます](https://access.redhat.com/ja/node/453983)
　[自動バグ報告ツール (ABRT)](https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/ch-abrt.html)
Raspberry Piの時刻を手動設定すると過去に戻れない

# 時刻が戻らない
Raspbianで、dateで未来の時刻を設定すると、rebootしてもその時刻が記憶されるのに、過去を設定すると、前に設定した未来に戻ってしまう、と聞いた。
何でそんなことを、というのは置いておいて、やってみたら、確かにそうなる。
面白いじゃないか。

# RTCが無い
そもそも、Raspberry Piには、RTCが無い。なのに何故時刻が記憶されるのか?
ググった結果、[fake-hwclock](https://git.einval.com/cgi-bin/gitweb.cgi?p=fake-hwclock.git;a=summary)にたどり着いた。システムの起動終了時に、時刻をファイルへ読み書きするらしい。debianのパッケージは[ここ](https://packages.debian.org/jessie/fake-hwclock)。

# fake-hwckockのforceオプション
fake-hwclock(8)によると、forceオプションを付けないと、過去には戻れないらしい。

```
COMMANDS
       save   Save the time to the file. If force is specified fake-hwclock will move the saved clock either backwards or forwards. Otherwise it will only move it forwards.
       load   Load  the  time  from  the file. If force is specified fake-hwclock will move the clock either backwards or forwards. Otherwise it will only move it forwards.
```

このmanは親切で、設定ファイル`/etc/default/fake-hwclock`の存在を知り、中身を見る。

```bash:/etc/default/fake-hwclock
# Uncomment to set clock even if saved value appears to be in the past
#FORCE=force
```

Uncommentすれば、forceになりそうだ。

```bash:/etc/default/fake-hwclock
# Uncomment to set clock even if saved value appears to be in the past
FORCE=force
```

# 実験
`date`で過去を設定し、fake-hwclock再起動。

```shell-session
root@raspberrypi:/home/pi# cat /etc/fake-hwclock.data
2017-01-25 23:42:01
root@raspberrypi:/home/pi# date 012523422015
Sun 25 Jan 23:42:00 UTC 2015
root@raspberrypi:/home/pi# systemctl restart fake-hwclock
root@raspberrypi:/home/pi# cat /etc/fake-hwclock.data
2017-01-25 23:42:01
```

`/etc/fake-hwclock.data`を見ても、過去が保存された気配はない。
そこで、`/lib/systemd/system/fake-hwclock.service`を確認する。

```bash:/lib/systemd/system/fake-hwclock.service
ExecStart=/sbin/fake-hwclock load $FORCE
ExecStop=/sbin/fake-hwclock save
```

save側に$FORCEが無い。過去は記憶されなさそうだ。
そこで、saveにも$FORCEを付けてしまう。

```bash:/lib/systemd/system/fake-hwclock.service
ExecStart=/sbin/fake-hwclock load $FORCE
ExecStop=/sbin/fake-hwclock save $FORCE
```

# 再実験
```shell-session
root@raspberrypi:/home/pi# systemctl daemon-reload
root@raspberrypi:/home/pi# date 012523422015
Sun 25 Jan 23:42:00 UTC 2015
root@raspberrypi:/home/pi# systemctl restart fake-hwclock
root@raspberrypi:/home/pi# cat /etc/fake-hwclock.data
2015-01-25 23:42:06
```

おお、過去が保存された。

# saveに$FORCEが無い理由
[本家](https://git.einval.com/cgi-bin/gitweb.cgi?p=fake-hwclock.git;a=summary)の歴史を見ると、途中で[saveにforceを追加](https://git.einval.com/cgi-bin/gitweb.cgi?p=fake-hwclock.git;a=commitdiff;h=53a5cc0b3e83a661e73258a5191403041d4118c9;hp=5640540b0050d80e9e04997eeeb63cb34bff94f5)した模様。
その時に、[`fake-hwclock.service`](https://git.einval.com/cgi-bin/gitweb.cgi?p=fake-hwclock.git;a=blob;f=debian/fake-hwclock.service;h=6e804c058009f458d0f4401010a198bb4eb57a25;hb=HEAD)のsaveに追加し忘れた?
まあそもそも`date`で設定した過去の時刻を保存するという機能は、仕様外というだけかもしれない。

# いまさら確認環境
- 2017-01-11-raspbian-jessie-lite
- Raspberry Pi 1 Model A+
- NTPサーバーにアクセスできないローカルネットワーク

# 宿題
本題とずれるが、`fake-hwclock.service`編集後、`systemctl daemon-reload`した後に、`systemctl stop fake-hwclock`としたが、どうも`fake-hwclock`が呼ばれない模様。restartだとうまく行く。
systemdの仕様と思われるが、何でだろう。`Type=oneshot`かつ`RemainAfterExit=yes`との関係は? などの調査。
Electronで文字が二重になるバグの解決方法

しばらく解決できなくてモヤモヤしていたがようやく原因が分かった。

## 症状
Electronアプリで文字が二重なる。スクロールすると殘像が残ってエディターアプリなどでは致命的な症状がでていた。`bold`じゃないのに太字になっているように見えるが、実際は文字が二重にかさなっているという状態。

![sam.jpg](https://qiita-image-store.s3.amazonaws.com/0/144150/e03c77a8-0d2e-e6bc-00dd-d115069aacd1.jpeg)
こういうやつ。

## 解決策
bodyやhtmlの背景に`background: #fff;`を指定してやれば解決！
あっけない結末であった。
![sa.jpg](https://qiita-image-store.s3.amazonaws.com/0/144150/61750296-bb2b-c788-3181-8433134988ef.jpeg)


## 原因
Chromiumのレンダリングに関するバグ。Viewを描画するときに元の背景色が上書きされず、殘像が残ってしまうということらしい。つまり、背景色を設定していないときに起こりうるバグということだろう。
デフォルトの背景色を指定してやることで、描画される毎に背景色がレンダリングされ、文字の殘像が塗り替えられるイメージ。もちろん`#fff`じゃなくても好きな色でOKかと思います！
RxSwiftをSwiftPMからインストールして使ってみる

#RxSwiftをSwiftPMからインストールして使ってみる

## はじめに
RxSwiftをSwiftPMでインストールし、Xcodeプロジェクトで使おうと思ったのですが、方法がわからず悪戦苦闘した結果なんとか実行できるようになったので、備忘録的に記事を書こうと思いました。
(正しい使い方ではないかもしれません...というか、全然自信ないです。詳しい人に教えてもらいたい)

## 環境
Mac OS X El Capitan 10.11.6
Xcode 8.2.1
Swift 3.0.2

## プロジェクトの作成
Xcode -> Create a new Xcode project -> iOS -> Single View Application
から新規作成
プロジェクト名は「RxSample」としました。

## SwiftPMのセットアップ
```bash
$ cd RxSample #作成したプロジェクトのルートフォルダに移動
$ ls
>> RxSample RxSample.xcodeproj RxSampleTests
$ touch Package.swift
```

## パッケージの追加
```swift:Package.swift
import PackageDescription
let package = Package(
    name: "RxSample",
    dependencies: [
        .Package(url: "https://github.com/ReactiveX/RxSwift.git", majorVersion: 3)
    ]
)
```

## パッケージのFetch
```swift
swift package fetch
```

## フレームワークの追加
Linked Frameworks and Libraries -> Add Other から
`./Packages/RxSwift-3.x/Rx.xcodeproj`を追加。

<img width="261" alt="スクリーンショット 2017-01-25 23.24.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/84888/9db8fc89-5b6d-28e2-f64b-3d485e7deda6.png">

FrameworksにRx.xcodeprojが追加された後、

もう一度Linked Frameworks and Librariesを確認すると

<img width="538" alt="スクリーンショット 2017-01-25 23.25.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/84888/734a1f72-0acd-c4b9-ec42-72eafc459409.png">

RxSwiftのターゲットが選択できるようになっているので、必要なものをAdd。

## モジュールのインポート
<img width="539" alt="スクリーンショット 2017-01-25 23.36.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/84888/6f8449d9-ffef-7ce0-c0c5-1d1a1f29b4fe.png">

`import RxSwift` でインポートできるようになっていると思います。
もし、表示されない場合、Xcode -> Product -> Build から一度ビルドをすることで
認識されるようになります。

## あとがき
大人しくCocoaPodsやCarthageを使っていればすんなり使えてたと思います...。
SwiftPMは本来こういう使い方をしないんでしょうか？勉強不足です...。
【メモ】クローラー拒否

今日のメモ

■検索エンジンへの指示

`<meta name="robots" content="noindex">`　　インデックスさせない
`<meta name="robots" content="nofollow">`　ページ内にあるリンク先へアクセスさせない
`<meta name="robots" content="noarchive">`　キャッシュを残さない
`<meta name="robots" content="noodp">`　Dmozのサイトで文章の引用を禁止
`<meta name="robots" content="nodir">` ヤフーカテゴリーで文章の引用を禁止

参考：
https://digital-marketing.jp/seo/index-control-meta-robots/
https://www.suzukikenichi.com/blog/how-to-use-meta-noindex-nofollow-noarchive/
mouseMovedをキャッチする方法


デフォルトではmouseMovedをオーバライドしてもメッセージを受け取ってくれない。
(それなりの理由はあるのだろうが、ややこしい事を・・・と思わなくもない）

やり方としてはObjective-CではNSWindowで以下のようなやり方があるらしい。（試してない）

```Objective-C
-(void)awakeFromNib
{
[self setAcceptsMouseMovedEvents:YES];
[self makeFirstResponder:self];
}

```

SwiftになってからはNSViewやNSImageViewでNSTrackingAreaの初期化時に指定するオプションでメッセージを受け取るようにするのがいいみたいです。

```

class customeImageView: NSImageView {
  
    override func awakeFromNib() {
        super.awakeFromNib()
        configure()
    }
    
    
    func configure() {
        let options:NSTrackingAreaOptions = [
            .mouseMoved,
            .cursorUpdate,
            .activeAlways,
            .enabledDuringMouseDrag
        ]
        let trackingArea = NSTrackingArea(rect: bounds, options: options, owner: self, userInfo: nil)
        addTrackingArea(trackingArea)
    }

    override func mouseDown(with event: NSEvent) {
        NSLog("mouseDown")
        
    }
    
    override func mouseDragged(with event: NSEvent) {
        NSLog("mouseDragged")
    }
    
    override func mouseMoved(with event: NSEvent) {
        NSLog("mouseMoved")
    }
   
}

```

#### 参考サイト

[NSTrackingAreaの初期化](http://qiita.com/toshi0383/items/90219268f4e263e92051)
LINE LIVEで棒読み機能などを追加する手順


## まえがき
これは技術者 **以外** の方が見るように書いてます。
（もしかしたら最後ら辺に技術面のことを書くかもしれませんが、あんまり書く気ないかも。）

最近、私が適当に作ったLINE LIVE用の棒読み機能について問い合わせがある為、ここにまとめておきます。
すぐ追加したい方は **機能追加方法** まですっ飛ばして読んでください。

また、これはある配信者の為に作ったのでこっちの都合でちょいちょい機能追加などすると思います。
それをご理解の上使用してください。

また、この機能は私が管理しているので私が悪いことしなければ健全な状態で使用できると思います。
ソースコードは誰でも見れる所にあるので気になる方はご覧ください。

バグがありましたらお手数ですが[こちらまで](https://twitter.com/ozepon)報告お願い致します。

## 作ったもの
ブックマークを押したらPC版のLINE LIVEに機能追加をする(bookmarklet)

#### 見た目before
![スクリーンショット 2017-01-25 22.50.10.png](https://qiita-image-store.s3.amazonaws.com/0/24013/9b6b32cd-2373-87e1-1991-5524396cb3ed.png "スクリーンショット 2017-01-25 22.50.10.png")

#### 見た目after
![スクリーンショット 2017-01-25 22.50.29.png](https://qiita-image-store.s3.amazonaws.com/0/24013/433ab6d9-dc1b-bc7e-c87a-41a042c18ee9.png "スクリーンショット 2017-01-25 22.50.29.png")

## 追加機能
1. コメントの棒読み
- 動画の音声ミュート
- 配信時間をコメントの上に設置
- 縦長の動画を横にし、いい感じにサイズ変更
- バグ報告ように私のtwitterリンクを追加


## 動作環境
- OS: mac, windows, linux系(試してないけどイケるんじゃない？）
- ブラウザ: chrome
- この他の環境は試していない（IEは動かない報告あり)

※ ザックリ説明：chromeとはブラウザと呼ばれるインターネットをするやつです
持ってない方は[こちら](https://www.google.co.jp/chrome/browser/desktop/)からダウンロードしてインストールして下さい。

## 機能追加方法

#### 1. スマホのアプリで自分の過去配信を見て、自分をフォローする(PC版のLINE LIVEに検索機能がない為)※配信した事ない人は必要ないと思うのでここで離脱

分かりにくいけど自分の配信を見てフォローボタンを押してます
![linelive_folor.gif](https://qiita-image-store.s3.amazonaws.com/0/24013/862db2b4-b62e-44a8-9fae-f1c97cb0cc99.gif "linelive_folor.gif")

#### 2. chromeで[LINE LIVE](https://live.line.me/)を開いてログイン
![linelive_login.gif](https://qiita-image-store.s3.amazonaws.com/0/24013/f6306f30-7aca-f6fc-e44a-9cd305c65a99.gif "linelive_login.gif")

#### 3. なんでもいいのだが、この画面をお気に入りに追加する（☆マークを押す）
![linelive_bookmark.gif](https://qiita-image-store.s3.amazonaws.com/0/24013/d4e4ce64-8725-3a52-36b4-6fb7f697318a.gif "linelive_bookmark.gif")

#### 4. 追加したお気に入りを編集。URLに以下の一文をコピペし保存する(適当に名前を変えてもよい)
	
```コピペするURL
javascript:(function()%7Bvar%20time%20=%20new%20Date().getTime();var%20s%20=%20document.createElement(%22script%22);s.src%20=%20%22https://cdn.rawgit.com/ozepon/cyocon_bookmarklet/master/js/main.js?v=%22%20+%20time;s.charset=%22UTF-8%22;document.body.appendChild(s);%7D)();
``` 
![linelive_bookmark_change.gif](https://qiita-image-store.s3.amazonaws.com/0/24013/57636e87-ea9d-8d1c-d1c1-a28f8ee3e06d.gif "linelive_bookmark_change.gif")


#### 5. 以上で終了。あとは配信を見てる時に編集したお気に入りをクリックすると機能が追加される。機能を取り消したい時はブラウザをリロードすれば消えます。
![linelive_on.gif](https://qiita-image-store.s3.amazonaws.com/0/24013/8bba82ec-4645-3463-83ae-910b69302ace.gif "linelive_on.gif")


## 動かない場合

ラインライブの画面を開いていないと棒読みは読み上げません。ラインライブ以外のタブをを開いてる場合はラインライブのタブに切り替えて下さい。

それでも動かない場合は、chromeを一旦落として再度トライして下さい。

何回も押すとバグるかもね

## 技術的な話

ただのbookmarkletです。
jsはにわかレベルなので、適当に書いております。

気になる方は[Github](https://github.com/ozepon/cyocon_bookmarklet)からご確認ください。（汚いよ❤️）
画像をダブルタップとピンチイン・ピンチアウトで拡大・縮小する Swift3編

ちょっと必要に迫られて[^1]、常に同じ画像を起動と同時に表示して、ピンチで拡大／縮小、ダブルタップで拡大、というアプリを、一晩で作ることになりました。
調べてみると、[まさにうってつけのページがありました](http://qiita.com/hanoopy/items/7a2c582cd9758e7a3076)が、正直Swift3ではまったく動きませんでした。ので、ちょっと手直しをさせていただきましたので、貼っておきます。

### コード

```swift:ViewController.swift
class ViewController: UIViewController, UIScrollViewDelegate {

    @IBOutlet var myImageView: UIImageView!
    @IBOutlet var myScrollView: UIScrollView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.myScrollView.delegate = self
        
        let doubleTapGesture = UITapGestureRecognizer(target: self, action:#selector(self.doubleTap))
        doubleTapGesture.numberOfTapsRequired = 2
        self.myImageView.addGestureRecognizer(doubleTapGesture)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        //print("pinch")
        return self.myImageView
    }
    
    func doubleTap(gesture: UITapGestureRecognizer) -> Void {
        //print(self.myScrollView.zoomScale)
        if (self.myScrollView.zoomScale < self.myScrollView.maximumZoomScale) {
            let newScale = self.myScrollView.zoomScale * 3
            let zoomRect = self.zoomRectForScale(scale: newScale, center: gesture.location(in: gesture.view))
            self.myScrollView.zoom(to: zoomRect, animated: true)
        } else {
            self.myScrollView.setZoomScale(1.0, animated: true)
        }
    }

    func zoomRectForScale(scale:CGFloat, center: CGPoint) -> CGRect{
        let size = CGSize(
            width: self.myScrollView.frame.size.width / scale,
            height: self.myScrollView.frame.size.height / scale
        )
        return CGRect(
            origin: CGPoint(
                x: center.x - size.width / 2.0,
                y: center.y - size.height / 2.0
            ),
            size: size
        )
    }
}
```

### 変更点

* `UIScrollView`や`UIImageView`をStoryBoardからロードするので、そちらで設定できる項目は極力そちらにまかせます
* `var`よりも`let`です
* 型推論を活用します
* 最初の引数にもラベルが必要になっています
* selectorの指定方法が`#selector()`に変わっています

### 脚注

[^1]: [島内に岡山県-香川県の県境がある石島に行く](http://feelfine.blog.izumichan.com/article.php?id=52765)ことになり、[実際に県境マニアのみなさんが上陸した際の地図画像](http://uub.jp/frm/member/off6/ishima.html)を、道なき道を進みつつ随時確認するために必要になりました。iPhone付属の写真アプリでは、アプリプロセスが終了したらまた画像を選び直さなければならなくなってしまい、それは獣道を進む最中の大きなコストです。ので、タスクリストからもアプリアイコンタップからもイッパツで画像表示ができるものを欲したわけです。
Rails で Pry を使う


# 概要

- pry-rails と pry-bybug をインストールすると...
	- Rails console で Pry が使える
	- `binding.pry` で処理を止めてステップ実行ができるようになる。
- 今回は pry-doc も入れてみた

# 環境

- Rails 4.2.2

# 方法

`Gemfile` に次の Gem を追加:

```ruby:Gemfile
group :development, :test do
  gem 'pry-rails'
  gem 'pry-byebug'
  gem 'pry-doc'
end
```

そして bundle install して Gem をインストール:

```bash:
$ bundle install
```

これで、以下のことができるようになる。

# 各 Gem の概説

## pry-rails

pry-rails を入れると...

- Rails console で Pry が起動するようになる
	- pry-rails を入れるまでは irb が起動する
- `show-routes` などのコマンドが Rails console で使えるようになる
	- Rails console で `help` と打つと、使えるコマンドがわかる
- `binding.pry` をソースコード中に挟むとそこがブレークポイントとなり、そこで処理を止めてデバッグできるようになる
	- pry-rails だけではステップ実行はできない

## pry-byebug

pry-byebug を入れると...

- `binding.pry` で止めたところからステップ実行ができる
	- 例えば `next` コマンドで一行ずつ実行できる
	- こちらも詳細は Rails console の `help` などを参照

## pry-doc

pry-doc を入れると...

- `show-method` コマンドで C で書かれたコードやドキュメントも出力できるようになる
	- `show-method` は Pry のコマンドで通常は Ruby で書かれたコードやドキュメントのみ出力できる

# 参考

パーフェクト Ruby on Rails
新卒エンジニアが上司からの機能変更に揉まれまくって気が付いた事

#新卒エンジニアが上司からの機能変更に揉まれまくって気が付いた事

僕は現在大手人材会社で新卒エンジニアとして働いている。WEBエンジニアとして、フロントエンド、サーバーサイドの設計から実装、テストまで担当している。といっても、作ってるシステム自体はSI案件でなく、自社開発の中規模アプリケーションだ。だから、新卒でも(文系出身)でも担当範囲が広い、と考えている。

チームは10人程度で、WebとiOSに分かれている。僕はWEB側で4ヶ月経験を積ませて頂いた。jQueryでのDOM操作も慣れてきたし、コードも汎用関数に纏める事で軽量化を図ることが出来るようになってきた。スコープも意識しているし、設計に関しては機能からDB設計を行えるようになった。高度なクエリはまだ書く事は出来ないが、数十〜百行程度のクエリは普段書いている。インフラ系の知識に関しても駆け出しレベルではあるが蓄積されてきた。自分で開発環境も整える事が出来る。

そんな僕が、最近学んだ経験をここで話すことにする。
現在僕は少し複雑なロジックの機能を担当している。ちなみに、それだけに2ヶ月もかかっている。
まず、他社の同等機能を洗い出して必要な機能を定義する。そして、それに必要なテーブルを作っていく。すると、もう実装に移る。
いま僕がいる部署では、スピード重視なのか設計や要件定義は殆どしない。これがアジャイル開発なのかなぁ、と思ったりもするのだろうがどうだろう？？教えてください。

そんなこんなで、初め定義した機能を満たした画面が4週間で完成した。4画面でこの機能は構成されている。僕も比較的満足して上司に報告した。
すると、上司は
『同時にこれとこれが登録出来る方がよくない？、そっちのが便利じゃん。』
僕は確かにそうだな、と思い機能変更にあまり抵抗を持たず改修に移った。すると、その変更要求を満たすにはテーブルを再定義する必要がある事に気が付いた。
仕方がないので、変更し、定義書をプッシュする。定義が変わったので、コードの様々な箇所に影響が出た。必要以上に改修が嵩み、2週間が過ぎてしまった。
やっとの思いで、変更要求を満たす事が出来た。
しかし、またその状況で困難な事に陥る。今度は自らが機能の欠陥に気が付いてしまった。変更要求を鵜呑みにして、改修した結果、一部の登録情報に影響が出るというものだった。
これはダメだ、と思い上司に相談し納期を遅らせてもらった。
必死に改修を続けた。自分のコードを読み直す中で、段々とクソコードだな、と感じるようになった。道理で改修も進まないわけだ。そこで、自分が書いたクソコードもリファクタリングする事にした。
オブジェクト思考の再利用性や保守性を身を持って実感する事が出来た。
そんなこんなでついに担当機能を完成させた。今まではリーダーに見せていたが、今度はマネージャーに見せる事になった。

結果は、不合格。あれだけリーダーやメンバの意見を信じて、機能変更してきたにも関わらずそれが否定？されてしまった。
上司曰く、機能が複雑すぎてお客さんにとっては難しい、との事だった。自分もその言葉に目を覚まして再度自分が作った物を見てみると、機能だけはリッチだが、本当に分かりにくい、使いづらい、難しい、と感じた。その瞬間に自分の愚かさを痛感した。

この経験を通じて僕は以下のような事を学んだ。
###・マネジャ、リーダー、メンバーの意見が絶対な正解ではない。

###・コーディングに追われて、システムの利便性を見失わない。

###・何よりも自分の意見をもってそれを信じる事。(勿論、誰よりもその機能に詳しくなり、顧客志向である事の前提のもと)

###・自分の意見を正しいものだと納得させる話し方を身につけること。


確かに今回の機能実装に関して、遅延してしまったが、自らの教訓として得る事ができた。新卒の内にこの様な経験をたくさん積んで、次に同じ様なシチュエーションに遭遇したら適切な行動がとれるようにしようと思う。

以上です。アドバイスあればよろしくお願いします。
秒速でコピペしたいHaskellデバッグ用関数

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ElmのDebug.traceみたいな挙動のプリンター、誰かhackageに挙げてないの？ないならさっさと作るよ？ <a href="https://twitter.com/hashtag/haskell?src=hash">#haskell</a></p>&mdash; Yuji Yamamoto: 山本悠滋 (@igrep) <a href="https://twitter.com/igrep/status/824139133094338560">2017年1月25日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

いつも[秒速で作ってる人もいるみたい](https://twitter.com/jinjor/status/824139563207716864)だけど、やっぱり逐一書く時間が勿体ないと思うのでここにメモします [^elm-log]。

[^elm-log]: この記事の最後でも触れますが、冒頭のtweetの「ElmのDebug.traceみたいな挙動のプリンター」の部分は正しくは「ElmのDebug.logみたいな挙動のプリンター」です。

求めていたものは[TraceUtils](http://hackage.haskell.org/package/TraceUtils-0.1.0.2)にありました。
気が向いたらcabalファイルに書けばよいでしょう。
ただ、どうやらstackageには登録されておらず、[LTS 7.16](https://www.stackage.org/lts-7.16)の時点で存在しません。
[ドキュメントにも "Feel free to copy&paste these functions into modules that need them, that may be easier to remove/clean up than adding a cabal dependency."](http://hackage.haskell.org/package/TraceUtils-0.1.0.2/docs/Debug-TraceUtils.html)と書かれているので多分コピペした方が速いでしょう。

と、いうわけで特に便利な`traceId`と`traceIdVia`を載せちゃいます。コピペの際邪魔になりそうなのでコメントは削除しました。
好きにコピペすればいいんじゃないかな。

```haskell
import Debug.Trace hiding (traceId)

traceIdVia :: Show b => (a -> b) -> String -> a -> a
traceIdVia via prefix x = trace (prefix ++ ": " ++ show (via x)) x

traceId :: Show a => String -> a -> a
traceId = traceIdVia id

-- おまけ: show ではコードポイントに変えられてしまう日本語を扱う我々にはきっとこちらの方が便利
traceStringVia :: (a -> String) -> String -> a -> a
traceStringVia via prefix x = trace (prefix ++ ": " ++ via x) x

traceString :: String -> String -> String
traceString = traceStringVia id
```

ちなみに、`traceId`については標準の`Debug.Trace`モジュールに同じ名前の関数があるので注意しましょう。なので :point_up: のコードでは hiding しています。
Elmと同様`log`ぐらい短い名前でいいかも。
git で任意のブランチが未プッシュかどうか検証する

git で任意のブランチが未プッシュかどうか検証します。
やり方は複数ありますが、今回は

* `git ls-remote`
* `git rev-parse`

を利用します

## <i class='fa fa-flask'></i> サンプル
### <i class='fa fa-rocket'></i> remote
※ ls-remote は個別のブランチを取得するオプションがないので取得した値から情報を切り出す必要がある

```sh
$ git clone https://github.com/tbpgr/linter-reek
$ cd linter-reek
$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/greenkeeper-atom-linter-8.0.0
  remotes/origin/greenkeeper-eslint-3.3.1
  remotes/origin/greenkeeper-eslint-3.4.0
  remotes/origin/greenkeeper-eslint-config-airbnb-base-5.0.3
  remotes/origin/greenkeeper-eslint-plugin-import-1.12.0
  remotes/origin/master
# greenkeeper-atom-linter-8.0.0 の remote sha を調べてみる
$ git ls-remote origin | grep greenkeeper-atom-linter-8.0.0  | cut  -f1
4d6ab932c68d50c912cf3562990d542dd8572bc6
```

### <i class='fa fa-home'></i> local
```sh
$ git checkout -b greenkeeper-atom-linter-8.0.0 -t origin/greenkeeper-atom-linter-8.0.0
$ git rev-parse greenkeeper-atom-linter-8.0.0
4d6ab932c68d50c912cf3562990d542dd8572bc6

# 試しに greenkeeper-atom-linter-8.0.0 ブランチを変更してみる
$ touch hoge;git add hoge;git commit -m "test"
[greenkeeper-atom-linter-8.0.0 40256a6] test
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 hoge

$ git rev-parse greenkeeper-atom-linter-8.0.0
40256a67e5cb4bdb5d46df4aecf36702783fdc9c

# git log で答え合わせ
$ git log -1
commit 40256a67e5cb4bdb5d46df4aecf36702783fdc9c
```

## <i class='fa fa-graduation-cap'></i> まとめ
remote で取得した値と local で取得した値を比較することで未pushかどうか判別できます。

## <i class='fa fa-book'></i> 関連資料
* [gitのリモートリポジトリの更新を確認する - yuyuchu3333 - Qiita](http://qiita.com/yuyuchu3333/items/a30387bdd6a0afc1185c)
* [git ls-remote](https://git-scm.com/docs/git-ls-remote.html)
* [git rev-parse](https://git-scm.com/docs/git-rev-parse)
Thorで出力テキストに色をつける

Thorで出力テキストに色をつけます

## <i class='fa fa-question'></i> Thorとは？
Ruby の CLI ツールの作成を支援するライブラリです。

[Ruby の CLI ツールの作成を支援する、 thor gem の基本について - Qiita](http://qiita.com/tbpgr/items/10a5c236cfb528c76ef5)

## <i class='fa fa-flask'></i> サンプル
### <i class='fa fa-code'></i> コード
~~~ruby:sample.rb
require 'thor'

def error_message(message)
  colored_message(message, ::Thor::Shell::Color::RED)
end

def warning_message(message)
  colored_message(message, ::Thor::Shell::Color::YELLOW)
end

def colored_message(message, color)
  ::Thor::Shell::Color.new.set_color(message, color)
end

puts error_message("エラーだお")
puts warning_message("ワーニングーだお")
~~~

### <i class='fa fa-terminal'></i> 出力
```sh
$ ruby sample.rb
エラーだお
ワーニングーだお
```

![outputs.png](https://qiita-image-store.s3.amazonaws.com/0/43480/f70dc441-0253-6116-c28d-07f124b9405e.png)

## <i class='fa fa-book'></i> 関連資料
* [Class: Thor::Shell::Color - thor api doc](http://www.rubydoc.info/github/wycats/thor/Thor/Shell/Color)
素人の言語処理100本ノック:67


[言語処理100本ノック 2015](http://www.cl.ecei.tohoku.ac.jp/nlp100/)の挑戦記録です。環境はUbuntu 16.04 LTS ＋ Python 3.5.2 \:\: Anaconda 4.1.1 (64-bit)です。過去のノックの一覧は[こちら](http://qiita.com/segavvy/items/fb50ba8097d59475f760)からどうぞ。

## 第7章: データベース
>artist.json.gzは，オープンな音楽データベースMusicBrainzの中で，アーティストに関するものをJSON形式に変換し，gzip形式で圧縮したファイルである．このファイルには，1アーティストに関する情報が1行にJSON形式で格納されている．JSON形式の概要は以下の通りである．
>
>|フィールド|型|内容|例|
>|--------|--------|-----|----|
>|id|ユニーク識別子|整数|20660|
>|gid|グローバル識別子|文字列|"ecf9f3a3-35e9-4c58-acaa-e707fba45060"|
>|name|アーティスト名|文字列|"Oasis"|
>|sort_name|アーティスト名（辞書順整列用）|文字列|"Oasis"|
>|area|活動場所|文字列|"United Kingdom"|
>|aliases|別名|辞書オブジェクトのリスト||
>|aliases[].name|別名|文字列|"オアシス"|
>|aliases[].sort_name|別名（整列用）|文字列|"オアシス"|
>|begin|活動開始日|辞書||
>|begin.year|活動開始年|整数|1991|
>|begin.month|活動開始月|整数||
>|begin.date|活動開始日|整数||
>|end|活動終了日|辞書||
>|end.year|活動終了年|整数|2009|
>|end.month|活動終了月|整数|8|
>|end.date|活動終了日|整数|28|
>|tags|タグ|辞書オブジェクトのリスト||
>|tags[].count|タグ付けされた回数|整数|1|
>|tags[].value|タグ内容|文字列|"rock"|
>|rating|レーティング|辞書オブジェクト||
>|rating.count|レーティングの投票数|整数|13|
>|rating.value|レーティングの値（平均値）|整数|86|
>
>artist.json.gzのデータをKey-Value-Store (KVS) およびドキュメント志向型データベースに格納・検索することを考える．KVSとしては，LevelDB，Redis，KyotoCabinet等を用いよ．ドキュメント志向型データベースとして，MongoDBを採用したが，CouchDBやRethinkDB等を用いてもよい．

###67. 複数のドキュメントの取得
>特定の（指定した）別名を持つアーティストを検索せよ．

####出来上がったコード：

```python:main.py
# coding: utf-8
import json
from pymongo import MongoClient
from bson.objectid import ObjectId


def support_ObjectId(obj):
	'''json.dumps()でObjectIdを処理するための関数
	ObjectIdはjsonエンコードできない型なので、文字列型に変換する

	戻り値：
	ObjectIdから変換した文字列
	'''
	if isinstance(obj, ObjectId):
		return str(obj)		# 文字列として扱う
	raise TypeError(repr(obj) + " is not JSON serializable")


# MongoDBのデータベースtestdbにコレクションartistにアクセス
client = MongoClient()
db = client.testdb
collection = db.artist

# 条件入力
clue = input('アーティストの別名を入力してください--> ')

# 検索
for i, doc in enumerate(collection.find({'aliases.name': clue}), start=1):

	# 整形して表示
	print('{}件目の内容：\n{}'.format(i,
		json.dumps(
			doc, indent='\t', ensure_ascii=False,
			sort_keys=True, default=support_ObjectId
		)
	))
```

####実行結果：

```console:実行結果
アーティストの別名を入力してください--> スマップ
1件目の内容：
{
	"_id": "5879fd911d41c85827314a38",
	"aliases": [
		{
			"name": "スマップ",
			"sort_name": "スマップ"
		}
	],
	"area": "Japan",
	"begin": {
		"month": 4,
		"year": 1988
	},
	"ended": true,
	"gid": "6ab7953b-8480-41fe-a9fe-5e220d8e9429",
	"id": 265728,
	"name": "SMAP",
	"sort_name": "SMAP",
	"tags": [
		{
			"count": 1,
			"value": "likedis auto"
		}
	],
	"type": "Group"
}
```

###複数のドキュメントの取得
プログラムはほとんど[問題65](http://qiita.com/segavvy/items/d360c2568b49bd5c153a)のままです。条件を入力できるようにして、検索対象をアーティスト名（name）から別名（aliases.name）に変えました。
今回の問題名は「複数の」ドキュメントの取得なのですが、実行例としてうまく複数のドキュメントをヒットさせる条件が見つかりませんでした(^^;

　
68本目のノックは以上です。誤りなどありましたら、ご指摘いただけますと幸いです。
<hr>

*実行結果には、[100本ノックで用いるコーパス・データ](http://www.cl.ecei.tohoku.ac.jp/nlp100/#data)で配布されているデータの一部が含まれます。この第7章で用いているデータのライセンスは[クリエイティブ・コモンズ 表示 - 非営利 - 継承 3.0 非移植](https://creativecommons.org/licenses/by-nc-sa/3.0/)（[日本語訳](https://creativecommons.org/licenses/by-nc-sa/3.0/deed.ja)）です。*
EventMachineのイベントハンドラでエラーが発生したときにバックトレースを表示する


faye-websocketを使ったコードを書いているときに、`on(:message)`とかのイベントハンドラでエラーがあっても何も表示されないのでかなりあせりました。
faye-websocketが非同期処理に使っているEventMachineがそもそもそういう動作っぽいです。

開発中は以下のようなコードをファイルの先頭あたりにでもいれておけばイベントハンドラ内でのエラーが表示されるようになって幸福実現です。

```ruby
EM.error_handler{ |e|
  STDERR.puts e.message
  STDERR.puts e.backtrace.join("\n")
}
```

参考: http://stackoverflow.com/questions/7628232/how-to-catch-top-level-failures-on-an-eventmachine-server
Laravel5.3でEloquentObjectをCollectionにまとめる方法

# 需要あるのかしら・・・
と思いながら備忘録的に書いています。

# ことの発端は
1. DBからとってきたEloquentオブジェクト
2. KVSにmessagepackされたEloquentオブジェクト

この2つをマージしてCollectionにして呼び出し元では気にせずに

```PHP
echo $model->name;
```

としたいというではありませんか！

# 結論
* はてさてそんなことできるのかと思いLaravelのコードを読んでみて試してみた。

```PHP
$fromdb = HogeModel::where('id', '>=', 100)->get();
$fromkvs = Cache::get('key_99');

// 単純に全くゼロの状態でつくりたいときは
$collection = \Illuminate\Database\Eloquent\Collection::make($fromkvs);

// マージしたいときは
$collection = $collection->merge($fromdb);
```

* これで受け取った側はそのままforeachしてプロパティにアクセスができる。
* わかってしまえば簡単ですね。
Bootstrap Calendarの雛形

メモ

```php
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<title></title>
	<meta name="robots" content="noindex,nofollow">

	<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/iScroll/5.1.3/iscroll.min.js"></script>
	<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
	<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
	<!-- Optional theme -->
  <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

<?php
	//CSS
	echo $html->css('//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css');
	//DatePicker
	echo $html->css('//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.4/css/bootstrap-datepicker.min.css');
	//JS
?>
</head>
<body>
    <div class="container">
      <h1>こんにちは、Datepicker！</h1>
      <div class="form-group">
        <label for="day1">日付</label>
        <input type="text" class="form-control datepicker1" name="day1" id="day1" placeholder="日付" readonly>
      </div>
    </div>
<!-- セクション -->
<?php

	// メインコンテンツ
	print $content_for_layout;
?>
<!-- セクション -->
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<!-- Latest compiled and minified JavaScript -->
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<!-- Datepicker for Bootstrap -->
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.4/js/bootstrap-datepicker.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.4/locales/bootstrap-datepicker.ja.min.js"></script>

<script>
	$('.datepicker1').datepicker({
	format: "yyyy/mm/dd",
	language: "ja",
	autoclose: true, //日付選択で自動的にカレンダーを閉じる
	orientation:'bottom left',
	todayHighlight: true,
	startDate: "2017/01/25"
	});
</script>

</body>
</html>

```
Linux - 現場で便利な操作＆コマンド

この投稿は便利なコマンドや操作をまとめします。
実行環境：
　ー　ツール：TeraTerm
　ー　OS:Redhat や　CentOS
留意：自分の使っているやつしか書いてないです。（^^;;;

１．ターミナル
　◉　カーソルを最初に移動する
　　Ctrl + A 
  
　◉　カーソルを最後に移動する
　　Ctrl + E 

　◉　カーソルを右へ移動する
　　Ctrl + B

　◉　カーソルを左へ移動する
   Ctrl + F

　◉　全部のコマンドを削除する
　　Ctrl + U
　
　◉　カソールの前の文字を削除する
　　Ctrl + H

　◉　カソールの後ろの文字を削除する
　　Ctrl + D

　◉　一つの単語を削除する
　　Ctrl + W
　
２．ファイルをバックアップする
　cp　<ファイル名>{,<任意の文字>."$(date +%Y%m%d_%H%M%S"}
  
  例: 
＄　cp testfile.txt{,.backup."$(date +%Y%m%d_%H%M%S)"}
  　結果: testfile.txt.backup.20170125_222251

３．前のコマンドの一覧やリストなどから検索
　＜コマンド＞　｜　grep ＜検索キーワード＞
例： 
＄　cat logs.170121.1133 | grep "HTTP 200"
　　結果：　HTTP　２００のある行が表示される

＄　yum list installed | grep vim
   結果：　インストールされた　VIMパッケージの情報が表示される
　　インストールしなかったら、なにも表示されません。

４. ログを見るときはこのコマンドを使えば、見続ける：
　　tail -f  ＜ログが格納場所＞　

＄　tail -f /var/log/tondemonai.log
Cでtable-driven testを書く

はじめに
--------

Goが推奨するtable-driven testが、Cでも記述できるのに気づきました。

Goのtable-driven test
---------------------

Goのテストは、[table-driven test](https://github.com/golang/go/wiki/TableDrivenTests)が推奨されています。テスト対象に与えるデータ入力と期待値のペアを1つのテストケースとして扱い、期待値と実測値の一覧を表のように表します。

たとえば`gcd()`メソッドのテストをtable-drivenで書くなら、次のようになります。

```go:gcd_test.go
func TestGcd(t *testing.T) {
	cases := []struct {
		a, b int
		z    int
	}{
		{12, 8, 4},
		{3, 7, 1},
	}

	for _, c := range cases {
		if gcd(c.a, c.b) != c.z {
			t.Errorf("expected gcd(%v,%v) == %v\n", c.a, c.b, c.z)
		}
	}

}
```

Goはstructの定義と変数の初期化を同時に書くことができます。テストケースの初期化はstruct literal syntax`{}`で、容易かつ型安全に初期化できます。コードはテストデータのみに集中できるので、非常に読みやすいです。

Cのtable-driven test
---------------------

Cで同じく`gcd()`のテストをtable-drivenに記述してみました。Cでも構造体宣言と変数の初期化が同時に行えます。そして初期化はstruct literal syntax`{}`で型安全に行うことができます。

```c:gcd_test.c
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

int test_gcd() {
	struct {
		int a, b;
		int z;
	} cases[] = {
		{12, 8, 4},
		{3, 7, 1},
	};

	for (int i = 0; i < ARRAY_SIZE(cases); ++i) {
		if (gcd(cases[i].a, cases[i].b) != cases[i].z) {
			printf("expected gcd(%d,%d) == %d\n", cases[i].a, cases[i].b, cases[i].z);
		}
	}
}
```

Goと比較しても、記述量や可読性に大きな差がなく、C言語でtable-driven testを記述できました。

おわりに
--------

Goは簡単なCとよく言われますが、Goの文化をCに輸入するのもよいですね。
【備忘録】Flacのインストール Windows編

## １．概要
ハイレゾ配信対応時に、Flacファイルのメタ情報に画像が正しく打たれているかを確認するために、
WindowsにFlac（CUI）をインストールしたので、その手順を明記します。

## ２．インストールの取得
以下のサイトからインストーラーを取得する。

■公式サイト
[FLAC - download](https://xiph.org/flac/download.html)

■手順
１．「FLAC for Windows」のリンクを押下して、DownLoadページを表示する。
２．「flac-1.3.1-win.zip」をダウンロードする。（2016/09/14 時点）

## ３．インストール手順
以下の手順でインストールをする。

■手順
１．「flac-1.3.1-win.zip」を解凍する。
２．配下に「win32」と「win64」のディレクトリがあるので、環境に合わせて残して、残りは削除する。
３．適宜、配置する。　※自分は、「C:\Program Files (x86)\flac\win64」として配置した。
４．環境変数のPATHに上記のパスを設定する。
## ４．実行確認
コマンドプロンプトを開いて、以下のコマンドを実行する。

```
C:\Users\k-yamamoto>flac -v
flac 1.3.1

C:\Users\k-yamamoto>metaflac --v
metaflac 1.3.1
```
## ５．補足事項
１．FLACの公式ツールとして、「flac」と「metaflac」があるそうです。
　※メタを操作するのは「metaflac」でした。

[FALC - documentation](https://xiph.org/flac/documentation_tools.html)

２．画像を取り出すのは、以下のコマンドを実行しました。

```
metaflac --export-picture-to C:\tmp\60254182.jpg C:\tmp\60254182.flac
```

３．コマンドのヘルプは、以下のページとなります。

[FALC - documentation（flac）](https://xiph.org/flac/documentation_tools_flac.html)
[FALC - documentation（metaflac）](https://xiph.org/flac/documentation_tools_metaflac.html)
PostgreSQLのOLEDB接続は使用しない方がいい

# はじめに
2013年ぐらいにIIS + レガシーASP + Oracle10gの業務システムをノートPCのみ(スタンドアローン版)で海外でも動作できるようにデータベースをPostgreSQL9.2.4に改修があり、同僚が担当しました。
※PostgreSQLの接続には、OLEDBドライバー [PgOleDb	1.0.0.20](http://pgfoundry.org/projects/oledb/)を使用

改修はしたものの結局使用されることなく数年が経ち、最近になりスタンドアローン版を使用してみたいという企画が出てきて、ノートPCにスタンドアローン版を導入して動作検証することになりました。

# 動作が遅い
ノートPCにスタンドアローン版の業務システムを導入してみたものの、動作が遅いということで何が原因なのか調査することになりました。

先ずは計測ということで、実行するSQLと処理時間をファイル出力する仕組みを作成しました。
すると特定のSQLが遅いわけでもなく、各SQLが100ms以上かかっておりトータルして遅いことが分かりました。PGAdminで各SQLを実行すると10msほどで処理が終わるので10倍は遅いってことです。ノートPC固有の環境が悪さしている可能性もあったので、別のPCに導入してみましたが結果は同じでした。

# ODBCドライバーに変更
PostgreSQLの接続にOLEDBドライバー [PgOleDb 1.0.0.20](http://pgfoundry.org/projects/oledb/)を使用していたので、先ずはODBC接続ドライバーを下記サイトからインストール(psqlodbc_09_02_0100.zip)して変更してみました。
https://www.postgresql.org/ftp/odbc/versions/msi/
すると各SQLが10msで処理が終わり、本来の業務システムとして正常な速度になりました。

参照：[ExcelからPostgreSQLにODBC接続してピボットテーブルを作成する](http://pgsqldeepdive.blogspot.jp/2013/04/excelpostgresqlodbc.html)

# 別のOLEDBドライバーを試す
別のOLEDBドライバーの「[PM PostgreSQL OLEDB](https://sourceforge.net/projects/pmpostgresqlole/)」も試してみたのですが、PgOleDbより少し速い程度でやはり遅い上に、PgOleDbでもODBCでもエラーにならなかった部分(numericの値)が正常に取得できないなど問題があったので止めました。

# 最後に
PgOleDbでは、「[PostgreSQLのnumeric型フィールド値がうまく取得できない](http://qa.atmarkit.co.jp/q/5163)」という問題もあるので、ADOやExcelなどでPostgreSQLを使用したい場合は、ODBC接続ドライバーを使用した方がいいでしょう。
.NETの場合は.NETライブラリ「Npgsql」を使えばいいですね。
「Ora-01722 数値が無効です」が出たときに使えたSQL

#Ora-01722について
文字列型(varchar,charなど)をto_numberを使って数値に変換する際、
「数値以外の文字が入ってるからnumber型に変換できません」っていうエラー

#シチュエーション
文字列型の列col1を持つtblAというテーブルに、以下のようなUpdate文を流したい。

```
UPDATE tblA
SET col1 = to_char( ( to_number( col1 ) +1 ) 
```

col1は数字だけの文字列が期待されているが、なにかの誤操作で数値以外の文字列が入っており、ora-01722が発生した。
テーブル全体に対してUpdateをかけているのでエラー該当行がパッと分からない。
どの行でora-01722が発生しているか特定したい。

#役に立ったSQL
```
SELECT * FROM tblA
WHERE (REGEXP_LIKE(COL1, '[^0-9]'))
```

##解説
###REGEXP_LIKE(COL,'regex')
COLに正規表現'regex'が部分マッチするかどうか
###[^0-9]
'^'は正規表現で否定を表す。つまり[^0-9]は数値以外の文字をあらわす。
###つまり？
正規表現で「数値以外の文字がcol1に含まれている」行をselectしている。

#参考(というか引用)
http://d.hatena.ne.jp/gonsuke777/20120215/1329301835
Travis CIでxcode8.2にしたらarchiveのcodesignで固まる、の解決方法

Travis CIで`osx_image`を`xcode8`から`xcode8.2`にあげたら、`archive`時にcodesignで１０分間応答がなくなり、buildが失敗するようになりました。

原因はMac OS Sierraから必要になったkeychain操作のコマンド修正をしていなかったため。
Travis CIではxcode8.1以上にすると、OSがMax OS 10.12 (= Sierra)になってしまうため、keychain操作のコマンドも変更が必要だった様子。

くわしくはTuenoさんのこちらのエントリの"CI上でのsigning時にハングする"に書いてある方法で解決できます。
[Xcode8のAutomatically manage signingを有効にしつつCI環境でも動作するようにする](http://qiita.com/Tueno@github/items/b6a3012059813eec4117#ci%E4%B8%8A%E3%81%A7%E3%81%AEsigning%E6%99%82%E3%81%AB%E3%83%8F%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B)

（追記）
Travisのcommon build problemsにも追記されましたね。
https://docs.travis-ci.com/user/common-build-problems/#Mac%3A-macOS-Sierra-(10.12)-Code-Signing-Errors
HaxeでPHPのNativeArrayを試す

HaxeにはPHPの配列を直接利用するために`php.NativeArray`という型があります。
`php.NativeArray`はどのように利用して、どのようなコードを出力するのでしょうか？

## HaxeのArrayType

通常、Haxeの中で定義した配列はトランスパイル後にHaxeが独自に定義する配列型でラップされた配列となります。

```hx:Haxeでの配列
[1,2,3,4,5];
```

```php:トランスパイル後（PHP）の配列
\Array_hx::wrap([1,2,3,4,5,]);
```

Haxeが提供する型によって安全性は保たれるものの、キーの型が固定されてしまうことによるPHPとの連携が難しくなる問題や、常に配列用のインスタンスを生成することによるパフォーマンスの劣化が問題となっていました。

## php.NativeArray

`php.NativeArray`はその名の通り、PHPの純粋な配列をHaxeから利用することを可能にする型です。

以下のようにして利用することが出来ます。

```hx
var arr = new php.NativeArray();
arr[0] = "a";
arr["foo"] = 1;
```

これは下記のようにトランスパイルされます。

```php
$this1 = [];
$this1[0] = "a";
$this1["foo"] = 1;
```

Haxeの中ではキーに`Int`と`String`が混在して使え、またセットする型はDynamicで定義されるのでどんな値でもセットすることが出来ることがわかります。

もっとも、Haxe側から型が混在するようなコードを書くことはありませんが、PHPのライブラリのExternを利用するときなどに大変役にたちますね。

`php.NativeArray`はそのままではループ処理に利用することが出来ませんが、`iterator`メソッドを呼ぶことでループ処理に利用できるようになります。

```hx
var arr = new php.NativeArray();
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;

for (item in arr.iterator()) {
    php.Lib.dump(item);
}
```

このコードはトランスパイル後下記のようになります。

```php
$this1 = [];
$this1[0] = 1;
$this1[1] = 2;
$this1[2] = 3;
$_g_hasMore = reset($this1) !== false;
while ($_g_hasMore) {
    unset($result);
    $result = current($this1);
    $_g_hasMore = next($this1) !== false;
    var_dump($result);
}
```

ループ処理の部分のコードがちょっと直感的ではないのですが、すべてNativePHPのコードになっていることが分かります。

---

`php.NativeArray`を通すことで、PHPの配列を利用することが出来るようになります。

HaxeのPHP7対応に加えて`php.NativeArray`を利用していけばパフォーマンスを保ちつつHaxeの型システムを利用しか開発が行えそうですね！