OmniAICreator/Qiita-1.07M huggingface dataset:
AWK によるテキストのワンライナー処理クックブック集

ログ集計など、コマンドラインで作業するとき、awk でさらっとワンライナーが書けると捗ることがあります。
本記事で、ユースケースに応じた awk のコマンド実行例を記していきます。主にサーバ運用に従事する方向けの内容になるでしょう。

私自身のユースケースに当てはまらないものは書かないこともありそうです。
何かお気づきの点があればお知らせ下さい。

# 入門編

## 指定したフィールドを抽出

```bash
% awk '{print $2,$3}' sample.tsv # 2,3列目
```

## `-F` オプションで区切り文字を変える

```bash
% awk -F, '{print $2,$3}' sample.csv # ,で区切って 2,3列目を出力
```

# 基本編

## 組み込み変数・特殊変数

- `NF` ... フィールド数
- `NR` ... 行番号
- `$0` ... 行全体の文字列

## 末尾からn番目のフィールドを指定する

`$NF` で末尾のフィールド、 `$(NF-n)` で末尾から n 番目のフィールドを指定できます。

```bash
% awk '{print $1,$(NF-1),$NF}' sample.csv # 1列目と最後の2列を出力
```

## 書式指定

`printf 書式, 変数1, 変数2, ...` の構文が使えます。

```bash
% awk '{printf "%10s %5d\n",$1,$3}' sample.dat
```

## 各行の長さを出力

`length(string)` 関数で改行を含む文字列の長さを取得できるので、これを利用します。

```bash
% awk '{print length($0)}' sample.txt
```

応用例としては、 `sort` と組み合わせて長い行から順に出力するということが、簡単にできます。

```bash
# 1行が長い順に TOP 10 を行長とともに表示
% awk '{print length($0), $0}' sample.txt | sort -nr | head
# 1行が短い順に TOP 10 を行長とともに表示
% awk '{print length($0), $0}' sample.txt | sort -n | head
```

## 集計処理

以下、sample.dat の4つめのフィールドに値が入っているとします。

### 平均値の算出

```bash
% awk '{sum += $4} END {print sum/NR}' sample.dat
```

### 最大値の算出

```bash
% awk '{if (max<$4) max=$4} END {print max}' sample.dat
```

### 連想配列を使ってキーごとに集計

```bash
% awk '
{sum_of[$3] += $4} END {for (key in sum_of) {printf "Key: %s, SUM: %d\n", key, sum_of[key]}}
' sample.dat
```

# 応用編

## 指定したフィールド"以外"を出力

```bash
#!bash
% echo {1..5} | awk '{$1=$3="";print}'
 2  4 5
```

# 参考

- [The GNU Awk User’s Guide](https://www.gnu.org/software/gawk/manual/gawk.html)
- [awkガナス(4) – 組み込み変数NF(フィールド数) NR(行番号) — SOUM/misc](http://www.soum.co.jp/misc/naka/awk/4.html "awkガナス(4) – 組み込み変数NF(フィールド数) NR(行番号) — SOUM/misc")
- [awkで末尾から数えてn番目のフィールドを取り出す。 - Qiita](http://qiita.com/koitatu3/items/3d746c7e292908c6167e "awkで末尾から数えてn番目のフィールドを取り出す。 - Qiita")
- ["awk" 指定した列を除いて表示する @LCD -Linux Command Dictionary-｜Replog!株式会社レップワンスタッフによるブログです](http://www.rep1.co.jp/staff/200vcxg/217rav/awk_lcd_-linux_command_diction_1.htm)
- [Let's AWK](http://aoki2.si.gunma-u.ac.jp/Hanasi/Algo/letsawk/WhatIsFunction.html "Let's AWK")
- [awk の連想配列 — WTOPIA v1.0 documentation](http://www.ie.u-ryukyu.ac.jp/~e085739/awk.tuts.ch17.html "awk の連想配列 — WTOPIA v1.0 documentation")

本稿は、自分の過去のブログ記事から加筆修正してまとめ直しました:

- [AWKによるテキストファイルのワンライナー処理 - weblog of key_amb]( http://keyamb.hatenablog.com/entry/20120516/1337144072)
mosh-server プロセスを kill する


mosh を利用していると、サーバー側の mosh-server プロセスが意図せずに残ってしまうことがある。

プロセスが残ってしまっているかどうかは、サーバーにログインして `w` コマンドを実行すると確認できる。


全ての mosh-server プロセスを kill する場合は

```
kill `pidof mosh-server`
```

を実行する。
現在接続しているプロセスも削除されるので、自動的にログアウトされる。
ps の結果からパスに空白を含むコマンド名を適切に処理する


GW に Mac の実行プロセスプロセスを可視化してかっちょよくする計画があったのだけど、psの処理結果をテキストでパースしようとして、パスに空白が入っている時いい感じに処理できないことに気がついた。

psコマンドは -o でフォーマットを変更できる・・・ということになっているのだけど、できるのは出力するカラムの追加削除だけで任意の出力形式にできるわけではない。区切り文字は空白で、空いた箇所も空白でパディングされるのでどーも綺麗に分割できない。。

## 「それ、AWKでできるよ」

と 思ったけど、AWKは cut みたいに「ある列から末尾までまとめて出力」がやりづらい。

かといって正規表現で切り出すのも嫌だ。

ということで、こんな感じになりました。

```shell-session
ps -A -o pid,%mem,comm | awk 'NR==1{ D=index($0, "COMM");} NR!=1{print "pid:" $1 "\tmem:" $2 "\tcommand:" substr($0, D, length($0))} '
```


## 内容

```awk
NR==1{ D=index($0, "COMM");}
```

これで1行目、ヘッダ "COMM" の位置を特定して。

1行目以外では、その位置から末尾までを substr で拾っている。

```awk
NR!=1{print "pid:" $1 "\tmem:" $2 "\tcommand:" substr($0, D, length($0))}
```

これなら手書きワンライナーできる程度にはシンプルだし汎用性がある。よしよし。

Atom Helper とか JUST UpdateChecker とか Google Chrome Helper とかがいてもコマンド名がちゃんと処理できてハッピーである。

これ書いてて気がついたけど、この問題に自分は以前も悩んだ記憶がある。その時はどうやったのかなぁ。
Laravel4でDBテーブルの値をselectで取り出す方法

下記のようなテーブルがあるとする。

    mysql> select name from company_basic_info;
    +-----------------------------+
    | name                        |
    +-----------------------------+
    | お試し有限会社              |
    | サンプル株式会社            |
    | なんとか証券会社            |
    | 合同会社あいうえお          |
    +-----------------------------+
    4 rows in set (0.00 sec)

このテーブルから会社名をすべて取り出したい。
その場合は、コントローラに下記メソッドを実装する。


    function index(){
        $inData = DB::table('company_basic_info')->get();
        return View::make('piyo')->with('inData',$inData);
    }

ここで、piyo は、ビューであり、
views/piyo.php
とする。その中身は下記のように実装する。


    <?php
    foreach(  $inData as $value ){
        echo $value->name . '<br/>';
    }
    ?>


あとは、routes.php に下記を設定して、

    Route::get('hoge/', 'HogeController@index');

http://localhost/hoge
にアクセスして、下記がブラウザに表示されたらOK。

    お試し有限会社
    合同会社あいうえお
    なんとか証券会社
    サンプル株式会社
Rails deviseによる認証機能の実装 参考まとめ ~facebook・twitter認証まで~

deviseによるユーザー認証機能の実装で役立った記事をまとめます。
**目次**
1.deviseの導入
2.deviseでの登録時に独自入力フォームを追加する
3.登録完了時にウェルカムメールを送信する
4.管理ユーザーを設定する
5.日本語化する
6.facebook認証
7.twitter認証

##1.deviseの導入
[Devise で認証機能を追加](http://railsgirls.jp/devise/)
記事通りに進めればオーケー。
“"Rails のサーバーが起動している事を確認したら、http://localhost:3000/users/sign_up をブラウザで開いてユーザーを作成してください。”"
の部分は再起動しないとエラー表示が出ることに注意。

##2.deviseでの登録時に独自入力フォームを追加する
[Rails4 Devise でサインアップ用のユーザー登録フォームに、独自の入力フィールドを追加する](http://easyramble.com/add-field-devise-signup-form.html)
ーサインアップ時に独自のフィールドを追加出来る。
ー基本的にこれで出来る
ただし、
app/views/users/regsitrations/new.html.erb
の部分は
app/views/devise/regsitrations/new.html.erb
だった（あと、viewの中身がちょっと違う）

##3.登録完了時にウェルカムメールを送信する
[Deviseでユーザー登録完了時にウェルカムメールを送信する]
(http://easyramble.com/welcome-mail-with-devise.html)
ーサインアップ時のメールの送信

注意点
ーrails cの後は
UserMailer.registration_confirmation.deliverではなくて
UserMailer.registration_confirmation.deliver_nowを打つ。
ー2段階認証プロセスに登録している場合は、アプリケーション固有のパスワードが必要になるが、登録してなければ気にする必要はない。
ただし、今回は2段階認証プロセスに登録していないのにauthエラー。ここで、「安全性の低いアプリを許可」で対応。
https://www.google.com/settings/security/lesssecureapps
ーconfig.action_mailer.raise_delivery_errors = true
ここをfalseとしてエラーメッセージがでなくて困ったので注意。
ー[メーラーからGmailへの接続時に認証（パスワード）のエラーが生じる場合の対処方法]
(http://www.atmarkit.co.jp/ait/articles/1409/03/news109.html)


[RailsのActionMailerでメールを送信する（Gmail経由）]
(http://qiita.com/ytr_i/items/0907ee3312ed9d79c9e8)
ーメール送信についてわかりやすくまとまっている

##4.管理ユーザーを設定する
[RailsとDeviseで管理者ユーザーを作ることに成功した]
(http://blog.panicblanket.com/archives/2054)
ー仕様：usersテーブルの中にadmin booleanを設定して、adminを判定。
user登録時にadminの設定がされているユーザがいなければ、adminへのチェックボックスが表示。既にアドミンが設定されていればチェックボックスは非表示。（つまり、最初のユーザだけadminになれる）

config.scoped_views = trueについて
http://d.hatena.ne.jp/gen0_0/20110125/1295987729
通常ユーザと管理人用ユーザのログイン画面を分けたいときに追記する。

##5.日本語化する
[railsの日本語化 deviseの日本語化](http://qiita.com/shizuma/items/a52fd0ef5b60d61fa330)
ーこれでdeviseも含め、日本語化出来る。

##6.facebook認証
以下の記事でひと通り出来る。
[Devise+OmniAuthでユーザ認証を実装する手順]
(http://qiita.com/kami30k/items/94aec2d94a2b4e9a1d0b)


以下、ひと通り記事通りにやってfacebookログインを試みたあとのエラー対応。

★missing required keys: [:provider]というエラー。

routes.rbのdeviceに
:omniauth_providers => [:facebook]
を追加した。
これでもうまく反映されなかったが、rails sをかけたらうまくいったので注意。

参考
[deviseでomni-authと組み合わせてたら「missing required keys: [:provider]」]
(http://qiita.com/ms2sato/items/0854de777dc27ca6f0b3)


★なぜかログインボタンを押してもログイン出来ない（ユーザ登録出来ていない）。

原因：メールアドレスでのユーザ登録時に付けたバリデーションが悪さしてた。
User.createの部分を
User.newとUser.save(:validate => false)で対応。

参考
[Devise + omniauthでfacebookでログインする機能を実装でハマったところを説明]
(http://nigohiroki.hatenablog.com/entry/2013/08/16/234258)


##7.twitter認証
facebook認証と同様に以下の記事でひと通り出来る。
[Devise+OmniAuthでユーザ認証を実装する手順]
(http://qiita.com/kami30k/items/94aec2d94a2b4e9a1d0b)

以下、twitterログイン関連のエラー

★アプリの登録が出来ない（URLでエラーが出る）

[Twitter Developer画面](https://apps.twitter.com)でwebサイトの設定を
```http://localhost:3000``` に設定するとエラーで登録出来ないが、
```http://127.0.0.1:3000``` に設定すると登録出来た。

★facebookログインのときと同様にmissing required keys: [:provider]というエラー。

以下のように、facebook同様の処理をする
routes.rbのdeviceに
:omniauth_providers => [:twitter]
を追加した。
これでもうまく反映されなかったが、rails sをかけたらうまくいったので注意。
CakePHP3でログをデータベースに書き込む

CakePHP3では、error/debug/infoなどのログをファイルだけじゃなく、データベースにもinsertすることができます。

詳しくは
http://book.cakephp.org/3.0/en/core-libraries/logging.html
に書いてあります

# テーブルの作成

```sql
 CREATE TABLE `logs` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `datetime` datetime NOT NULL,
  `level` varchar(10) NOT NULL,
  `message` text,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
```

# モデルの作成

```shell-session
$ ./bin/cake bake model logs
```

# DatabaseLogクラスの作成

```php:src/Log/Engine/DatabaseLog.php
<?php
namespace App\Log\Engine;

use Cake\Log\Engine\BaseLog;
use Cake\ORM\TableRegistry;

class DatabaseLog extends BaseLog
{
    protected $_defaultConfig = [
        'types' => null,
        'levels' => [],
        'scopes' => [],
        'user_id' => null
    ];

    /**
     * {@inheritDoc}
     */
    public function __construct(array $config = [])
    {
        parent::__construct($config);
    }

    /**
     * {@inheritDoc}
     */
    public function log($level, $message, array $context = [])
    {
        $model = TableRegistry::get($this->_config['model']);
        $entity = $model->newEntity([
            'datetime' => date('Y-m-d H:i:s'),
            'level' => ucfirst($level),
            'message' => $message
        ]);
        $model->save($entity);
    }
}
```

# configの追加

```php:config/app.php
    'Log' => [
        'database' => [
            'className' => 'App\Log\Engine\DatabaseLog',
            'model' => 'Logs',
            'levels' => ['notice', 'info', 'debug', 'warning', 'error', 'critical', 'alert', 'emergency'],
        ],
    ],
```

以上のようにすると、ログがデータベースにも記録されるようになります。
Threadの戻り値と例外


JavaのThread実行で...

* 実行した処理の戻り値の取得
* 発生した例外の取得

が簡単にできましたので、忘れないうちにメモ.

``` java
Integer retVal = null;

// Thread実行したい処理を、Callable<T> interfaceで指定.
// ※ lambda (java8) が使える.
ExecutorService service = Executors.newSingleThreadExecutor();
Future<Integer> future = service.submit( () -> 1 + 2 );

try {
    // 戻り値を取得する.
    // Threadの終了、もしくはタイムアウトまで待つ.
    retVal = future.get(2, TimeUnit.SECONDS);

} catch (InterruptedException ex) {
    // Threadが中断された.

} catch (ExecutionException ex) {
    // 実行した処理が例外を投げた.
    Throwable cause = ex.getCause();

} catch (TimeoutException ex) {
    // タイムアウト秒に達した.
    future.cancel(true); // threadをinterruptする.
}

service.shutdown();
System.out.println("result: " + retVal);
```

```
result: 3
```

タイムアウトをするには、[Thread実行する処理を適切に実装する](http://stackoverflow.com/questions/16277191/executor-service-timeout-of-thread)必要がある.

``` java
// Thread実行したい処理を、Callable<T> interfaceで指定.
// ※ lambda (java8) が使える.
ExecutorService service = Executors.newSingleThreadExecutor();
Future<Integer> future = service.submit( () -> {
    // 時間のかかる処理.
    for (int i = 0; i < 1000000; i++) {
        // future.cancel(true) でThreadがinterruptされる.
        if (Thread.interrupted()) {
            throw new InterruptedException();
        }

        System.out.println("cnt: " + i);
    }

    return 1 + 2;
});
```
Arduino開発 : vim + ino

![arduino_ino.png](https://qiita-image-store.s3.amazonaws.com/0/77816/0c291929-8a3c-f7b1-035a-b0d7ccd780ed.png)
## `ino`について

arduinoのIDEはシンプルでおしゃれなデザインだ。
が、自分はやっぱりコマンドベースで開発したい。

- Mac OS X Yosemite
- Ubuntu 14.04

[ino](http://inotool.org/)という非公式だがコマンドラインツールがある。
それを使えば、簡単にビルドとアップロードができる。公式でも[紹介](http://playground.arduino.cc/Learning/CommandLine)されている。

`ino`は単体ではビルドやアップロードができない。公式のArduino Software(IDE)が必要だ。

が、これにすごはまってしまった。結論から言うとarduino1.0x系だとオリジナルの`ino`は使える。Arduino Softwareは現在、1.0x系と1.5x系(beta)、1.6x系がある。現時点での最新は1.6.3である。
([OldSoftwareRelease](http://www.arduino.cc/en/Main/OldSoftwareReleases))

何パターンか試したんだけど、以下のような結果になった。pipからインストールする`ino`のバージョンはv0.3.6で、v1.5x系に対応しているバージョン(v0.3.7)は自分でインストールする必要がある。あまり良い結果ではないので、最新版をベースにコマンドラインで開発する場合、自分で修正するか別の方法を模索したほうが良さそうだ。

| | ino v0.3.6 (pip install) | ino v0.3.7 (githug install)
|---|---|---|
|IDE v1.6.3 |×|×
|IDE v1.5.8 BETA| × | ×
|IDE v1.5 BETA| x | ○
|IDE v1.0.5| ○ | ○

最新を使ってビルドしたかったので、トライアンドエラーで`ino`の修正を行い、ビルドまではできた。しかし他のコマンド、例えば`upload`も修正が必要だったので心が折れてあきらめた。
だって早くArduinoで遊びたいのだもの。(IDE使えって話なんだけど。。)

とりあえず、古いバージョンでもビルドやアップロードができるのでこちらをメモ。気になる場合は[リリースノート](http://www.arduino.cc/en/Main/ReleaseNotes)で差分を確認してみてください。

## 環境構築

### Arudino Softwareを取得する

長ったるい前置になってしまったが、Arduinoバージョンは`v1.0.5`を使う。MacはArduinoサイトから、Ubuntuは`apt-get`からゲットできる。自分は両プラットホームを一緒に環境構築したのでメモ。どちらも手順はほとんど同じ。

#### Mac

- v1.0x系の最新である[v1.0.5](http://www.arduino.cc/en/Main/OldSoftwareReleases)をダウンロードする

![20150428084901.png](https://qiita-image-store.s3.amazonaws.com/0/77816/a32280b6-dbba-3faa-5705-11e36902a4de.png)


```sh
# wgetでもいける
$ wget http://arduino.googlecode.com/files/arduino-1.0.5-macosx.zip
```

- 解凍してアプリケーションフォルダに放り込む


#### Ubuntu

- `apt-get`でインストールできる。パッケージからのバージョンは[v1.0.5](http://packages.ubuntu.com/trusty/arduino)。

```sh
# arduino IDE
$ sudo apt-get install arduino
```

### inoのインストール

- `pip`を使ってインストール

```sh
$ easy_install pip
$ pip install ino
```

- v1.5対応の最新版がよければ自分でインストール

```sh
$ git clone https://github.com/amperka/ino.git
$ cd ino
$ make install
```

- 環境によっては`sudo`ユーザでなければいけないかも。

## inoを使ってみる

### プロジェクト作成

`-t`でLEDの点灯サンプルコードがデフォルトで書かれている

```sh
$ mkdir ./hoge
$ cd ./hoge
$ ino inot -t blink
```

### build

```sh
$ ino build
```

### upload

特にポート指定しなくてもアップロードはできた。オプションで指定もできる。

```sh
$ ino upload
```

## おしまい

何も細かいことを気にせずにシンプル操作でビルドとアップロードができるはすごく便利だ。
もちろん詳細も設定できる。`/etc/ino.ini`か、`~/.inorc`を作成して、そこに例えばシリアルのデバイスや、ボーレート、Arduino IDEのディレクトリなども指定できる。(http://inotool.org/quickstart)

`ino serial`コマンドでシリアルもチェックできるわけだが、`picocom`が必須。


実は`ino`は使っていない。`platformio`を使っている。こちらはもっと楽なのでメモを残したいと思う。
c++ builder XE4 > TThread > Suspended()後のStart() > 実行中または一時停止中のスレッドに対してはStartを呼び出せません

```txt.動作確認
C++ Builder XE4
```

TThreadに関して、最近のC++ BuilderではResume()は非推奨になりStart()を使ってくださいとのこと。

しかしながら、以下のコードはStart()のところでエラーが出る。
```
thread1->Suspend();
...
thread1->Start();
```

> エラーメッセージ：実行中または一時停止中のスレッドに対してはStartを呼び出せません。

Start()をResume()に戻すとこのエラーは出なくなる。


以下が関係しそう。
[SO](http://stackoverflow.com/questions/1624071/resuming-suspended-thread-in-delphi-2010)
> "Cannot call start on a running or supsended thread"

上記の細かい部分は読み切れていない。


以下の方法ではResumeに相当する処理ができたが、正しい方法ではないかもしれない。

```
// thread1->Start(); // Error: Cannot call start on a ...
thread1->Suspended = false;
```

非推奨のResume()を使うのとどちらがいいのか悩ましいところではある。

### Suspended = falseあるいはStart
(追記 2018/10/12)

下記に「SuspendedをFalseにする、やStartを使う」という回答がIlyaによりある。
https://stackoverflow.com/questions/1418333/tthread-resume-is-deprecated-in-delphi-2010-what-should-be-used-in-place
Mac で homebrew の bash をログインシェルにする

peco が使いたくて、bash のバージョンを 4 以上にしたくて実施しました。[^1]

[^1]: [bashでもpercolをイイ感じに使う方法 - (ひ)メモ](http://d.hatena.ne.jp/hirose31/20140612/1402559889)

## Homebrew で bash をインストール

```bash
brew update
brew install bash
```

## ログインシェルの変更

`/etc/shells` に追記して、`chsh` 実行

```bash
echo '/usr/local/bin/bash' | sudo tee -a /etc/shells
chsh -s /usr/local/bin/bash
```

端末を再起動して、完了。

## 参考

- [MacのログインシェルをHomebrew等で入れたzshやbashに変更する方法 | Macとかの雑記帳](http://tukaikta.blog135.fc2.com/blog-entry-195.html)
- [Macの環境設定(3) zshを入れる - Qiita](http://qiita.com/nenokido2000/items/763a4af5c161ff5ede68)
- [MacOSX - MacのBashをbrewで怖くないbashにする - Qiita](http://qiita.com/seiiichi_o/items/545572971416fc6d4cf0)
Trello の各カードに期限日を設定して、Google Calendar に同期させる


Trello のカレンダー機能を有効にすると、各カードごとに期限日を設定することができるようになります。それを googleカレンダー に同期して表示させる方法です。

## Trello のカレンダー機能を有効にする

ボードのメニュー → `Power-Ups` → `Calendar` で Enable を選び、カレンダー機能を有効にします。

![001.png](https://qiita-image-store.s3.amazonaws.com/0/45034/3ee3cae5-b8ac-5845-7a74-27f97ec4dc7d.png "001.png")

## カードに期限を設定する

カードの編集時に `Due Date` ボタンから、各タスクの期限日時を設定します。

![002.png](https://qiita-image-store.s3.amazonaws.com/0/45034/ff0ee6f7-7843-cf9a-343b-471f99697481.png "002.png")

期限を設定するとこんな感じ。
期限が迫ったカードは、日付が赤や黄色で表示されます。

![003.png](https://qiita-image-store.s3.amazonaws.com/0/45034/f2bfbb25-f5ed-c910-39eb-03229f58b64f.png "003.png")

## カレンダー表示

ボード上部の `Calendar` ボタンをクリックすると、カードをカレンダー形式で表示させることもできます。

![004.png](https://qiita-image-store.s3.amazonaws.com/0/45034/47011689-42e6-4f42-212c-534f99d7d152.png "004.png")

## iCal 形式の URLを取得

メニュー → `Power-Ups` → `Calendar` の設定アイコンから、iCal 形式のURLを生成することができます。`Your Personal iCalendar Feed` のところです。
これをコピーしておいて、

![005.png](https://qiita-image-store.s3.amazonaws.com/0/45034/b1ab00bf-dcb2-d87a-5950-1ef026cc5bb5.png "005.png")

## googleカレンダーにインポート

googleカレンダーの `他のカレンダー` → `URLで追加` から、さきほどの URL を登録。

![006.png](https://qiita-image-store.s3.amazonaws.com/0/45034/81d5063f-9487-8ed3-2615-e585746eb791.png "006.png")

こんな感じで googleカレンダーに、Trello のカードを表示できるようになりました。

![007.png](https://qiita-image-store.s3.amazonaws.com/0/45034/c3315003-ae20-a5f8-5275-d1168b957573.png "007.png")
Rails jQueryを用いたajax化のやり方

RailsでのajaxをjQueryを用いて実現します。
基本的で分かりやすい削除のajax化を例にしてajax化のやり方を紹介します。


#記事(article)の削除のajax化
下記の記事のゴミ箱アイコンを押すと記事がふわっと消えるようにします。

![スクリーンショット 2015-05-07 12.39.01.png](https://qiita-image-store.s3.amazonaws.com/0/40796/421fd525-fab7-9dd1-d4ca-4ed04dc51dd4.png)

まず、ゴミ箱アイコンのリンクにremote: trueを追加します。railsはこれだけでajaxの通信をしてくれます。

```erb:article.erb
<%= link_to content_tag(:i, '', class: 'fa fa-trash'), article_path(article.id), method: :delete, data: { confirm: "本当に削除してもよろしいですか" }, class: "article_delete", remote: true %>
```

ただし、このままだと記事の削除が実行されてデータベース上から消えるだけで画面上からは更新をかけないと消えてくれません。ここからは、ajaxのresponseを受け取り即座に記事を消えるようにします。
controllerで```render :json```を使いデータをjs側に送ります。

```rb:articles_controller.rb
  def destroy
    writer = Article.find(params[:id])['user_id']
    if @user.id != writer
      redirect_to articles_path, :flash => {:alert => "削除権限がありません。"}
    else
      @article.destroy
      render :json => {:article => @article}
    end
  end
```

ajaxのデータを受け取り、任意の記事を消します。
今回は記事に#item_(id)というidをふっているので、それをfadeOutさせています。

```js:articles.js
(function() {
  $(function() {
    $(document).on('ajax:complete', '.article_delete', function(event, ajax, status) {
      var response;
      response = $.parseJSON(ajax.responseText);
      $('#item_'+response.article.id).fadeOut();
    });
  });
}).call(this);
```

これで完了です。ゴミ箱アイコンを押すと記事がfadeOutしてくれるはずです。

##応用できる
ここでは削除を例にしましたが同様のやり方でいろいろなことをajax化出来そうです。


例えば、commentのcreateのajax化ではformにremote: trueを追加して、コントローラーで部分テンプレートを利用してhtmlを受け取り、あとは同様にajaxで受け取り表示するだけです。

```rb:comments_controller.rb
  def create
    @comments = @article.comments.create(comment_params)
      html = render_to_string partial: 'articles/comment_show', locals: { comment: @comments }
      render :json => {:html => html}
  end
```
Laravel4でDBのテーブルにinsertする方法

下記のようなテーブルがあるとする。

    mysql> desc company_basic_info;
    +---------------+------------------+------+-----+---------+----------------+
    | Field         | Type             | Null | Key | Default | Extra          |
    +---------------+------------------+------+-----+---------+----------------+
    | id            | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
    | name          | varchar(255)     | NO   | UNI | NULL    |                |
    | kana          | varchar(255)     | NO   | UNI | NULL    |                |
    | tel           | varchar(40)      | NO   | UNI | NULL    |                |
    | fax           | varchar(40)      | NO   | UNI | NULL    |                |
    | address       | varchar(255)     | NO   | UNI | NULL    |                |
    | url           | varchar(255)     | NO   | UNI | NULL    |                |
    | establishment | date             | NO   |     | NULL    |                |
    | capital       | int(11)          | NO   |     | NULL    |                |
    +---------------+------------------+------+-----+---------+----------------+
    9 rows in set (0.00 sec)

このテーブルに値をインサートしたい。その場合は、コントローラに下記メソッドを実装する。

    public function store(){
        DB::table('company_basic_info')->insert([
                'name'=>'サンプル株式会社',
                'kana'=>'さんぷるかぶしきがいしゃ',
                'tel'=>'0120-1234-5678',
                'fax'=>'0120-9876-5432',
                'address'=>'東京都品川区',
                'url'=>'http://www.sample.co.jp',
                'establishment'=>'2001-12-24',
                'capital'=> 3000000
        ]);
        return Redirect::to('/');
    }

あとは routes.php にて、下記のように設定して呼び出せばよい。

    Route::get('hoge/', 'HogeController@store');

http://localhost/hoge

にアクセスすると、company_basic_info に値がインサートされる。

    mysql> select * from company_basic_info where id = 5;
    +----+--------------------------+--------------------------------------+----------------+----------------+--------------------+-------------------------+---------------+---------+
    | id | name                     | kana                                 | tel            | fax            | address            | url                     | establishment | capital |
    +----+--------------------------+--------------------------------------+----------------+----------------+--------------------+-------------------------+---------------+---------+
    |  5 | サンプル株式会社         | さんぷるかぶしきがいしゃ             | 0120-1234-5678 | 0120-9876-5432 | 東京都品川区       | http://www.sample.co.jp | 2001-12-24    | 3000000 |
    +----+--------------------------+--------------------------------------+----------------+----------------+--------------------+-------------------------+---------------+---------+
    1 row in set (0.00 sec)
文字列リテラルをfreezeすると共有の定数になる

ruby 2.1 から文字列リテラルをfreezeすると、一つの定数としてオブジェクトが共有されてオブジェクトが無駄に増えないようになっているそうです。(Effective Ruby 参照)
freezeよりも文字列の生成が先なのに、なぜ増えないのか不思議です。
共有されるのは「文字列のみ」のようです。Hashで試したら定数にはなりませんでした。

```ruby
X = "x".freeze
N = 100000

GC.enable
GC.start
GC.disable
N.times { "x" }
ObjectSpace.each_object(String).count {|e| e == X } # => 100002

GC.enable
GC.start
GC.disable
N.times { "x".freeze }
ObjectSpace.each_object(String).count {|e| e == X } # => 2

X.object_id == "x".freeze.object_id # => true

N.times.collect {|e| "x".freeze.object_id }.uniq.count # => 1

RUBY_VERSION                    # => "2.2.2"
```
TypeScript入門

# TypeScript

## 開発環境

Atomのプラグインを使うのが楽

1. Setting -> install ->atom-typescript

2. .tsファイルを保存すると、勝手にコンパイルして.jsファイルを作ってくれる。

3. .jsファイルを読み込む.htmlファイルをブラウザで開いて動作確認

## サンプル


```ts:sample.ts
var str = window.prompt('入力してください');
showStr(str);
function showStr(str: string) {
	alert(str);
}
```

保存すると.jsが生成される(ついでにtsconfig.jsonも生成される)

```js:sample.js
var str = window.prompt('入力してください');
showStr(str);
function showStr(str) {
    alert(str);
}
```

htmlでjsを実行

```html:sample.html
<html>
<head>
	<meta charset="UTF-8">
	<script src="sample.js"></script>
</head>
<body>
	<script type="text/javascript">
		str;
	</script>
</body>
<html>
```
railsめも（HTML以外の出力）

**コントローラからHTML以外を出力する方法について**

以下の出力方法についてのメモです。
1 json形式
2 xml形式

*1 json形式*
```コントローラ内
render :json => オブジェクト
```

*2 xml形式*
```コントローラ内
render :xml => オブジェクト
```
gitWatch > .inl > inline関数だけのファイル

https://github.com/gameplay3d/GamePlay/blob/master/gameplay/src/Vector3.inl

.inlというファイルにinline宣言の関数をまとめているようだ。

.inlという別ファイルにすることについてはいろいろ議論があるようだ。
[SO](http://stackoverflow.com/questions/1208028/significance-of-a-inl-file-in-c)
Rails 多対多テーブルのModelの書き方~お気に入り・フォロー機能を例に~

多対多テーブル Modelの書き方を
・お気に入り機能(comment<->favorite_comment<->user)
・フォロー機能(user<->follow_user<->user)
の2つを例にして紹介する。

#お気に入り機能
ユーザー(users)がコメント(comments)をお気に入りする
##テーブル
・comments
・favoite_comments(中間テーブル)
　-comment_id
　-user_id
・users

##Model

```rb:comment.rb
has_many :favorite_comments
has_many :favo_users, class_name: "User", foreign_key: "user_id", through: :favorite_comments, :source 'user', dependent: :delete_all
```

```rb:user.rb
has_many :favorite_comments
has_many :favo_comments, class_name: "Comment", foreign_key: "comment_id", through: :favorite_comemnts, :source 'user', dependent: :delete_all
```

```rb:favorite_comment.rb
belogns_to :comment
belongs_to :user
```

#フォロー機能
 ユーザー(from_user)がユーザー(to_user)をフォローする
##テーブル
・users
・follow_users(中間テーブル)
-to_user_id
-from_user_id
##Model
```rb:user.rb
has_many :follow_users_of_to_user, class_name: 'FollowUser', foreign_key: 'to_user_id', dependent: :delete_all
has_many :friends_of_to_user, through: :follow_users_to_user, source: 'from_user'

has_many :follow_users_of_from_user, class_name: 'FollowUser', foreign_key: 'from_user_id', dependent: :delete_all
has_many :friends_of_from_user, through: :follow_users_from_user, source: 'to_user'
```

```rb:follow_user.rb
belongs_to :to_user, class_name: 'User', foreign_key: 'to_user_id'
belongs_to :from_user, class_name: 'User', foreign_key: 'from_user_id'
```

#associationのoptionについて
##dependent
今回はdependent: :delete_allを使ったが、
時としてこんなエラーになることがある。

```
Cannot delete or update a parent row: a foreign key constraint fails (`finc_blog_development`.`comments`, CONSTRAINT `fk_rails_35f401eaf6` FOREIGN KEY (`article_id`) REFERENCES `articles` (`id`))
```
user削除->article削除->comment削除と2段階以上の関連があることが問題だった。
2段階以上の関連があるときは:destroyを使わなければならない。
ただし、1段階の関連のときは、処理速度の速いdelete_allのほうが効率がよい。


つまり、
1段階の関連だけなら処理は速いdelete_allで2段階以上の関連ならdestroyを使えばよい。

##through
多対多のモデルで中間テーブルを使うときに登場し、中間テーブルを意識せずに関連データの取得ができるようになる。
has_and_belongs_to_manyを使う方法もあるが、制約が多いのでthroughを使うほうが無難。

##class_name, foreign_key, source
多対多の場合、フォロー機能のようにUserモデルだけでフォローする側、フォローされる側の両方の役割を担う必要があり、その関係を示すために使用している。

##参考
[Railsで多対多のテーブルを実装する](http://b.pyar.bz/blog/2014/10/16/many-to-many-table/)
[同一モデル間で友達関係のような多対多関連をつくる【rails4】](http://www.coma-tech.com/archives/258/)
Haskellの実験メモ一覧

Haskellで気になったことなどを試行錯誤した記事のリストです。新しい実験を行えば随時追加する予定です。

* 2015/12/07 [アローの取っ掛かり](http://qiita.com/7shi/items/9a6e7e3b8e88bafe4174)
* 2015/07/24 [Maybeモナドによる中置記法の処理](http://qiita.com/7shi/items/cda901af6abb732f9c64)
* 2015/04/28 [Parsecをモナド変換子で模倣](http://qiita.com/7shi/items/201f379443079736e18e)
* 2015/04/24 [MaybeとStateを合成](http://qiita.com/7shi/items/12036631dad1979a273b)
* 2015/01/11 [リストとIOUArray](http://qiita.com/7shi/items/1e6b5899db3ab6b6a8fc)
* 2015/01/05 [アンボックス化タプルの挙動を確認（微妙）](http://qiita.com/7shi/items/60f787149673b4d4775f)
* 2014/12/18 [ジェネレーターでリストモナドを模倣してみた](http://qiita.com/7shi/items/8ec339bcddbb6692b738)
* 2014/12/09 [IOモナドを素手で触ってみた](http://qiita.com/7shi/items/0a90d7ba31355e1c73aa)
* 2014/11/28 [再帰をfoldrで書き換えて確認](http://qiita.com/7shi/items/82b1e074a360dd28fcbe)
* 2014/11/21 [IORefとState](http://qiita.com/7shi/items/3722f0a677d6763eb395)
* 2014/11/08 [Haskellで空間を実装してみた](http://qiita.com/7shi/items/0bd828489aa176252fe8)
* 2014/08/25 [Haskellの型クラスとF#のインターフェース](http://qiita.com/7shi/items/cd7f65a898dd5696c73d)
* 2014/08/22 [Haskellで関数のオーバーロード](http://qiita.com/7shi/items/17a1567a635af17fc83f)

あまり意味のないテストがほとんどですが、有用なものは書き直して超入門シリーズに追加するかもしれません。

* 2014/08/20 [Haskell 超入門](http://qiita.com/7shi/items/145f1234f8ec2af923ef)
Golang超基本構文メモ


* [CodinGame](http://www.codingame.com/)で遊んでる時にすぐ頭に浮かばなかった構文をまとめてます.
* import文は省略しています.


## 配列・文字列長
```go
	len(arr)
```

## string->int
```go
	val, _ := strconv.Atoi("100")
```

## string->float
```go
	val, _ := strconv.ParseFloat("1.5", 64)
```

## Upper/Lower
```go
	strings.ToUpper("hoge")
	strings.ToLower("HOGE")
```

## Index/LastIndex
```go
   strings.Index("chicken", "ken")
   strings.LastIndex("hoge.png", ".")
```

## HasPrefix(startsWith)/Suffix(endsWith)
```go
	strings.HasPrefix("aiueo", aiu)
	strings.HasPrefix("aiueo", eo)
```

## Trim
```go
	strings.Trim(val, " ")
```

## 文字列カット(slice)
```go
	str[5:10] // start:end (lengthではない)
	str[5:]
	str[:10]
```

## 文字列split
```go
	arr := strings.Split("a,b,c", ",")
```

## 文字(char/rune)->int
```go
	val := int('Z')
```

## 配列初期化
```go
	arr := make([]string, 99)
```

### Map初期化
```go
	dic := make(map[string]string)
```

## リスト回し
```go
    for _, obj := range list {
    }
```

## ソート
```go
	arr := make([]int, 100)
	//...
	sort.Ints(arr)
```

## Switch
```go
    switch val {
        case 0: 
        case 1: 
        case 2: 
        default: 
    }
```

## 三項演算子

* ない
 
## 可変長引数

```go
func Hoge(args ...int) int {
	piyo := args[0]
```

## struct定義

```go
type KeyVal struct {
	key string
	val string
}

// メソッド定義
func (obj *KeyVal) check(key string) string {
	if obj.key == key {
		return obj.val
	}
	return ""
}

	// 使う時
	var kv KeyVal
	kv.key = "hoge"
	kv.val = "piyo"
	kv.check("hoge")
	
	// もしくはこう
	kv := KeyVal{key: "hoge", val: "piyo"}
```
awsでmoshを使う

必要な事前の設定

#セキュリティーグループ
UDP60000-61000を許可する

#mosh install

```
#yum install mosh
```

#クライアントへのInstall
インストール方法を見て、インストールしてください。

#クライアントからのアクセス方法
MacOSからアクセスするとき

```
$mosh ec2-user@xxx.xxx.xxx.xxx --ssh="/usr/bin/ssh -i ~/.ssh/xxx.pem"
```

xxx.xxx.xxx.xxx IPアドレスを指定
xxx.pem アクセスの秘密鍵を指定
React.js のコード(JSX)をAtomでコードフォーマットする


微妙にハマったので。なんかひどいやり方なのは承知の上なんですが、記録のために残しておきます。

# パッケージの導入

まず、パッケージで React と Atom-beautifyを入れる。

![スクリーンショット 2015-05-07 10.52.16.png](https://qiita-image-store.s3.amazonaws.com/0/17911/ef3c8409-410b-2648-ecfe-a4da448120ca.png "スクリーンショット 2015-05-07 10.52.16.png")

![スクリーンショット 2015-05-07 10.52.48.png](https://qiita-image-store.s3.amazonaws.com/0/17911/0f9e8177-3460-e29e-463d-39f50ab1c978.png "スクリーンショット 2015-05-07 10.52.48.png")

React パッケージを入れると Reformat JSXなるコマンドが追加されるのだが、手元ではうまく機能しなかった。詳細は不明。

# 設定を編集し、language名を "JavaScript(JSX)" から"JSX"にする

React パッケージで提供される language 名が JavaScript(JSX)だったために、Atom-Beautify のフォーマットが失敗する。・・・というように読めるエラーメッセージが出る。

![スクリーンショット 2015-05-07 11.16.12.png](https://qiita-image-store.s3.amazonaws.com/0/17911/a3e08b78-95c3-31af-5677-91a7d1d1f4ab.png "スクリーンショット 2015-05-07 11.16.12.png")

なんか根本的な間違いがあるのかもしれない。が、Atom周りのことはよく知らないので調べるのは後回しにする。

コードを読むとどうも単純に language 名をキーとして探しているようなので、React パッケージが提供している language 名の方を修正してしまう。

設定ファイルを直接開き、、、

![スクリーンショット 2015-05-07 10.55.46.png](https://qiita-image-store.s3.amazonaws.com/0/17911/8bd2b345-5ffa-239d-9a6d-406f09b93b42.png "スクリーンショット 2015-05-07 10.55.46.png")

これを

![スクリーンショット 2015-05-07 10.56.19.png](https://qiita-image-store.s3.amazonaws.com/0/17911/c07378eb-45ee-8eae-b10a-7c847bb427f7.png "スクリーンショット 2015-05-07 10.56.19.png")

こうじゃ。なんか他の箇所でも JavaScript(JSX) って表記残ってるけど動作に支障がなさそうだったので目を瞑る。設定ファイルを編集したのでAtomを再起動しよう。

# Beautify !!!

これで、Alt + Ctl + B でコードフォーマットが .jsx ファイルに実行できるようになった。

![スクリーンショット 2015-05-07 11.20.15.png](https://qiita-image-store.s3.amazonaws.com/0/17911/f999e756-cfd3-51be-a6a1-696194162311.png "スクリーンショット 2015-05-07 11.20.15.png")



こんな風なのが、

![スクリーンショット 2015-05-07 10.58.46.png](https://qiita-image-store.s3.amazonaws.com/0/17911/10ce2292-f285-1e28-64db-352f98cc6f97.png "スクリーンショット 2015-05-07 10.58.46.png")

こうなるよ!!!

実は React.js を学習していて一番ストレッシーだったのが Vim のシンプルなインデントルールだとうまく整形されなくて畜生ってなってたことでした。（Vimについてはプラグイン入れたりしないことにしているのです）　まあ食わず嫌いだったようで、評判通り Atom いいですねー。デフォルトで Vimモードあるし。

React のサンプルコードは以下から借りました。

https://html5experts.jp/hokaccha/13301/
IPアドレスの部分に国名、国コードを挿入するツール

#できること

ログ等のテキストのIPv4アドレスの部分に
国名、国コードを挿入できます。

#使うもの

下記URLで公開しているiptoccコマンドを利用します。

[ 解説 ]
http://qiita.com/chocolatampcoffee/items/9887c5ee3a528ba43720

[ 本体 ]
https://github.com/INC-i/IPStaff

※iptoccコマンドの動作には、同梱のipstaff.pyおよび、同梱の
　makerirdbコマンドから作成されたデータベース(rirdb)が必要です。

#使い方

##1
コマンド1 | ./iptocc

##2
iptocc IPv4アドレス

#1の具体例

 # cat /var/log/messages | egrep "Dropped Packet" | egrep -o "SRC=[^ ]*" | head -10
SRC=85.25.43.94
SRC=74.42.63.123
SRC=74.42.63.123
SRC=27.118.26.131
SRC=66.240.192.138
SRC=27.118.26.131
SRC=14.157.226.199
SRC=14.157.226.199
SRC=14.157.226.199
SRC=216.218.206.121

上記の出力をiptoccコマンドに渡すと下記のようになります。

 # cat /var/log/messages | egrep "Dropped Packet" | egrep -o "SRC=[^ ]*" | head -10 | ./iptocc
SRC=85.25.43.94(DE:Germany)
SRC=74.42.63.123(US:United States)
SRC=74.42.63.123(US:United States)
SRC=27.118.26.131(VN:Viet Nam)
SRC=66.240.192.138(US:United States)
SRC=27.118.26.131(VN:Viet Nam)
SRC=14.157.226.199(CN:China)
SRC=14.157.226.199(CN:China)
SRC=14.157.226.199(CN:China)
SRC=216.218.206.121(US:United States)

-j オプションをつけると国名が日本語になります。

 # cat /var/log/messages | egrep "Dropped Packet" | egrep -o "SRC=[^ ]*" | head -10 | ./iptocc -j
SRC=85.25.43.94(DE:ドイツ)
SRC=74.42.63.123(US:アメリカ合衆国)
SRC=74.42.63.123(US:アメリカ合衆国)
SRC=27.118.26.131(VN:ベトナム)
SRC=66.240.192.138(US:アメリカ合衆国)
SRC=27.118.26.131(VN:ベトナム)
SRC=14.157.226.199(CN:中華人民共和国|中国)
SRC=14.157.226.199(CN:中華人民共和国|中国)
SRC=14.157.226.199(CN:中華人民共和国|中国)
SRC=216.218.206.121(US:アメリカ合衆国)

#2の具体例

 # ./iptocc 8.8.8.8
IP: 8.8.8.8
CountryCode: US
Country: United States

 # ./iptocc -j 8.8.8.8
IP: 8.8.8.8
CountryCode: US
Country: アメリカ合衆国
RedisのCluster調査


## はじめに

[Redis cluster tutorial](http://redis.io/topics/cluster-tutorial)を参考に、RedisのCluster環境を構築するための調査をする。
このページの[creating-and-using-a-redis-cluster](## はじめに
)で紹介されている構築手順は2つある。

* 手動で構築する方法
* スクリプトで構築する方法

前者は手間がかかるが、Cluster構築の手順を学ぶのに良い。後者は、お手軽に構築できるので、すぐに動作確認したい人には良い。

## 要約

### Redis cluster tutorial

* [Redis Cluster 101](http://redis.io/topics/cluster-tutorial#redis-cluster-101)
	* Redis Clusterは、データが複数のノードに跨がって自動的に分割されている状況においても、インストールを実行する方法を提供する。
	* 
* [Redis Cluster TCP ports](http://redis.io/topics/cluster-tutorial#redis-cluster-tcp-ports)
* [Redis Cluster data sharding](http://redis.io/topics/cluster-tutorial#redis-cluster-data-sharding)
* [Redis Cluster master-slave model](http://redis.io/topics/cluster-tutorial#redis-cluster-master-slave-model)
* [Redis Cluster consistency guarantees](http://redis.io/topics/cluster-tutorial#redis-cluster-consistency-guarantees)

### Redis Cluster configuration parameters

### Creating and using a Redis Cluster

* [Creating the cluster](http://redis.io/topics/cluster-tutorial#creating-the-cluster)
* [Creating a Redis Cluster using the create-cluster script](http://redis.io/topics/cluster-tutorial#creating-a-redis-cluster-using-the-create-cluster-script)
* [Playing with the cluster](http://redis.io/topics/cluster-tutorial#playing-with-the-cluster)

## 調査環境

* Ubuntu 14.04
[Windows] ソース:Schannel、イベントID:36888のエラーまとめ

IISでWebサーバを運用しているときのお話です。

# :fearful:  イベントID:36888エラーがしょっちゅう記録される

IISでWebサーバを運用していると、次のようなエラーがしょっちゅう記録されます。

> Message:  次の致命的な警告が生成されました: 40。内部エラーの状態は 1205 です。

# :anguished: どうして？？？

これは、httpsポートにオイタな接続をしようとしていることが原因なのだそうです。

https://support.microsoft.com/ja-jp/kb/2904855 より
> Schannel ID: 36888 (警告10, 内部エラー 1203) エラーについては、SSL/TLS で利用されるポート (443/tcp) に対して、SSL/TLS 以外の目的で通信を受けた場合に記録されるイベントです。

# :pensive: 無視してよいらしい

サーバー側が原因ではないので無視してよいエラーだそうです。

# :grimacing: それでも気になる

SSL的などんな具合の悪いことがあったかは、メッセージ『次の致命的な警告が生成されました: **40**』の数字部分で判別できます。この数字は[RFC2246](https://www.ietf.org/rfc/rfc2246.txt) 付録A.3 Alert Messageにまとまっているそうです。

以下にRFC2246から抜粋します。

|警告レベル|内容|
|:---|:--|
|0|close_notify|
|10|unexpected_message|
|20|bad_record_mac|
|21|decryption_failed|
|22|record_overflow|
|30|decompression_failure|
|40|handshake_failure|
|42|bad_certificate|
|43|unsupported_certificate|
|44|certificate_revoked|
|45|certificate_expired|
|46|certificate_unknown|
|47|illegal_parameter|
|48|unknown_ca|
|49|access_denied|
|50|decode_error|
|51|decrypt_error|
|60|export_restriction|
|70|protocol_version|
|71|insufficient_security|
|80|internal_error|
|90|user_canceled|
|100|no_renegotiation|

# イベントID:36874も？

警告レベル40の場合は、イベントID:36874も一緒に記録されるかもです。

# :nose: くさいにおいは元から断たなきゃダメ！？

こんな接続をしてくるクライアントはファイアウォールでアクセス拒否したいですよね。

けど、クライアントのIPアドレスを調べるにはパケットキャプチャしないといけないそうです。 :-1: :-1: :-1: :-1: :-1: 

他にいい方法がないか探索中です。
ssh公開鍵認証でログインできなくなる

いきなり以下のようなエラーが出ました。


```
[root@entaku19890818 /]# tail -f /var/log/secure 
 Authentication refused: bad ownership or modes for file /***/.ssh/authorized_keys
```

調べてみると、ホームディレクトリのパーミッションが所有者以外の場合に起こってしまう現象のようです。
なので、chmodでパーミッションを変更しOK。
気軽に変えてはいけないし、作業ディレクトリは別にすべきかなー

```
chmod -R 755 /****/        
```
Android WearでパーミッションにREAD_LOGSが入っているとインストール時にWear側にインストールされない

ちょっと前にはまった。


Android wearのアプリをパッケージ化して配布する時の注意点として、以下のようなものがある。

- https://developer.android.com/training/wearables/apps/packaging.html
- http://qiita.com/lamrongol/items/4076e2e8e5dd909c9ce8


今回、上記の部分は何度も確認したにも関わらず、wearable側にアプリがインストールされない状態だった。。。


handheld側にて、出ているログをみていると、


```
W/PackageManager(503): Not granting permission android.permission.READ_LOGS to package com.mapyo.sample
```

こういう警告が出ていた。
READ_LOGSのパーミッションを外すと普通にインストール出来た。

ログはちゃんと見ましょうという事です。はう〜。
C#におけるデリゲートの記法の進化、クエリ式について


以下の記事がわかりやすかったので勉強がてらコードを書いてみた
[【LINQの前に】ラムダ式？デリゲート？Func<T, TResult>？な人へのまとめ【知ってほしい】](http://qiita.com/RyotaMurohoshi/items/740151bd772889cf07de)

# 歴史をすっとばして紹介すると
## このコードが

```csharp

using System;
using System.Collections.Generic;

namespace DelegateSamples
{
	class MainClass
	{
		//デリゲートの定義
		public delegate bool predicate(string str);

		//デリゲートの参照先メソッド
		public static bool IsLengthLessThan5(string str)
		{
			return str.Length < 5;
		}

		//アイテムを判定するメソッド
		private static int CountList(List<string> names,predicate pre)
		{
			int count = 0;

			foreach (string item in names)
			{
				if (pre(item)) {
					// 真ならカウンタをインクリメント
					count++;
				}
			}
			return count;
		}

		public static void Main (string[] args)
		{
			//リストの定義
			List<string> names = new List<string>
			{
				"Taro",
				"Jiro",
				"Saburo",
				"Umeko",
				"Takeko",
				"Matsuko",
			};

			//デリゲートの型のメソッドを変数化する
			//これにより引数にメソッドを渡す事ができる
			predicate IsLengthCheck = MainClass.IsLengthLessThan5;
			int count = CountList(names, IsLengthCheck);
			Console.WriteLine(count.ToString());
		}
	}
}

```

## こうなる

```csharp

using System;
using System.Collections.Generic;
using System.Linq;

namespace DelegateTest04
{
	class MainClass
	{
		public static void Main (string[] args)
		{
			List<string> names = new List<string>
			{
				"Taro",
				"Jiro",
				"Saburo",
				"Umeko",
				"Takeko",
				"Matsuko",
			};

			Console.WriteLine(names.Count((x) => x.Length < 5).ToString());
		}
	}
}

```

# 短っ！！
リンク先の記事は「LINQの前に」と断っているためLINQの事は書いていませんがLINQを理解する上で重要な事が丁寧に書いてあります。

コメント適当な感じですが、一応サンプルコードも置きますので学習の一助になれば幸いです

* [Delegate時代](https://dl.dropboxusercontent.com/u/6955/DelegateTest/DelegateTest01.zip)
* [Genericsが使える時代](https://dl.dropboxusercontent.com/u/6955/DelegateTest/DelegateTest02.zip)
* [匿名関数とGnericsを組み合わせ](https://dl.dropboxusercontent.com/u/6955/DelegateTest/DelegateTest03.zip)
* [LINQを活用](https://dl.dropboxusercontent.com/u/6955/DelegateTest/DelegateTest04.zip)

# 疑問
Multicastどこいってもうたんや...
匿名メソッドでも+=できるけど戻り値は最後のメソッドだけ帰ってくる

このあたりかな、そのうち書こう

* [マルチキャストデリゲートのそれぞれの返り値を知る方法](http://kurusugawa.jp/2007/05/29/%E3%83%9E%E3%83%AB%E3%83%81%E3%82%AD%E3%83%A3%E3%82%B9%E3%83%88%E3%83%87%E3%83%AA%E3%82%B2%E3%83%BC%E3%83%88%E3%81%AE%E3%81%9D%E3%82%8C%E3%81%9E%E3%82%8C%E3%81%AE%E8%BF%94%E3%82%8A%E5%80%A4%E3%82%92/)
* [[C#] マルチキャストデリゲートのそれぞれの戻り値を得る方法](http://d.hatena.ne.jp/siokoshou/20070410#p1)
WebGLの環境毎のスペックを知る

PixiJSを使っていて、スプライトシートの最大サイズが4096pxを超えると、Android Chromeで
正しく表示されない問題にぶち当たりました。

いろいろ調べた結果、環境によって扱えるテクスチャの最大サイズがあることを知りました。
その中で、WebGLの環境ごとのスペックを大まかに知ることができるサイトを見つけたので、ここにメモしておきます。

http://webglstats.com/

今回はテクスチャのサイズを調査しました。
MAX_TEXTURE_SIZEの項目がそれに該当します。

下記の画像の通り、Android+Chromeの場合、ほとんど4096pxがMAXであることがわかります。

![MAX_TEXTURE_SIZE](https://qiita-image-store.s3.amazonaws.com/0/75209/c4b3db27-e063-a4a3-3b22-9231f538ccf5.png)
Socket.IOでメッセージが届いたことを確認する

WebSocket使ってると、クライアントからサーバーにメッセージ送って、届いたのがはっきりしてから何かしたいことがあったりします。WebSocketの仕様その物にはそういう機能は無いようですが、[Socket.IO][]にはそういう機能があったのでこれが使えました。
（低レベルの話を期待していた方、済みません）

ドキュメントに書いてあることそのままではあるんですが：[Sending and getting data (acknowledgements)][ackdoc]

Socket.IOのacknowledgements機能
------------------------------

`emit`するクライアント側のコード、サーバー側の`on`で待ち受けるブロックのコード、のそれぞれでコールバック関数を登録することで、クライアントからのメッセージが届いた時の処理を書けます。処理を書けるということは、届いたことが確認できるということです。

```javascript:client.js
// クライアント側
var ws = io();
// 色々初期化処理
ws.emit("post", data, function onack(response) {
  // データが届いたことを確認できた
  doSomethingWith(response);
});
```

```javascript:server.js
// サーバー側
// 色々初期化処理
var io = require("socket.io")(server);
io.on("connection", function(user) {
  user.on("post", function(data, ack) {
    // dataをDBに保存したりする
    // ユニークキーが割り振られたりする
    data.id = dbRecord.id;
    ack(data);// データが届いたことの確認、兼、追加データの通知
  });
});
```

Promiseにしてみる
----------------

これだけで終わってもアレなので、Promsieにしてみるとこんな感じでしょうか。

```javascript:client-with-promise.js
// クライアント側
var ws = io();
// 色々初期化処理
post(data).then(function(response) {
  doSomethingWith(response);
});

function post(data) {
  return new Promise(function(resolve, reject) {
    ws.emit("post", data, resolve);
  });
}
```

ストリームにしてみる
---------------
これだけで終わってもアレなので、[WAHTWG Streams][streams]のストリームにしてみるとこんな感じでしょうか。

```javascript:client-with-streams.js
// クライアント側
var ws = io();
// 色々初期設定
userActionStream // 「保存ボタンを押す」とかのアクション
  .pipeThrough(actionToData()) // DOMツリーからデータ集めて整形
  .pipeThrough(post(ws)) // ここの話なので下に実装置いときます
  .pipeTo(soSomethingWithResponse());

function post(ws) {
  return new TransformStream({
    transform: function(data, enqueue, done) {
      ws.emit("post", data, function ack(response) {
        enqueue(response);
        done();
      });
    }
  });
}
```
（2015年5月3日版の仕様と[リファレンス実装][streamsrefimpl]を使っています）

[Socket.IO]: http://socket.io/
[ackdoc]: http://socket.io/docs/#sending-and-getting-data-(acknowledgements)
[streams]: https://streams.spec.whatwg.org/
[streamsrefimpl]: https://github.com/whatwg/streams/tree/master/reference-implementation
gem install rmagick に失敗したときの対処

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    /opt/rubies/ruby-2.1.0/bin/ruby -r ./siteconf20150506-27602-1f5ibbz.rb extconf.rb
checking for Ruby version >= 1.8.5... yes
checking for gcc... yes
checking for Magick-config... no
checking for pkg-config... yes
checking for ImageMagick version >= 6.4.9... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/opt/rubies/ruby-2.1.0/bin/ruby
extconf.rb:154:in ``': No such file or directory - convert (Errno::ENOENT)
	from extconf.rb:154:in `block in <main>'
	from /opt/rubies/ruby-2.1.0/lib/ruby/2.1.0/mkmf.rb:918:in `block in checking_for'
	from /opt/rubies/ruby-2.1.0/lib/ruby/2.1.0/mkmf.rb:351:in `block (2 levels) in postpone'
	from /opt/rubies/ruby-2.1.0/lib/ruby/2.1.0/mkmf.rb:321:in `open'
	from /opt/rubies/ruby-2.1.0/lib/ruby/2.1.0/mkmf.rb:351:in `block in postpone'
	from /opt/rubies/ruby-2.1.0/lib/ruby/2.1.0/mkmf.rb:321:in `open'
	from /opt/rubies/ruby-2.1.0/lib/ruby/2.1.0/mkmf.rb:347:in `postpone'
	from /opt/rubies/ruby-2.1.0/lib/ruby/2.1.0/mkmf.rb:917:in `checking_for'
	from extconf.rb:151:in `<main>'

extconf failed, exit code 1

Gem files will remain installed in /home/vagrant/.gem/ruby/2.1.0/gems/rmagick-2.13.4 for inspection.
Results logged to /home/vagrant/.gem/ruby/2.1.0/extensions/x86_64-linux/2.1.0-static/rmagick-2.13.4/gem_make.out
An error occurred while installing rmagick (2.13.4), and Bundler cannot continue.
Make sure that `gem install rmagick -v '2.13.4'` succeeds before bundling.
 



```
yum install ImageMagick-devel
```
で解決。
技術英語 > Safety First and Production Second

何を一番に、次に何を優先するか言う時に使う。

Debugging First and Meeting the deadline Second.
「デバッグが一番、納期に合わせるのは次だ」
というのは余程のことがない限りなさそう。

Robustness First and Responsiveness Second.
「頑健性が一番、次に応答性」
X/Open System Interface (XSI) > POSIX規格の拡張である...

引用: C/C++ セキュアコーディング 第2版 by Robert C. Seacordら

> POSIX規格の拡張であるX/OpenSystem Interface(XSI)はこれらの型が存在することを要求するが、型を使った計算が意味のある結果になることは要求していない。
secureCoding > 書式文字列中の長さ修飾子(the length modifier) j > ...がintmax_t型(uintmax_t型)を持つ引数に適用されることを表す

引用: C/C++ セキュアコーディング 第2版 by Robert C. Seacordら

> 書式文字列中の長さ修飾子 jは、続く変換指定子 (d, i, o, u, x, X, n)がintmax_t型もしくはuintmax_t型を持つ引数に適用されることを表す。

```
mytypedef_t x;
printf("%ju", (uintmax_t) x);
```

「長さ修飾子」は「The length modifier」として以下に説明がある。
http://linux.die.net/man/3/printf
secureCoding > PTRDIFF_MINの最小値 -65535 | PTRDIFF_MAXの最小値 +65535

引用: C/C++ セキュアコーディング 第2版 by Robert C. Seacordら

> ptrdiff_tの下限と上限はそれぞれPTRDIFF_MINとPTRDIFF_MAXとして定義される。C言語規格は、これらの値の最小値を次の通り定めている。

「最小値を」という記載があるので、実際の値はもっと大きな値が定義されているのかもしれない。

たとえば[QNX](http://www.qnx.com/developers/docs/6.4.1/dinkum_en/c99/stdint.html?lang=jp)においては以下のように定義されている。

```
#define PTRDIFF_MIN  INT32_MIN
#define PTRDIFF_MAX  INT32_MAX
```
RSpecのsleep処理について


RSpecのテスト内容を見てみるとsleepが大量に使っている場合があります。
これがどうにかならないのか色々と調べてみた。


## どういう時にsleepが使われているか？

使用目的としては画面遷移が完了するまでの待機やAjaxなどjavascriptの処理を待つに使われるのがほとんどの模様

## 対策

遷移後の画面にあるべき要素を検索する（find）という処理を入れる。
findは要素が見つかるまで（default_wait_timeの間）ループ処理が入るため、sleepを使うよりスマートと思われる。

他にもhas_◯◯（has_xpath,has_cssなど）でもfindと同じようにループ処理が入る。
findとは挙動が違い、Ajaxの後にsleepを用いている際にはhas_◯◯を使うべきである。

https://github.com/jnicklas/capybara#asynchronous-javascript-ajax-and-friends

__2015/07/03 10:18 追記：__
have_xxxでも以下のようにexpectを用いる場合にはループ処理が入る。

````test_spec.rb
expect(page).to have_xxx "Foo bar"
````

## まとめ

日本語の情報のほとんどがsleepやwaitを使えといった書き方をしているが、そんなことはない。
Shapefile を tippecanoe でベクトルタイル変換して tessera 経由でブラウザ確認するまで

STEP 1: Shapefile を GeoJSON ファイルに変換する
===
GDAL/OGR は手元の OS X では Java6 依存性があるように表示されてしまうので、ここは迷うことなく GeoRuby を使って Ruby で処理する。ストリームを意識しやすいので良い。次の togeojson.rb を使って

```bash
$ ruby togeojson.rb | gzip -9 > some.geojson.gz
```

等とする。tippecanoe はストリームが切れていても終末の処理を適当にしてくれるので、ファイルの完成を待たずに次のステップに進んでも良い。

スクリプトは次のとおり。属性の文字コードを変換すべきかどうかは、Shapefile と GeoRuby の細かな特性に依存すると思うので、手元のデータ・手元の環境に合わせて調整するのがよい。

```ruby
require 'rubygems'
require 'find'
require 'json'
require 'georuby'
require 'geo_ruby/shp'
#require 'geo_ruby/geojson'

def process(shp_path)
  $stderr.print "processing #{shp_path}.\n"
  geojson_path = shp_path.sub(/shp$/, 'geojson')
  s = []
  GeoRuby::Shp4r::ShpFile.open(shp_path) {|shp|
    shp.each {|r|
      r.data.attributes.each{|k,v|
        if v.class == String
          # 属性の文字コードを Shift_JIS から UTF-8 に変換する
          r.data.attributes[k] = v.encode('UTF-8', 'CP932')
        end
      }
      if $first
        $first = false
      else
        print ",\n"
      end
      r.geometry.with_m = false
      r.geometry.with_z = false
      print JSON.dump({
        "type" => "Feature",
        "geometry" => r.geometry,
        "properties" => r.data.attributes
      })
    }
  }
end

$first = true
print <<-EOS
{"type": "FeatureCollection", "features": [
EOS
count = 0
Find.find('.') {|path|
  next unless /shp$/.match path
  next unless /RdCL/.match path # "RdCL" がファイル名に入っている場合のみ処理
  next if /(NNFPt|NRPt|CSPt|PFPt|DEM)/.match path # 属性・分量の問題で後回し
  count += 1
  process(path)
  #break if count == 100
}
print <<-EOS
]}
EOS
```

Tippecanoe で GeoJSON をベクトルタイルに変換する
===
https://github.com/mapbox/tippecanoe
にある tippecanoe をインストールする。

```bash
$ brew install tippecanoe
```

手元にあるのは中縮尺・大縮尺のデータなので、とりあえず閲覧するために z=15〜18 でベクトルタイルを作成したりしている。（これは手元にあるデータによって変わってくる。）

```bash
$ gzcat some.geojson.gz | tippecanoe -z 18 -Z 15 -t . some.mbtiles
```

ここで、 -t . とするのは作業ディレクトリをカレントディレクトリにするため。たいていの Shapefile ベースのデータでは問題なく処理してくれるのが tessera のありがたいところだけれども、処理の特に後段のところで、ややテンポラリを多く使う場合がある。私は残り容量の少ない MacBook Air (11-inch, mid 2011) で処理をしているので、データが置かれているカレントディレクトリ（安い USB HDD）にテンポラリを置くことにしている。それでも、劇的に速度が低下するという感じはない。

tessera でベクトルタイルを閲覧してみる
===

ここから先は node.js による処理になる。一部、node のバージョンに依存するライブラリもあるので、nodebrew で node / npm を導入したほうが良いかもしれない。

ソフトウェア導入についてこれから説明するが、記憶によるところなので、依存性処理によって不要になるコマンドが入っているかもしれない。それぞれのモジュールについての覚書を兼ねている。

```bash
$ npm install mbtiles tilelive tilelive-mapnik
```
↑このあたりは必要だと思うが、後段の tessera 導入で自動的にインストールされるかもしれない。

```bash
$ npm install tessera
```
サーバとして動いてくれる tessera を導入する。

```bash
$ npm install tilelive-vector tilelive-xray
```
今回、ベクトルタイルのデータを閲覧するので、上記のモジュールが必要になる。特に、tilelive-xray が重要。スタイルをつけていないデータを上手く表示してくれるための機能らしく、tilelive-xray を導入していないと、tessera がエラーメッセージを出して終了してしまう。

また、導入すべき node モジュールが足りないと、tessera でエラーが出る。次のようにしてモジュールを一覧することにより、推理して頂くのがよい。

```bash
$ npm find tilelive
```

実際にサーバを動かすには、次のようにする

```bash
$ tessera mbtiles://./some.mbtiles
```
これで、localhost にサーバが立ち上がるのでブラウザで Leaflet ベースのウェブ地図として最低限閲覧することができる。

ただし、この方法で tessera から送信されるのは、tessera が（たぶんオンデマンドでレンダリングした）PNGタイルである。まさに、Mapbox Studio 的なアプローチで、ぎりぎりサーバサイドレンダリングを実施している。クライアントサイドレンダリングを試してみる方法は、後ほど記載することにしたい。
Genymotion で Virtual Device を Start しようとしても何も起こらない場合

Genymotion で Virtual Device を起動しようと Start ボタンを押してみても、何も起こらない。
起動もしないしエラーメッセージも出ないので、何が悪いのかわからず困ってしまった。

## 環境
- Mac OS X 10.10.3
- Genymotion 2.4.0

## 吐かぬなら吐かせてみよう動作ログ

ターミナルで Genymotion.app 内のバイナリを直接実行し、動作中のログを確認できるようにしてみた。

```
% cd /Applications/Genymotion.app/Contents/MacOS
% ./genymotion
```

この状態で、 Virtual Device を選択し Start ボタンを押してみる。すると...

```
% ./genymotion
Logging activities to file: /Users/user/.Genymobile/genymotion.log
The file /Applications/Genymotion.app/Contents/MacOS/Player.app does not exist.
```

どうやら `Player.app` が存在しないらしい。確認してみよう。

```
% cd /Applications/Genymotion.app/Contents/MacOS
% ls
crypto/          device-upgrade*  genymotion*      genymotion-tool* player@
player.app/      plugins/         tools/           translations/
```

`Player.app` ではなく `player.app` になっている......!

## シンボリックリンクを張ってみよう

Genymotion が要求する名前でシンボリックを張ってみた。

```
$ ln -s player.app Player.app
```

この状態で、再び Virtual Device の Start を試してみたところ、起動できるようになったようです！


OS X をインストールする際、ファイルシステムのフォーマット選択で「大文字/小文字を区別 (Case-sensitive)」にしたため、`player.app` の名前の違いで起動しなくなってしまったのではないかと思われます。（検証用の環境が他に無いため、推測になってしまいますが。）