OmniAICreator/Qiita-1.07M huggingface dataset:
CygwinからWin32版GVimを起動する

この記事は、[Vim Advent Calendar 2014](http://qiita.com/advent-calendar/2014/vim)の27日目の記事ではありません。（たぶん）

Windowsで使えるVimにはいくつかの種類があります。例えば以下のようなものがあります。

* Win32(or Win64)版のVim/GVim
* Cygwin版のVim/GVim
* MSYSのVim

それぞれの環境から別の環境のVimを起動するのはトラブルの元ですが、それでも別環境のVimを起動したい場合もあるでしょう。
ここでは、CygwinからWin32版のGVimを起動する場合の注意点を説明します。

# 環境変数

CygwinからWin32 GVimを起動する場合に一番問題になるのが環境変数です。Vimに関連する環境変数には以下のようなものがあります。

* `HOME`  
`.vimrc`や`.gvimrc`などの設定ファイルを探す際に使用されます。Cygwinでは、`/home/<user>`が設定されています。Win32では通常は設定不要で、設定されていなければ`C:\Users\<user>`が使われます。（Win32のホームディレクトリを、Cygwinのホームディレクトリを指すようにすることで設定ファイルを共有することも出来ますが、おすすめしません。）
* `SHELL`  
Vimから外部コマンドを実行する際に使用されるシェルを指定します。Cygwinでは、`/bin/bash`等が設定されています。Win32では通常は設定不要で、設定されていなければ`cmd.exe`が使われます。
* `PATH`  
Vimから外部コマンドを実行する際に使われます。Cygwin内部では、通常の`PATH`の先頭に`/usr/local/bin:/usr/bin`などが追加されています。元の環境変数は`ORIGINAL_PATH`に保存されています。Win32 GVimからCygwinのコマンドを実行する必要がなければ、元の環境変数を復元した方がよいでしょう。
* `TMP`, `TEMP`  
一時ディレクトリの場所です。Cygwinでは、`/tmp` (=`C:\cygwin\tmp`)が設定されています。Win32では、`C:\Users\<user>\AppData\Local\Temp`が指定されています。一時ディレクトリに過ぎないので、大抵はどのディレクトリでも問題ないはずですが、外部コマンドによっては復元しておいた方がよいかもしれません。

以上を踏まえて、`.bashrc`等に以下のようなエイリアスを設定しておくとよいでしょう。

```sh
alias gvim='HOME= SHELL= PATH=$ORIGINAL_PATH gvim'
```

`TMP`と`TEMP`も復元する場合は以下のようにするとよいでしょう。

```sh
alias gvim='HOME= SHELL= PATH=$ORIGINAL_PATH TMP=$LOCALAPPDATA\\Temp TEMP=$TMP gvim'
```
Win32版GVimにパスが通っていない場合は、末尾の`gvim`を`/cygwin/c/vim/gvim.exe`などのようにフルパスで指定してください。

これで、Cygwinからは、

```sh
gvim <filename> &
```
でWin32版GVimが起動できます。


# パス形式

CygwinとWin32ではパスの形式が異なっています。前述の設定でWin32版GVimを起動する場合、ファイルのパスはWin32形式（あるいはWin32形式の```\```を`/`に置き換えた形式）で指定する必要があります。
ファイルを相対パスで指定する場合には、Cygwin形式とWin32形式の違いを意識する必要はさほどありませんが、絶対パスで指定する場合には注意が必要です。（また、Cygwin形式のsymlinkについても注意する必要があります。）

## 自動変換（参考）

Cygwinの`cygpath`コマンドを利用すれば、パスの形式を相互に変換することが出来ます。例えば、

```bash
function gvimhelper() {
  HOME= SHELL= PATH=$ORIGINAL_PATH gvim $(cygpath -aw "$@")
}
alias gvim=gvimhelper
```

のような設定を行えば、パスを自動的にWin32形式に変換してGVimを起動することが出来ます。しかし、この設定の場合、GVimにオプションを渡すことが出来ないという問題があります。まじめに対処するには、引数を一つ一つチェックし、オプションでなければ`cygpath`で変換するという処理が必要ですが、ここでは割愛します。

* [* Cygwin - Windows の gVim を使う方法！ - mk-mode BLOG](http://www.mk-mode.com/octopress/2011/12/18/18002054/ "* Cygwin - Windows の gVim を使う方法！ - mk-mode BLOG")
* [Cygwinのbashからエクスプローラや外部のGVimを起動するエイリアスの設定 - phithonの日記](http://d.hatena.ne.jp/phithon/20140112/launch_gvim_and_explorer_on_cygwin_bash_shell "Cygwinのbashからエクスプローラや外部のGVimを起動するエイリアスの設定 - phithonの日記")
* [cygwin環境からwin32のgvimを使う: ボンクラ技術者の備忘ノート](http://bonkura-note.cocolog-nifty.com/blog/2014/06/cygwinwin32gvim.html "cygwin環境からwin32のgvimを使う: ボンクラ技術者の備忘ノート") -- がんばって引数を一つ一つチェックしているようです。
* その他、[cygwin gvim で検索](https://www.google.co.jp/search?q=cygwin+gvim&ie=utf-8&oe=utf-8&hl=ja)するといろいろ見つかります。

# まとめ

CygwinからWin32版GVimを起動する際の注意点を述べましたが、GVimに限らず、他のWin32アプリを実行する際にも参考になるでしょう。
[Android] データの永続化領域について -getFilesDir() vs getExternalFilesDirs()-（アプリ内で取得した画像の置き場所に迷ったので）


アプリ内でダウンロードした画像や動画はどこに置いたらいんだっけ、というのが自分の中で割りと曖昧だったので調べました。
似たような記事はいろいろありますが、自分の言葉でまとめておきたかったので備忘録的に。

Androidではデータの永続化領域としていくつかの場所が用意されている。
大きく分けると、「アプリ内のデータ領域」と「外部ストレージ」があると思います。

## アプリ内データ領域


### Context.getCacheDir()
ex) `/data/data/{パッケージ名}/cache`
これで得られるディレクトリ以下のファイルはあくまでキャッシュ用。容量が足りなくなった時に削除可能性がある。また、Androidの設定画面の`Clear Cache`でも削除される。


### Context.getFilesDir()
ex) `/data/data/{パッケージ名}/files`
アプリ内データの永続化領域。アプリのアンインストール時にここのファイル達は失われる。


## 外部ストレージ領域
`getExternalFilesDirs()`のようにExternalという言葉が使われているが、外部といっても必ずしもSDカードのようなものではない。端末内蔵のストレージの場合もあればSDカードのように取り外し可能なものある。つまりアプリから見て外部というような意味合いかと。
公式レファレンスにも同様のことが書かれており、アプリケーション間で共有しているストレージ領域だとのこと。
逆に、端末内蔵ストレージかSDカードかといったような区別は特にしていない模様。
基本的に外部ストレージを使うためには現在そこへアクセス可能かを確認する必要がある。内蔵ストレージが端末にマウントされていなかったり、SDカードが外されている場合には当然そこへアクセスすることはできない。
http://developer.android.com/reference/android/os/Environment.html#getExternalStorageDirectory()


### Environment.getDataDirectory()
ex) `/data`
Androidのデータ保存領域

### Environment.getExternalStorageDirectory()
ex) `/storage/emulated/0`
外部ストレージのディレクトリを取得する。
ただし、直接ここへ何かを置くべきではない。アプリケーションプライベートであれば`Context.getExternalFilesDir`、共有ファイルであれば`Environment.getExternalStoragePublicDirectory(String)`経由でこの外部ストレージ領域を利用すべきとのこと。

### Environment.getExternalStoragePublicDirectory(String)
ex)`getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)): 
/storage/emulated/0/Download
`
外部ストレージ領域の最上位パス。タイプを指定する必要がある。

### Context.getExternalFilesDirs()
ex) `/storage/emulated/0/Android/data/{パッケージ名}/files`
アプリ固有の外部ストレージ領域。
アプリ固有のデータを保存するという点では`getFilesDir()`と同様だが、以下の２点が重要な違いだ。

* 常に利用可能というわけではない。（上述）
* `WRITE_EXTERNAL_STORAGE`権限があれば他アプリからの書き込みが可能

## まとめ
`Context`経由で呼び出せるものはアプリ固有のデータ領域。
Externalが付いているものは外部ストレージ領域。マウントされていない場合には使えない。
Externalが付いているものは、アプリ固有のデータであっても、アプリアンインストールで消えることはない。例えば、`Context.getExternalFilesDirs()`で得られる領域はContext経由なのでアプリ固有のデータ領域だが、Externalなのでアプリを削除してもデータは残る。

Externalはストレージがマウントされてない可能性を考えないといけないからアプリ固有のデータであれば`Context.getFilesDir()`がいいかなあ。
適当なC++テンプレート入門

##はじめまして
Qiitaというものがあるそうじゃないですか、
適当にやったことをまとめようと思いまして、

##ところで

C++にはたくさんの型が存在します。
`int` `float` `char` `std::string`
などなど、自作の型も含めれば無数に存在します。


型というのは不自由なものでして、
型を決定してしまうことで、そのコード自体を不自由にしてしまう可能性があります。

例えばこんな関数

```cpp:add.cpp
int Add(int a,int b){
    return a+b;
}
```
Add関数は見ての通り`int`型のみを受け取り、`int`型を返す関数になります。
もちろん引数に`float`などの浮動小数点型を与えた場合は`int`にキャストされて小数点以下は切り捨てられるってわけですね。

まあ、C++の**オーバーロード**を使えば同名で多重定義することも可能です

```cpp:add.cpp
int Add(int a,int b){
    return a+b;
}
float Add(float a,float b){
    return a+b;
}
```

これによって、`int`と`float`限定でadd関数が使用可能になります。


先に上げたように、型は無数に存在するので
Add関数も無数に書かなければいけません。

ついでにいうと、このままではライブラリの開発者はユーザーがどんな型を使うのか予知する必要があります。


##関数テンプレート

プログラマは全員が予言者では無いので、
**あらゆる型に対して適応できる万能のコード**で書く必要があります

```cpp:add.cpp
template<typename T>
T Add(T a,T b){
    return a+b;
}
```

とまあこんな感じで
`template<class T>`と記述することでTを任意の型として関数内で使用できます。

```cpp:add.cpp
template<typename T,typename U>
T Add(T a,U b){
    return a+b;
}
```
二個以上の引数を取ることもできます。
この場合T=UでもT≠Uであってもこの関数が使用できます。

また、この関数の場合+演算子を使用できない型はコンパイル時にエラーが吐き出されます。

##テンプレートの特殊化

ある日僕は言われました

>「俺はfloatが嫌いだ！そのAdd関数、floatの時だけ減算の処理をしてくれ！」

おまかせください。テンプレートには特定の型だけ違う処理をする**テンプレートの特殊化**の機能があります。

```cpp:add.cpp
template <typename T>
T add(T a,T b){
	return a + b;
}

template <>
float add(float a,float b){
	return a - b;
}
```
こんな感じでfloatだけ別の処理にすることもできます。

##関数クラスメンバエイリアステンプレート

テンプレートには実は何種類かあります

+ 関数テンプレート
+ クラステンプレート
+ メンバテンプレート
+ エイリアステンプレート

####関数テンプレート

さっきのAdd関数とか

```cpp:add.cpp
template <typename T>
T add(T a,T b){
	return a + b;
}
```

割と使う

####クラステンプレート

クラスと共に暮らす

```cpp:myclass.cpp
template <typename T>
class myclass{
public:
    T value;
};
```

宣言の仕方は`myclass<int>`のように宣言し、
テンプレート引数に指定した型を持つようになる。

####メンバテンプレート

正直、関数テンプレートとほとんど同じ

```cpp:myclass2.cpp
class myclass2{
public:
    int nanika;

public:

    template<typename T>
    T Function(T a,T b);

};
```

メンバ関数にも関数テンプレートは使用できる。それだけ


####エイリアステンプレート

C++11からtypedefをusingで記述できるようになった

```cpp
typedef TypographicError typo;
using typo = TypographicError;
```

これら２つは同様の意味を持つ。

そしてusingを使ったエイリアスにはテンプレートを使用できる

```cpp:UsingTemplate.cpp
template<typename T,typename U>
T Add2(T a,U b);

template <typename T>
using Add1 = Add2<T,T>;
```

このように、型のエイリアスの作成、テンプレート引数の再編成などが行える。
でもC++11から

##まとめ
テンプレートを用いることで汎用的なプログラムコードを作成できる。
ここまで読んでくれた人はきっと既にテンプレートなしでは生きられない体になっているだろう。
テンプレートマスターになって再利用しやすいコードを書こう！

まあ、テンプレートの真の力はこんなものでは無いんだけどね。
それは又の機会に…
CentOS(6.6)にluajitを有効化したvim7.4をインストール

luaじゃなくてluajitを使ったインストール手順はあんまり無いみたいなので、備忘録がわりに置いておきます。

# インストール手順

## makeに必要なファイルをインストール

    sudo yum install ncurses-devel perl-ExtUtils-Embed python-devel readline-devel gcc ruby-devel python-devel ruby lua-devel

※最小構成で構築した CentOS6.6 のため、普通の環境の場合は、既にパッケージが入ってる可能性があります。

## luajitをインストール

    $ sudo mkdir /usr/local/luajit
    $ sudo chown hykw /usr/local/luajit
    $ wget http://luajit.org/download/LuaJIT-2.0.3.tar.gz
    $ tar zxvf LuaJIT-2.0.3.tar.gz
    $ cd LuaJIT-2.0.3

### Makefile を編集

    $ vi Makefile

    export PREFIX= /usr/local/luajit
    INSTALL_INC=   $(DPREFIX)/include

### インストール

    $ make
    $ make install

    $ export PATH="/usr/local/luajit/bin/:$PATH"

## vim をインストール
 
    sudo mkdir /usr/local/vim
    sudo chown hykw /usr/local/vim
    
    wget ftp://ftp.vim.org/pub/vim/unix/vim-7.4.tar.bz2
    tar jxvf vim-7.4.tar.bz2
    cd vim74

    ./configure \
    --with-features=huge \
    --enable-fail-if-missing \
    --prefix=/usr/local/vim \
    --enable-luainterp \
    --with-luajit \
    --with-lua-prefix=/usr/local/luajit \
    --enable-perlinterp \
    --enable-pythoninterp \
    --enable-rubyinterp

    make

    sudo touch /etc/ld.so.conf.d/luajit.conf
    sudo chown hykw /etc/ld.so.conf.d/luajit.conf
    echo "/usr/local/luajit/lib" > /etc/ld.so.conf.d/luajit.conf
    sudo ldconfig

    ./src/vim --version
    make install
さくらVPSにubuntu14.04入れて設定


次やるとき忘れているのでメモ。
セキュリティのとりあえずの設定を行うまでです。

## インストール

[こちらの記事](http://qiita.com/takehiro_t59/items/94130e8fc6ea50743a73 "さくらのVPSでカスタムOS、Ubuntu14.04を入れるやり方の一つ(osインストールのみ)")を参考にされれば良いかと。

インストール後はサーバが停止するのでさくらVPSコントトールパネル(以後、コンパネ)から起動しましょう。ubuntu(以後、リモート)へは最初の方はさくらVPSのコンソール(以後、コンソール)からログインします。
Winならssh接続とか、鍵生成に[PuTTY](http://www.system-act.com/develop/windows/putty.html "PuTTY")とか用意しておくといいです。

## セキュリティ関連

### 各種パッケージを更新

sshの設定はとりぜず置いといて、パッケージの更新をしておきます。ついでにvimを。

```リモート
> sudo apt-get update
> sudo apt-get check
> sudo apt-get -s upgrade
> sudo apt-get upgrade

> sudo apt-get install vim
```

### sshの設定

1.公開鍵認証にするため、ローカルに鍵を作成する

```ローカル(Mac、Linux)
> ssh-keygen
```
Winは頑張って作成してください。

2.作成した鍵は~/.sshに格納します。

```ローカル(Mac、Linux)
> mkdir ~/.ssh
> mv id_rsa id_rsa.pub ~/.ssh/.
```
Winもホームに同じ感じに置けばよかったと思います。

3.リモートに公開鍵をセットする

```リモート
> mkdir ~/.ssh
```
```ローカル(Mac、Linux)
> cd ~/.ssh
> sftp [user]@[IP or host]
  > cd ~/.ssh
  > put id_rsa.pub
  > quit
```
```リモート
> cd ~/.ssh
> cat id_rsa.pub >> authorized_keys
> chmod 600 authorized_keys
> chmod 700 ~/.ssh
``` 

4.Portの変更、パスワードでのログインを禁止

設定ファイルの対象の項目を編集します。

```リモート
> sudo vim /etc/ssh/sshd_config
```
```sshd_config
Port 22222
PasswordAuthentication no
```

Portを変更したので、接続できるよう設定ファイルを書きます。Winはソフトに任せてください。

```ローカル(Mac、Linux)
> vim ~/.ssh/config
```
```config
Host ubuntu
  HostName [IP]
  Port 22222
  User [user]
```

5.sshサーバを再起動

ssh接続している場合はログアウトし、コンソールで入りなおしてください。

```リモート
> sudo service ssh restart
```

以降は、sshで接続して作業します。

```ローカル(Mac、Linux)
> ssh ubuntu
```

### ファイアウォールの設定

最初は無効になっています。sshとhttpのポート以外は全部閉じます。

```リモート
> sudo ufw status
Status: inactive #非アクティブ

> sudo ufw default deny
Default incoming policy changed to 'deny'
(be sure to update your rules accordingly)

> sudo ufw allow 80
Rules updated
Rules updated (v6)

> sudo ufw allow 22222
Rules updated
Rules updated (v6)

> sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

> sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
80                         ALLOW       Anywhere
22222                      ALLOW       Anywhere
80 (v6)                    ALLOW       Anywhere (v6)
22222 (v6)                 ALLOW       Anywhere (v6)
```

こんなんでいいのでしょうか...
クリップボードの画像ファイルをアップロードする

QiitaやGithub のようにWebアプリ上でクリップボードにコピーした画像をペーストコマンドでサーバに直接アップロードする方法。

# 実装例
[DevHub](https://github.com/volpe28v/DevHub)というチャットツールのチャット欄・メモ欄に実装した。
Web上の画像をコピー、または画面キャプチャから直接ペースト機能を使ってファイルアップロードからの表示ができるようになったのでとても便利になった。

以下、動作イメージ。
* クリップボードに画像をコピーした状態でメモ欄に Ctrl-v すると画像ファイルがアップロードされ、パスが返ってくる。
![スクリーンショット 2014-12-27 22.17.19.png](https://qiita-image-store.s3.amazonaws.com/0/4195/a7da733f-b177-7371-13c2-a440a730c7db.png)

* 編集を終了すると独自のマークダウン処理で画像が表示される。
![スクリーンショット 2014-12-27 22.17.39.png](https://qiita-image-store.s3.amazonaws.com/0/4195/1eb75485-f640-6407-83ae-a5ecc584cb41.png)

# 実装手順
* 貼り付け対象のDOMに 'paste' イベントをバインド
* pasteイベント処理内でeventから画像を取り出す
* Ajaxで画像情報をサーバに送信
* サーバ側でファイルを保存し保存後のパスをクライアントに送信
* クライアントで保存後のファイルパスを元に画像を表示する

# クライアントサイド(js)
pasteイベント発生時にクリップボードの画像をサーバへ送信する。
Ajaxでのアップロード処理は通常のフォームからのファイルアップロードと同様。
(以下のソースは [DevHub](https://github.com/volpe28v/DevHub)のソースから抜粋して多少単純化している)

```js
$target.on('paste', function(event){
  // event からクリップボードのアイテムを取り出す
  var items = event.originalEvent.clipboardData.items; // ここがミソ
  for (var i = 0 ; i < items.length ; i++) {
    var item = items[i];
    if (item.type.indexOf("image") != -1) {
      // 画像のみサーバへ送信する
      var file = item.getAsFile();
      upload_file_with_ajax(file);
    }
  }
});

// ファイルアップロード
function upload_file_with_ajax(file){
    var formData = new FormData();
    formData.append('file', file);

    $.ajax('/upload' , {
      type: 'POST',
      contentType: false,
      processData: false,
      data: formData,
      error: function() {
        // アップロードエラー処理
      },
      success: function(res) {
        // アップロード成功処理 res.fileName
      }
    });
  }
```

# サーバサイド(Node)
サーバサイドではクライアントからPOSTに対し画像の保存と保存後ファイルパスの返却を行う。

```js
var fs = require('fs');
var util = require('../lib/util');

exports.post = function(req, res) {
  var tmp_path = req.files.file.path;
  var base_name = req.files.file.name;

  // 画像貼り付けの場合は拡張子を付加する paste_image.xxx
  if (base_name == "blob" && req.files.file.type.indexOf('image') != -1){
    base_name = "paste_image." + req.files.file.type.split('/')[1];
  }

  // 20141114000310_paste_image.png のようなファイル名を生成
  var file_name = util.getFullDateNoSepa(new Date()) + '_' + base_name;

  var target_path = './static/uploads/' + file_name; // 保存先パス
  var access_path = '/uploads/' + file_name; // クライアントへ返すパス

  // ファイルの保存が成功したらレスポンスを返す
  fs.rename(tmp_path, target_path, function(err) {
    if (err) {
      throw err;
    }
    fs.unlink(tmp_path, function() {
      if (err) {
        throw err;
      }
      res.send({fileName: access_path});
      // クライアントでは fileName でファイルパスの取得可能
    });
  });
};
```
iPhoneアプリのライフサイクル

##修正（2014/12/30）
* shouldperformseguewithidentifier はDeprecatedらしいので、削除しました
  （shouldperformseguewithidentifierの中でSegueで遷移するかどうかを判定するのではなく、あらかじめ遷移してよいかどうかを判定した上で、prepareForSegueを実行せよということなんでしょうね）

* canPerformUnwindSegueAction を追加
* 画面間を移動した場合のApper系の実行順がおかしかったので訂正
* その他、ちょこちょこと補記


##目的
AppDelagate、ViewController、Segue、全部まとめたものがなさそうだったのでまとめてみました。


##ライフサイクル
![キャプチャ3.PNG](https://qiita-image-store.s3.amazonaws.com/0/53823/b279b29d-9f5b-0945-7206-eb5aa359742c.png)


### 画面遷移時の遷移元、遷移先の実行順（タブ画面の場合）
    1:-[FirstViewController viewDidLoad]
    1:-[FirstViewController viewWillAppear:]
    1:-[FirstViewController viewDidAppear:]

    2:-[SecondViewController viewDidLoad]
    2:-[SecondViewController viewWillAppear:]
    1:-[FirstViewController viewWillDisappear:]
    1:-[FirstViewController viewDidDisappear:]
    2:-[SecondViewController viewDidAppear:]

    1:-[FirstViewController viewWillAppear:]
    2:-[SecondViewController viewWillDisappear:]
    2:-[SecondViewController viewDidDisappear:]
    1:-[FirstViewController viewDidAppear:]


##参考資料
[アプリの状態とマルチタスキング](https://gist.github.com/shinyaohira/5975781)
[iOS のイベント駆動をライフサイクルイベントとユーザアクションイベントにわけて理解する](http://d.hatena.ne.jp/glass-_-onion/20120405/1333611664)
[iOSのライフサイクル](https://sites.google.com/a/gclue.jp/ios-docs/iosnoraifusaikuru)
今年出会った[Error!]をまとめるよ

Titanium新参者の@nobinegoと申します．
2014年もあとわずか…
Titaniumでの開発で悩まされたエラーの数々を年内にまとめておこうということで，初めて記事を書きます．
よろしくお願いします．

<h1>WindowsでTitanium開発をするのは大変!</h1>
私の身の回りには，WindowsでTitanium開発をしている人が多数います．
しかし，WindowsのTitanium Studioでは予期せぬエラーが発生することが多いらしいですね．

きっと1度は検索するだろう項目についてまとめていきます．

<h2>Androidエミュレータでアプリが起動しない</h2>

>[ERROR] Application Installer abnormal process termination. Process exit value was 1
>[ERROR] Emulator exited with error: 1

時に上記のエラーを吐いて，Androidエミュレータが起動しない場合があります．
こんなときはまず，Android SDK Managerを起動して，以下のことをチェックしましょう．
1. Android SDK Toolsのバージョンが最新であること
2. Android SDK Platform-toolsのバージョンが最新であること
3. <b>Android Build Toolsのバージョンが<font color="red">20以下</font>であること</b>

Android Build Toolsの最新版は予期せぬエラーを引き起こす可能性があるようです．
20くらいだと正常に動作することが確認されているので，現状は20を使うのがいいでしょう．

<h2>それでもAndroidエミュレータでアプリが起動しない</h2>

>[ERROR] Application Installer abnormal process termination. Process exit value was 1
>[ERROR] Emulator failed to start in a timely manner
>[INFO] Warning for emulator to become ready The current timeout is set to 120000 ms

次の敵はタイムアウトエラーです．
何度もRunしているうちに，たまに起動できるときもあるみたいですが，

```
$Titanium config android.emulatorStartTimeout <timeout ms>
```

でタイムアウトまでの時間をミリ秒を単位として設定できます．

Windowsでは，Android SDKやホームディレクトリが..\Program File(x64)\などにあると，このタイムアウトエラーが発生する場合もあるようです．
つまり，空白や()を含む名前をディレクトリに設定するな，ということですね．
<br>
しかし，iOSアプリとAndroidアプリの両方で動作を確認したいというのに，Androidエミュレータの起動が運任せというのはいただけない．
そんなあなたに

<div align="center">
<img src="https://qiita-image-store.s3.amazonaws.com/0/63721/21fad6f2-0487-ef18-f64e-5c30dd258703.png" width="400">
</div>

もしくは，お手持ちのAndroid端末で実行してみるのがいいかもしれません．
Androidエミュレータだけが悪いのであれば，端末上ではちゃんとアプリが起動する場合のほうが多いですから．

<h1>MacなのにTitaniumがビルドできない</h1>
普段開発を行うのはMacBook Airなのですが，
<div align="center">
<img src="https://qiita-image-store.s3.amazonaws.com/0/63721/3c926c04-6801-3975-be75-64a67e562bbe.png" width="400">
</div>

こんなときはビルド失敗となります．

>[ERROR] Failed to run command "build"
>[ERROR] TypeError: Cannot read property 'cyan' of undefined

なにが問題かというと，<b>Xcodeが自動アップデートできない</b>のです．

5GB程度の空き容量は常に持っておきたいですね．
そして，大切なのは，

<h3 align="center"><b><font color="red">ターミナルを再起動すること</font></b></h3>

アップデートを適用してビルドを実行するためには，新しいターミナルを立ち上げるか，今立ち上がっているターミナルを再起動しましょう．
そんな簡単なことに気づかず，堂々巡りをしていたときもありました（遠い目

* * *
<br>
以上，今年何度も悩まされ続けたエラーでした．
1度解決したにも関わらず，忘れた頃にやってきて苦しめられました．
これできっと，2015年は悩むことなく，エラーに対処することができるでしょう！
<br>
<br>
* * *
<br>
それでは皆様，
<h3 align="center">☆･:ﾟ* 良いお年を *ﾟ:･☆</h3>
<br>
<br>
0バイトのファイルを保存した時に、ファイルを削除するVim script

# これは何か？
開いているファイルが不要になった時などに、中身を空にして保存をすると、そのファイルを削除することができる Vim script です。無条件で削除するのもアレなので、確認時に y を押した時のみ実行されます。

## ユースケース
例えば memolist を使っていて、もはや不要になったメモを削除したいと思った時などに使っています。

## ソース
    augroup hykw_removeFile
      autocmd!
      autocmd BufWritePost * call s:Hykw_removeFileIf0Byte()
    augroup END
    
    function! s:Hykw_removeFileIf0Byte()
      let filename = expand('%:p')
      if getfsize(filename) > 0
        " do nothing
        return
      endif
    
      let msg = printf("\n%s is empty, remove?(y/N)", filename)
      if input(msg) == 'y'
        call delete(filename)
        bdelete
      endif
    endfunction

## 使い方
.vim の適当な所にソースを貼り付けるだけです。ファイルの保存イベントの後に呼び出されます。

## URL
https://github.com/hykw/vim-hykw-removeFileIf0Byte
ブックマークレットで入力欄に自動入力する

テストなどでWeb画面に自動入力するときの定番はSeleniumだと思うが、文字列を入れるだけだったら、ブックマークレットが便利（[というネタを2009年に書いてた](http://goodsite.cocolog-nifty.com/uessay/2009/02/toto-bc5b.html
)が、自分でコピペしやすいように転記する）

まず、jQueryを読み込ませておく。jQueryをすでに読み込んでるサイトは、この手順はスキップ。

```js
javascript:var jq=document.createElement('script');jq.src='//code.jquery.com/jquery-2.1.3.min.js';document.body.appendChild(jq);
```
[bookmarklet](javascript:var jq=document.createElement('script');jq.src='//code.jquery.com/jquery-2.1.3.min.js';document.body.appendChild(jq);
)

続けて、jQueryのval()で値を入れ込むブックマークレットを実行。Googleの入力欄の場合はname=qなので、こんな感じで指定する。

```js
javascript:jQuery("*[name=q]").val("test");void(0);
```
[bookmarklet](javascript:jQuery("*[name=q]").val("test");void(0);
)

jQueryを読み込むブックマークレットと、val()を実行するブックマークレットをひとつにすると、読み込みタイミングの関係で実行されないので、別々にする必要があるが、スクリプトファイルを作っておくと、こんな感じでまとめられる。

```js
javascript:var jq=document.createElement('script');jq.src='//code.jquery.com/jquery-2.1.3.min.js';document.body.appendChild(jq);var s=document.createElement('script');s.src='//example.com/test.js';document.body.appendChild(s);void(0)
```
CentOS 7 Percona (MySQL) のインストール

CentOS7 での Percona (MySQL) のインストール手順

## もし mysql がすでに入っている状態なら削除する

```shell-session
$ sudo yum remove -y mysql mysql-server mysql-libs php-mysql
```

## Percona のリポジトリを追加

```shell-session
$ sudo yum install http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm
```

## インストール

```shell-session
$ sudo yum install Percona-Server-client-57 Percona-Server-server-57 percona-toolkit
```

## 起動
```shell-session
$ sudo systemctl start mysql
```

※起動してこない場合は `/var/log/message` を見る。メモリが少ないと立ち上がらない。その場合は `/etc/my.cnf` をいじる
SwiftでUndocumentedAPIを使う

Objective-CのカテゴリでUndocumented APIの宣言をします


```objc:UndocumentedAPICategories.h
@interface NSFileManager (HogeExtension)
- (NSString *)_web_pathWithUniqueFilenameForPath:(NSString *)path;
@end
```


ブリッジヘッダでインポートします

```objc:PROJECT-Bridging-Header.h
#import "UndocumentedAPICategories.h"
```

以上
Windows 使いの Mac 初導入 | Launcher #win2mac

# <i class="fa fa-windows" style="font-size:1em;"></i> Windows 使いの <i class="fa fa-apple" style="font-size:1em;"></i> Mac 初導入 | Launcher #win2mac
## <i class="fa fa-cubes" style="font-size:1em;"></i> 概要
Launcher の移行
## <i class="fa fa-windows" style="font-size:1em;"></i> Windows では
特別な Launcher ソフトは使用せず、 Window キー + アプリケーション名を入力をしていました。

例えば、 chrome を起動したければ

~~~bash
Win, ch, Enter
~~~

のようなキー入力です。

## <i class="fa fa-apple" style="font-size:1em;"></i> Mac では
Alfred を利用します。
いくつか候補はあるようですが、先人の勧めに従います。

<blockquote class="twitter-tweet" lang="ja"><p><a href="https://twitter.com/tbpgr">@tbpgr</a> つalfred</p>&mdash; DOQER (@DQNEO) <a href="https://twitter.com/DQNEO/status/548672590466654209">2014, 12月 27</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

### <i class="fa fa-exclamation-circle" style="font-size:1em;"></i> Alfred とは？
公式サイト曰く,　[^1]

>Alfred is an award-winning productivity application for Mac OS X
>
>Alfred saves you time when you search for files online or on your Mac. 
>Be more productive with hotkeys, keywords and file actions at your fingertips.

とのこと。

### <i class="fa fa-cloud-download" style="font-size:1em;"></i> Alfred のインストールについて

~~~bash
$ wget https://cachefly.alfredapp.com/Alfred_2.5.1_308.zip
$ unzip Alfred_2.5.1_308.zip
$ ls -1
Alfred_2.app
Alfred_2.1_308.zip
~~~

app がアプリケーション本体なのか。
これ、をどうすればいい？
ぐぐってみた。

こちらを参考にします

<i class="fa fa-external-link" style="font-size:1em;"></i> [超絶便利なランチャアプリ Alfred 本体と Powerpack をインストールしてみる](http://dev.ontheroad.jp/archives/3154)

app を Application フォルダ に ドラッグ & ドロップ　すればいいようです。

### <i class="fa fa-check-circle" style="font-size:1em;"></i> 動作確認

option + space で検索窓が表示され、 `ter, Enter` の入力で無事ターミナルを起動できました。

## :book: 脚注
[^1]: [Alfred 公式サイト](http://www.alfredapp.com/)
仮想マシンにおけるブリッジとNATの違い

Samba使ってゲストの`xfs`のHDDからホストの`NTFS`のHDDにコピーする際気がついた。

## ホストのLANがLINKUPしていない場合

* ブリッジ : ゲストと通信できない(DHCPの場合)
* NAT : ゲストと通信出来る

## sambaの速度

* ブリッジ : 5MB/s(@無線LAN)
* NAT : 24MB/s

## 結論

* ブリッジ
  * ホストとゲスト間で通信する際、一度ネットワーク機器にパケットを送り、戻ってくる。ここが遅いと実際の転送速度に影響が出る。
* NAT
  * ホストとゲスト間で通信する際、PC内で完結する。
bundle console で pry を使う bundler v1.6 以降

まずは `pry` を Gemfile へ追加。

```:Gemfile
gem "pry", group: :development
```

gemspec な人は以下のように追加

```:your_gem.gemspec
  spec.add_development_dependency "pry"
```

追加できたら `bundle config console pry`

```shell-session
$ bundle config console pry
$ bundle console
Resolving dependencies...
[1] pry(main)> 
```

`bundle console` を諦めて `bundle exec pry` してた人、`.irbrc` を書き換えたくない人には嬉しいですね。

Enjoy:metal:

## Resources

- [公式のドキュメント](http://bundler.io/v1.6/bundle_console.html)
- https://github.com/bundler/bundler/pull/2620
  - Great work!!
自作XSDをEclipseが解析可能にする2つの方法

# 概要

自作した XSD ファイルを Eclipse に認識させ、解析されるようにする 2 つの方法を解説します。この 2 つの方法のいずれかで実現できます。

以降“自作した XSD ファイル”のことを XML Schema ファイルと称します。

使用する Eclipse は Pleiades プラグインが適用されていることを前提とします。

# 方法１：Eclipse プラグインで実現

ここでは仮に XML スキーマ名を“[http://xmlns.my-server.local/sample/XMLSchema/foobar.xsd]()”にしたとします。

## Eclipse プラグインを作成する

1. メインメニューの“ファイル”を選択
2. “ファイル”メニューの“新規”を選択
3. “新規”メニューから“プロジェクト...”を選択
4. “ウィザードを選択”と書かれたダイアログボックスから“プラグイン・プロジェクト”を選択
5. “プラグイン・プロジェクト”と書かれたページにプロジェクト名を記入
6. 同ページ上の“Java プロジェクトの作成”チェックボックスからチェックを外す
7. 同ページの“次へ”ボタンを押下
8. “完了”ボタンを押下
9. 作成されたプロジェクトに plugin.xml を追加する
10. plugin.xml の“概要”タブを選択して“このプラグインはシングルトン”チェックボックスにチェックを入れる
11. プロジェクト直下に xsd フォルダーを作成
12. xsd/foobar.xsd、plugin.xml、build.propertiesを以下のようにする
13. plugin.xmlをダブルクリックして表れる画面の“概要”タブを選択
14. 概要タブ上の“エクスポート・ウィザード”からプラグインを作成
15. プラグインとして作成された jar ファイルを Eclipse の Plugins フォルダーに格納
16. Eclipse を再起動

```xml:xsd/foobar.xsd
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="foobar">
    <xsd:complexType>
      <xsd:sequence>
        〜
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>
```

```xml:plugin.xml
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
  <extension point="org.eclipse.wst.xml.core.catalogContributions">
    <catalogContribution>
      <!-- XML スキーマ名と XSD ファイルを結びつける -->
      <system systemId="http://xmlns.my-server.local/sample/XMLSchema/foobar.xsd"
              uri="xsd/foobar.xsd"/>
      <!-- 複数の XML スキーマがある場合は、ここに続けて system タグを記入 -->
    </catalogContribution>
  </extension>
</plugin>
```

```properties:build.properties
# META-INF/MANIFEST.MF と XML スキーマファイル、plugin.xml をプラグインに含める設定
bin.includes = META-INF/,\
               .,\
               xsd/,\
               plugin.xml
```

## XML ファイルを記述する
XML スキーマを XML に記述します。

```xml:my-file.xml
<?xml version="1.0" encoding="utf-8"?>
<foobar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://xmlns.my-server.local/sample/XMLSchema"
        xsi:schemaLocation="http://xmlns.my-server.local/sample/XMLSchema http://xmlns.my-server.local/sample/XMLSchema/foobar.xsd">
  〜
</foobar>
```

## XML カタログを確認

Eclipse の設定から XML カタログを表示してください。

自作した XML スキーマがリストアップされていることを確認してください。

## Eclipse で検証する

XML ファイルを右クリックして“検証”を選択して XML が正しいかどうかを検証してください。

# 方法２：XML Schema ファイルをプロジェクトに含めて実現

## XSD ファイルを記述する
以下のようなファイルを foobar.xsd という名称で作成したとします。

```xml:foobar.xsd
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="foobar">
    <xsd:complexType>
      <xsd:sequence>
        〜
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>
```

## XML ファイルを記述する
noNamespaceSchemaLocation 属性に、作成した XSD ファイルを指定します。

```xml:my-file.xml
<?xml version="1.0" encoding="utf-8"?>
<foobar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="foobar.xsd">
  〜
</foobar>
```

## Eclipse で検証する

XML ファイルを右クリックして“検証”を選択して XML が正しいかどうかを検証してください。
Dockerizeされたskydnsとetcdを動かす


Dockerizeされたskydnsとetcdをどう動かしたかの記録を残す。
但し、digで応答が返ってくるのを確認した程度の状態なので後で追加、修正するかも。
結局二行で動かせたけど、必要なパラメータを把握するのに苦労した。

##環境

|ソフトウェア|バージョン|
|:-:|:-:|
| boot2docker-cli | v1.3.1|
| docker | 1.3.0 |
| skydns | 2.0.1d |
| etcd | 0.4.6 |

## 起動方法

### etcd

```bash
$ docker run -it --name etcd --rm -p 7001:7001 -p 4001:4001 coreos/etcd:v0.4.6 --addr=$(boot2docker ip 2>/dev/null):4001 --peer-addr=$(boot2docker ip 2>/dev/null):7001
```

### skydns

```bash
$ docker run -it -p 53:53 -p 53:53/udp --name skydns --link etcd:etcd --rm -e ETCD_MACHINES=http://etcd:4001 skynetservices/skydns:latest --addr=0.0.0.0:53
```

### registrator

registratorは以下の感じで動かせた。

```bash
$ docker run --name registrator -h registrator -v /var/run/docker.sock:/tmp/docker.sock progrium/registrator skydns2://$(boot2docker ip 2>/dev/null):4001/skydns.local
```

##動作確認

### ダミーの情報をetcdに登録

skydnsのREADMEに書いてある例を使って、サービスの情報をetcdに登録

```bash
$ curl -XPUT http://$(boot2docker ip 2>/dev/null):4001/v2/keys/skydns/local/skydns/east/production/rails/1 -d value='{"host":"service1.example.com","port":8080}'
$ curl -XPUT http://$(boot2docker ip 2>/dev/null):4001/v2/keys/skydns/local/skydns/west/production/rails/2 -d value='{"host":"service2.example.com","port":8080}'
$ curl -XPUT http://$(boot2docker ip 2>/dev/null):4001/v2/keys/skydns/local/skydns/east/staging/rails/4 -d value='{"host":"10.0.1.125","port":8080}'
$ curl -XPUT http://$(boot2docker ip 2>/dev/null):4001/v2/keys/skydns/local/skydns/east/staging/rails/6 -d value='{"host":"2003::8:1","port":8080}'
```

### digで登録情報を確認

```bash
$ dig @$(boot2docker ip 2>/dev/null) rails.staging.east.skydns.local

; <<>> DiG 9.8.3-P1 <<>> @192.168.59.103 rails.staging.east.skydns.local
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26296
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;rails.staging.east.skydns.local. IN	A

;; ANSWER SECTION:
rails.staging.east.skydns.local. 3600 IN A	10.0.1.125

;; Query time: 47 msec
;; SERVER: 192.168.59.103#53(192.168.59.103)
;; WHEN: Sat Dec 27 21:29:03 2014
;; MSG SIZE  rcvd: 65
```

## 参考URL

[Dockerにおけるマルチホストでのコンテナ間リンク考察](http://k2nr.me/blog/2014/08/21/docker-container-management.html)

[CoreOS 上の Docker コンテナのサービス情報を registrator を使って SkyDNS2 に自動登録する](http://qiita.com/spesnova/items/1d384f80a76d8fa5c23f)

[SkyDNS2 VERSION 2](http://miek.nl/posts/2014/Jun/08/announcing%20SkyDNS%20version%202/)

[skynetservices/skydns - Docker Hub](https://registry.hub.docker.com/u/skynetservices/skydns/)

[skynetservices/skydns - GitHub]
(https://github.com/skynetservices/skydns)

[coreos/etcd - Github](https://github.com/coreos/etcd)

[Etcd Configuration](https://github.com/coreos/etcd/blob/master/Documentation/configuration.md)
エアリプをコンソールに表示するPHPスクリプト


# php-cmt4rt (comments for RT)

https://github.com/takatama/php-cmt4rt

コンソールから使います。
指定したリツイートに対するコメント（エアリプ）っぽいものを探して表示します。


## 事前準備

https://apps.twitter.com で以下を作ります。

* consumer_key
* consumer_secret
* access_token
* access_token_secret

[Create New App]でアプリを作った後、Keys and Access Tokens タブの Token Actions で access_token, access_token_secret を作ります。

*_secret は安全なところに隠しましょう。

## インストール

```
$ git clone https://github.com/takatama/php-cmt4rt.git
$ cd php-cmt4rt
$ curl -sS https://getcomposer.org/installer | php
$ php composer.phar update
```
key.ini.template を key.ini にリネームして、取得した情報を書き込みます。

```keys.ini
consumer_key=ここに書く
consumer_secret=ここに書く
access_token=ここに書く
access_token_secret=ここに書く
```

## 使い方

調査したいツイートのURLか、IDを指定します。
例えば、これの場合
<blockquote class="twitter-tweet" lang="ja"><p>悪い知らせを受けた時に、まず「報告してくれてありがとう」と言える、大きな人物になりたいなー。早い段階で報告されなくなったら、おしまいだもの。「だから言ったのに！」って今言われても凹むし、次は黙ってようと思っちゃうよ…</p>&mdash; 高玉広和 (@takatama_jp) <a href="https://twitter.com/takatama_jp/status/547687296988770304">2014, 12月 24</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

```
$ php cmt4rt.php https://twitter.com/takatama_jp/status/547687296988770304
```

または

```
$ php cmt4rt.php 547687296988770304
```

## 難しいところ

* エアリプが気になるくらいなら、ツイートを控え(ry
* エアリプかどうかは判断が難しいですね。参考のため、RTの後、コメントされるまでの時間も表示してます。
* Twitter API の制限がきつくて、たくさんRTされたものは調べきれないです。Web アプリにするのは難しそうですね。
* Guzzle の非同期 API 使ったら、体感速度はもうちょい上がると思います。ばりばりの手続き型で書いちゃってます。

## 参考にした情報
* RtRTはAPI廃止でダメになった→すまん、ありゃウソだった - esuji5's diary
http://esuji5.hateblo.jp/entry/2014/04/01/233633

* PHP - Guzzle で Twitter REST API を叩く - Qiita
http://qiita.com/kawanamiyuu/items/2cab57e3d3932a2c5e4e

* API Rate Limits | Twitter Developers
https://dev.twitter.com/rest/public/rate-limiting

* GET statuses/retweets/:id | Twitter Developers
https://dev.twitter.com/rest/reference/get/statuses/retweets/%3Aid

* GET statuses/user_timeline | Twitter Developers
https://dev.twitter.com/rest/reference/get/statuses/user_timeline
geminaboxにlocalhost以外からアクセスできない。ったらbinding, お前か

local に gem server を立てる geminabox で localhost からのアクセスしか受け付けてくれない。ってときは多分 WEBRick 起動で binding がデフォルトのまま localhost になってる。

geminabox は Sinatra でつくられていて binding を渡すオプションは ```-o``` です。

```bash
bundle exec rackup config.ru -p 9292 -o 0.0.0.0
```

* [Sinatraがデフォルトでは外部から繋がらなくなってたよ](http://qiita.com/u1_fukui/items/b86b21f6ed39f4c10d5d)
* [developmentでWEBrick起動のRailsはbindオプションでanyアクセスを受け付けるようになる](http://qiita.com/weakboson@github/items/9ef390679347460d6d77)
VimのNERDTree上でgrepする

タイトルにはgrepと書きましたが、今回はgrepの代わりに、より高速な[The Silver Searcher](https://github.com/ggreer/the_silver_searcher 'ggreer/the_silver_searcher')を使います。

もちろん、NERDTreeは既に使えるという前提です。

### 1. The Silver Searcherのインストール

```
$ brew install the_silver_searcher
```
The Silver Searcherについては、以下の記事を参考。
[ackを捨てて、より高速なag(The Silver Searcher)に切り替えた](http://blog.glidenote.com/blog/2013/02/28/the-silver-searcher-better-than-ack/ 'Glide Note')

### 2. VimからThe Silver Searcherを使えるようにする

[ag.vim](https://github.com/rking/ag.vim 'rking/ag.vim')というプラグインを利用します。
`.vimrc`に以下を追記して、`:NeoBundleInstall`

```.vimrc

NeoBundle 'rking/ag.vim'
```

これで、vimから`:Ag [options] {pattern} [{directory}]`で、The Silver Searcherが使えるようになります。

### 3. NERDTreeのmenuにgrepを追加する
[grep_menuitem.vim](https://gist.github.com/inagaa/5141204 ' inagaa / grep_menuitem.vim')というプラグインを利用します。

grep_menuitem.vimを`.vim/bundle/nerdtree/nerdtree_plugin/`以下に置く。

これで、NERDTreeのmenuにgrepが追加されます。
![スクリーンショット 2014-12-27 21.10.20.png](https://qiita-image-store.s3.amazonaws.com/0/18185/4c99e6ba-eab0-4fab-04a3-ae406a0a8481.png "スクリーンショット 2014-12-27 21.10.20.png")




### 4. NERDTreeでThe Silver Searcherを使う
2でVimからThe Silver Searcherを使えるようにし、3でNERDTreeでgrepを使えるようにしたので、次はNERDTreeでThe Silver Searcherを使えるようにします。

具体的には、3で追加した`grep_menuitem.vim`を以下のように修正。

```grep_menuitem.vim
" exec 'silent grep -rn ' . pattern . ' .' "変更前
exec 'silent Ag ' . pattern . ' .' "変更後
```

これで、NERDTreeでgrepの代わりにThe Silver Searcherが使えるようになりました。
特にファイル数の多いディレクトリ以下を検索するときは、grepよりThe Silver Searcherの方が圧倒的に早いです。

## 参照
* [黄昏てなんかいられない](http://kronus9.sblo.jp/article/82559389.html '黄昏てなんかいられない')
* [ackを捨てて、より高速なag(The Silver Searcher)に切り替えた](http://blog.glidenote.com/blog/2013/02/28/the-silver-searcher-better-than-ack/ 'Glide Note')
Kobito+Qiitaを一週間使ってみて得られたもの


# 背景
先週からKobitoでメモを取りながら、そのうち一部をQiitaで公開することにした。
一週間経過した現時点までに考えたことを記録しておく。

# 新しいツールを使い始めた経緯

一週間前にQiitaとKobitoを使い始めたときに考えたことの記録。

## Qiitaを使い始めた理由

### 新しいメモツールを探していた
個人的なメモは長らくOperaのメモ機能を使っていたが、OperaがWebKitを採用したバージョンからメモ機能が使えなくなってしまった。一年くらいはメモ機能があるOperaを利用していたが、いつまで経っても新しいOperaにメモ機能が実装されない。そろそろ新しいやり方を考えようと思った。

### 文章を公開する習慣を付けたかった
理由はいろいろあるのだが、ここ一年くらい、人に読んでもらえる文章を書けるようになりたいと考える機会が増えていた。メモの習慣を変えるのに合わせて、これからは公開できる文章を書く習慣をつけたいと思った。そのために、「メモを書く」ことから「その文章を公開する」ことへのハードルが低いツールを使いたいと考えた。

### マークダウンを使いたかった
マークダウンできれいなテキストを書けるツールを試してみたかった。欲を言えば、プログラムのコードをいい感じに整形してくれるツールでメモをとれたらいいなと思った。以前ブログでコードを載せようとしたことがあるが、導入方法について調べるのに時間がかかって諦めてしまったことがある。(ちなみにブログはもう更新されなくなって久しい。)文章を書く習慣をつけるためには、きれいな文章を書くためのハードルが低いツールがよかった。

### できるだけ文章が消えるリスク低くしたかった
書いた文章がなくなってしまったり、書いている途中の文章が消えてしまうと、一気に文章を書く意欲が削がれる。そのような状況を防ぐため、クラウドにバックアップがあったり、下書きを自動(もしくはショートカットキー)で保存してくれるツールが欲しかった。

### どこでもメモをとれるようにしたかった
いつも使っているコンピュータが手元にあればいいが、そうでないときもあるだろう。主に使っているMacbookの他にも、WindowsPCを使うこともある。そうなると、最低限ブラウザがあれば利用できる、そんなツールがを探した。

## Kobitoを使い始めた理由

### Qiitaと連携できる
メモを取るのにはQiitaを使うことに決めたので、それと連携できるアプリケーションということで試してみようと思った。
もちろんマークダウンも使えるし、リアルタイムできれいなプレビューが表示されるのも良さそうだった。

### キーボードショートカットが十分揃っている
記事の選択・編集・検索・新規作成、さらに、Qiitaへの投稿までがショートカットで素早く利用できる。これは、ストレス無くメモを取るにはすごく重要だと考えた。

### 検索が速い
記事一覧ではインクリメンタルな全文検索が可能。記事内でもキーワード検索が利用できる。オンラインでQiitaを利用するよりも、Kobitoの検索の方が早くて使い勝手が良さそうだった。

### 文章がローカルに保存される
オフライン環境や、ネットワーク環境が悪い場所でもいつもと同じようにメモが取れる。新幹線で移動することも多そうで、これも地味に嬉しい点だった。
ただ、Macbookを紛失したり、壊れたりした場合に備えて、Dropboxでバックアップを取るように構成した。

# 一週間使ってみての感想

上のようなことを期待して使い始めたところ、現時点では思った以上に良いツールだと感じている。

## Kobitoで文章を書くと、きれいにレイアウトされて楽しい
「文章を書く」→「きれいにレイアウトされる」→「楽しい」→「もっと文章を書く」という好循環ができた。これはKobitoのマークダウン機能が素晴らしいおかげだ。また、キーボードショートカットのおかげで操作にストレスがない。
操作やレイアウトに頭を悩ませなくて良いので、文章を書くことだけに集中することができる。

## Qiitaで文章を公開すると、多くの人に見てもらえて嬉しい
こちらも「記事を公開する」→「人に見てもらえる」→「嬉しい」→「さらに記事を公開する」という好循環ができつつある。いままで公開した記事に関しては、なんのPRをしなくても数日で数十〜数百Viewがついた。さらに記事がストックされることもあり、その場合はもっと嬉しくなる。
これは、文章を書き続けるためには大きなモチベーションになるはずだ。なんでもそうだと思うが、公開したものに対して何かしらのフィードバックがあると嬉しい。一人でひっそりと公開しているブログでは、同じ記事を投稿してもそんなにはアクセスされないのではと思う。

# 結論

## Kobito + Qiita で、文章を書いて公開する好循環ができた

Kobitoを使うと文章を書くことが楽しくなる。
Qiitaを使うと文章を公開することが楽しくなる。
Windows 使いの Mac 初導入 | Package Manager #win2mac

# <i class="fa fa-windows" style="font-size:1em;"></i> Windows 使いの <i class="fa fa-apple" style="font-size:1em;"></i> Mac 初導入 | Package Manager
## <i class="fa fa-cubes" style="font-size:1em;"></i> 概要
Package Manager の移行
## <i class="fa fa-windows" style="font-size:1em;"></i> Windows では
Windows では, Cygwin の apt-cyg を利用していました。
それ Windows っていうの？ というツッコミもあるかもしれませんが、
あくまで私が Windows でやっていたことを Mac でもできるようにするのが今回の連載の趣旨です。

### <i class="fa fa-exclamation-circle" style="font-size:1em;"></i> apt-cyg とは？
Cygwin で利用するソフトウェアを CUI でインストールできるツールです。
通常、 Cygwin では setup.exe を利用して GUI でインストールを行いますが、
CUI を利用するために Cygwin を導入した人にとっては億劫な方法でした。

そこで、 apt-cyg を利用すると他の Linux 系 OS の Package Manager のように
コマンドでインストールが可能になります。

もし、 Windows 環境で Cygwin を使っているが、 apt-cyg をインストールしていない、という方は
ぜひインストールするといいと思います。

### <i class="fa fa-cloud-download" style="font-size:1em;"></i> apt-cyg のインストールについて
こちらの記事が詳しいです
<i class="fa fa-external-link" style="font-size:1em;"></i> [64bit版Cygwinをインストールしてapt-cygするまで](http://dqn.sakusakutto.jp/2013/12/64bit_cygwin_apt-cyg.html)

### <i class="fa fa-check-circle" style="font-size:1em;"></i> 動作確認

~~~bash
$ apt-cyg install figlet
$ figlet 'Thanks DQNEO!'
 _____ _                 _          ____   ___  _   _ _____ ___  _
|_   _| |__   __ _ _ __ | | _____  |  _ \ / _ \| \ | | ____/ _ \| |
  | | | '_ \ / _` | '_ \| |/ / __| | | | | | | |  \| |  _|| | | | |
  | | | | | | (_| | | | |   <\__ \ | |_| | |_| | |\  | |__| |_| |_|
  |_| |_| |_|\__,_|_| |_|_|\_\___/ |____/ \__\_\_| \_|_____\___/(_)
~~~

## <i class="fa fa-apple" style="font-size:1em;"></i> Mac では
Homebrew を利用します。
日本語公式サイトを参考にインストールを行います。 [^1]

### <i class="fa fa-exclamation-circle" style="font-size:1em;"></i> Homebrew とは？
OS X 用のパッケージマネージャーです。

### <i class="fa fa-cloud-download" style="font-size:1em;"></i> apt-cyg のインストールについて
下記のコマンドを実行します。

~~~bash
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
~~~

### <i class="fa fa-check-circle" style="font-size:1em;"></i> 動作確認

~~~bash
$ brew install figlet
$ figlet 'Goodbye Windows!'
  ____                 _ _
 / ___| ___   ___   __| | |__  _   _  ___
| |  _ / _ \ / _ \ / _` | '_ \| | | |/ _ \
| |_| | (_) | (_) | (_| | |_) | |_| |  __/
 \____|\___/ \___/ \__,_|_.__/ \__, |\___|
                               |___/
__        ___           _                   _
\ \      / (_)_ __   __| | _____      _____| |
 \ \ /\ / /| | '_ \ / _` |/ _ \ \ /\ / / __| |
  \ V  V / | | | | | (_| | (_) \ V  V /\__ \_|
   \_/\_/  |_|_| |_|\__,_|\___/ \_/\_/ |___(_)
~~~

## :book: 脚注
[^1]: [Homebrew 日本語公式サイト](http://brew.sh/index_ja.html)
Windows 使いの Mac 初導入 まとめ記事 #win2mac

# Windows 使いの Mac 初導入 まとめ記事 #win2mac

更新日: 2015/01/12 21:35:38

|No.|タイトル|作成日|ストック数|
|--:|:--|:--:|--:|
|1|[WinToMac  Windows 使いの Mac 初導入 #win2mac](http://qiita.com/tbpgr/items/40529c3d9b10c7219a2c)|2014/12/27 21:01:23|0|
|2|[Windows 使いの Mac 初導入  Package Manager #win2mac](http://qiita.com/tbpgr/items/ac5fea19bb8aab8ed160)|2014/12/27 21:05:26|0|
|3|[Windows 使いの Mac 初導入  Launcher #win2mac](http://qiita.com/tbpgr/items/0e6fd195aeec09b60896)|2014/12/27 22:01:43|1|
|4|[Windows 使いの Mac 初導入  Clipboard #win2mac](http://qiita.com/tbpgr/items/e61251bea939b56ac359)|2014/12/28 15:17:02|0|
|5|[Windows 使いの Mac 初導入  Menu を Keyboard で操作 #win2mac](http://qiita.com/tbpgr/items/072d6513511c367f3164)|2014/12/28 20:49:23|1|
|6|[Windows 使いの Mac 初導入  仮想デスクトップ #win2mac](http://qiita.com/tbpgr/items/5963efee46ffaf552828)|2015/01/02 15:55:32|1|
|7|[Windows 使いの Mac 初導入  アプリケーションスイッチャ #win2mac](http://qiita.com/tbpgr/items/6797de52742a65312979)|2015/01/12 21:34:56|0|
WinToMac | Windows 使いの Mac 初導入 #win2mac

# <i class="fa fa-windows" style="font-size:1em;"></i> Windows 使いの <i class="fa fa-apple" style="font-size:1em;"></i> Mac 初導入
## <i class="fa fa-cubes" style="font-size:1em;"></i> 概要
Windows 使いの Mac 初導入

## <i class="fa fa-history" style="font-size:1em;"></i> 経緯
公私ともにメイン OS として Windows を使ってきたのですが、
CUI を中心としたツール類を利用した生産性の高いツール類を導入していくうちに、

* このツールは、 Windows だと動かない
* このツールは、 Windows だと設定手順が増える
* このツールは、 Windows だけバグる

など、つらい状況が増えてきました。

そこで、 Mac への移行を決断しました。
段階的に Mac に移行するために、まずは Macbook Pro を購入しました。
ここで慣らしてから デスクトップも Mac に移行していこうかと思っています。

今後、似たような道を辿る方のために移行時に行ったことを書き残して行こうと思います。
( 今後、自宅のデスクトップ PC に Mac を導入したり、
会社でも  Mac を導入したりするようなことがあった場合の
資料としての意味合いもあります )

基本的に

「Windows でやってたアレは Mac でどうやるの」

という視点でまとめます。

単純な Mac の機能紹介なら既に良情報は大量にあると思いますので。

## :books: まとめ記事
以後、こちらに記事をまとめていきます。

<i class="fa fa-external-link-square" style="font-size:1em;"></i> [Windows 使いの Mac 初導入 まとめ](http://qiita.com/tbpgr/items/1043457aa0604e7131b9)

## :memo: 補足
※この記事ではなく、別の記事のまとめる理由ですが
Qiita のタグを元に一覧記事を生成する qiita_matome という自作ツールを利用しているためです。
手動で一覧を更新したくないのが理由です。

qiita_matome は Ruby の gem です。
気になる方は、下記を参照ください。

<i class="fa fa-external-link-square" style="font-size:1em;"></i> [Qiitaの特定ユーザー・特定タグの記事をテーブル形式のまとめ記事として生成する QiitaMatome gem を作ってみた](http://qiita.com/tbpgr/items/36089a184aa0bd7d7954)
C#で作成されたdllから文字列を抽出する

タイトルにはC#、DLLと書きましたが.NetやMonoで作成されたものなら大抵大丈夫です。

今回は`Mono.Cecil`を利用してDLLから文字列を抽出しました。
`Mono.Cecil`を使用すると簡単にDLLやEXEの中身を確認したり変更したりすることができて便利です。
`Mono.Cecil`はNuGetからインストールできるので簡単に使用することができます。

```showString.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length == 1)
            {
                var assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly(args[0]);
                assembly.Modules
                    .SelectMany(x => x.Types)
                    .ToList()
                    .ForEach((type) =>
                {
                    showString(type, assembly);
                });
            }
            else
            {
                Console.WriteLine("引き数にdllかexeを指定してください。");
            }
        }

        static private void showString(Mono.Cecil.TypeDefinition type, Mono.Cecil.AssemblyDefinition assembly, string prefix = "")
        {
            if (prefix != "")
            {
                prefix += ".";
            }
            if (type.Namespace != "")
            {
                prefix += type.Namespace + ".";
            }
            prefix += type.Name;

            type.NestedTypes.ToList().ForEach(x => {
                showString(x, assembly, prefix);
            });

            type.Methods.ToList().ForEach((method) =>
            {
                var lineCount = 0;
                if (method.HasBody)
                {
                    method.Body.Instructions.ToList().ForEach(inst =>
                    {
                        if (inst.OpCode == Mono.Cecil.Cil.OpCodes.Ldstr)
                        {
                            if (lineCount == 0)
                            {
                                Console.WriteLine(string.Format("{0}.{1}:", prefix, method.Name));
                            }
                            Console.WriteLine(string.Format("{0}:{1}", lineCount, inst.Operand.ToString()));
                            lineCount++;
                        }
                    });
                }

                if (lineCount != 0)
                {
                    Console.WriteLine();
                }
            });
        }
    }
}

```

このプログラムでこのプログラムから文字列を抽出すると以下のようになります。

```text
ConsoleApplication2.Program.<>c__DisplayClass3.<Main>b__0:
0:

ConsoleApplication2.Program.<>c__DisplayClass8.<>c__DisplayClassb.<showString>b__7:
0:{0}.{1}:
1:{0}:{1}

ConsoleApplication2.Program.Main:
0:引き数にdllかexeを指定してください。

ConsoleApplication2.Program.showString:
0:
1:.
2:
3:.


```

## 参考
[How to search for a string in a compiled assembly using Reflection or Mono.Cecil?](http://stackoverflow.com/questions/21910322/how-to-search-for-a-string-in-a-compiled-assembly-using-reflection-or-mono-cecil)
『徹底攻略Rails4技術者認定シルバー試験問題集』第2章の勉強メモ

『[徹底攻略Rails4技術者認定シルバー試験問題集](http://www.amazon.co.jp/dp/4844337238/chintara-22)』第2章「Active Record」の勉強メモです。随時更新します。

# 第2章 Active Record

## 問1

* モデルのテストデータは、フィクスチャファイルに YAML 形式で記述する

## 問2

* rails generate model コマンドのフィールド定義部分で decimal 型が指定できる
 * 「decimal{5,2}」は、全体桁数5桁、うち小数点以下桁数2桁である数値を表す
* 同じくフィールド定義部分で、データ型の後ろに「:uniq」を指定すると、そのフィールドに一意性制約が設定される

## 問3

* PosgreSQL のネットワークアドレス型（inet、cidr、macaddr）に対応している
 * inet、cidr は IPAddr クラス、macaddr は String クラスで表現される

## 問4

* コールバックの呼び出し順は下記の通り
 * 作成時：before_validation → after_validation → before_save → around_save → before_create → around_create → after_create → after_save
 * 更新時：before_validation → after_validation → before_save → around_save → before_update → around_update → after_update → after_save
 * 削除時：before_destroy → around_destroy → after_destroy

## 問5

* rake db:seed コマンドで初期データが投入できるが、既存データは削除されない
 * 既存データを削除したい場合は rake db:setup する

## 問6

* モデルの composed_of メソッドで、モデルの属性とバリューオブジェクトの関連を指定できる
 * mapping オプションで対応関係を、class_name オプションでバリューオブジェクトのクラス名を指定できる

## 問9

* モデルの has_many メソッドの through オプションで、多対多の関連が指定できる
 * 中間部分のモデル名は任意に指定できる
 * 中間部分のモデルには任意の属性を追加できる

## 問10

* モデルの has_and_belongs_to_many メソッドで、多対多の関連が指定できる
 * 結合テーブル名は2つのモデルの複数形の名称をアルファベット順に「_」でつないだもの（Group モデルと User モデルなら「groups_users」）
 * 結合テーブルには2つのモデルの外部キー以外のカラムは持たせない
 * 中間部分のモデルは作らない

## 問11

* rails generate コマンドで、データ型に references{polymorphic} を指定することで、ポリモーフィック関連の記述を含むモデルとマイグレーションを生成できる
 * マイグレーションで「t.references :hogehoge, polymorphic: true」と記述するのは、「t.integer :hogehoge_id」と「t.string :hogehoge_type」を記述するのと同等
 * 中間テーブルは作らない

## 問12

* モデルの save メソッドは、バリデーションエラーがあったら false を返す
 * save! メソッドは、バリデーションエラーがあったら例外を発生させる
* モデルの valid? メソッドで、任意のタイミングでバリデーションできる

## 問13

* presence バリデーションヘルパーで、フォームの対応フィールドに値が入力されていることを検証できる
* absence バリデーションヘルパーで、フォームの対応フィールドに値が入力されていないことを検証できる

## 問14

* exclusion バリデーションヘルパーで、フォームの対応フィールドに入力された値がリストに含まれないことを検証できる
 * リストは「validates :foo, exclusion: { in: ['bar', 'baz'] }」、「validates :foo, exclusion: ['bar', 'baz']」のように指定する

## 問15

* acceptance バリデーションヘルパーで、フォームの対応チェックボックスがチェックされていることを検証できる
* confirmation バリデーションヘルパーで、フォームの対応する2つのフィールドに同一の内容が入力されていることを検証できる
 * 再入力用のフィールド名は、元のフィールド名に「_confirmation」を付けたもの
 * 再入力用のフィールドは、デフォルトで必須とはならない（必須にしたければ presence ヘルパーを使う）

# リンク

* [第1章の勉強メモ](http://qiita.com/iwamot/items/9c6983af9ad4c9b68788)
travisでpython-mecabを動かしたい時の設定


Pythonで形態素解析をしたい時、とりあえずMeCabを使うときがある。ただこのMeCab、`pip install MeCab` みたいに1行書けばすぐに使える楽な物では無いので、他の環境で動かしたい時にやや面倒。何度か試行錯誤したのでメモ。

## 方針

- Virtualenvを使う
- システムに `apt-get install python-mecab` で入れた物を使わない

## 設定

システムにインストールするmecabは全てバージョンを指定する。

```yml:.travis.yml
before_install:
  - sudo apt-get update -qq
  - wget http://ftp.sjtu.edu.cn/ubuntu/pool/universe/m/mecab/libmecab2_0.996-1.1_amd64.deb
  - sudo dpkg -i  libmecab2_0.996-1.1_amd64.deb
  - wget http://ftp.sjtu.edu.cn/ubuntu/pool/universe/m/mecab/libmecab-dev_0.996-1.1_amd64.deb
  - sudo dpkg -i libmecab-dev_0.996-1.1_amd64.deb
  - wget http://ftp.sjtu.edu.cn/ubuntu/pool/universe/m/mecab/mecab-utils_0.996-1.1_amd64.deb
  - sudo dpkg -i mecab-utils_0.996-1.1_amd64.deb
  - sudo apt-get install -y mecab-ipadic-utf8
language: python
python:
  - "2.7"
install:
  - "pip install -r requirements.txt"
script: "python tests.py"
```

```requirements.txt
https://mecab.googlecode.com/files/mecab-python-0.996.tar.gz
```

## 結果

動いた
https://travis-ci.org/hagino3000/mecab-deploy-test
HiveMQ で WebSocket を port 80 で起動しようとしてエラーですぐに停止してしまう時の対処

#現象
port 80 を使っているプロセスはいないはずなのに以下のエラーになる。
"ERROR - Could not bind to all interfaces and port 80, because it is already in use. Stopping HiveMQ."

#結論
少しお行儀が悪いのかもしれませんが root で起動できました

#経緯
cofiguration.properties で

```configuration.properties
websockets.enabled=true
```

と設定すると Websocket を有効になります。デフォルトでは port=8000 なのですが、これを以下のように port=80 に変更すると掲題のエラーで起動直後にとまってしまいました

```configuration.properties
websockets.port=80
```

hivemq.log ファイルを見るとこんな感じです

```hivemq.log
2014-12-26 18:43:50,337 INFO  - Starting on all interfaces and port 1883
2014-12-26 18:43:50,377 INFO  - Starting with Websockets support on all interfaces and port 80
2014-12-26 18:43:50,383 INFO  - Shutting down HiveMQ
2014-12-26 18:43:50,383 INFO  - Closing all connections
2014-12-26 18:43:50,393 ERROR - Could not bind to all interfaces and port 80, because it is already in use. Stopping HiveMQ.
2014-12-26 18:43:50,402 INFO  - All connections closed in 19 ms
```

なにか起動してたっけ？と lsof コマンドで確認

```bash:
lsof -iTCP:80
```
80で Listen しているプロセスが何もない。なんで？？？
forum で教えてもらった[こちら](http://www.hivemq.com/docs/hivemq/2.1.1/#hivemqdocs_using_ports_between_1_and_1024_on_linux_machines)をもう一度みて見て納得。単にエラーメッセージが適切でなくテキトーなだけ（よくあることですね）で、本当の原因は 80 番ポートだから root 権限が必要だったんですね。で、その手順で authbind の設定をするのですが現象がかわらない。？？？

そこで、hivemq の初期化スクリプトを確認してみると、上の手順の sed で書き換えてる行がないというか、run.sh なんか呼んでない...

```/etc/init.d/hivemq
do_start()
{
    # Return
    #   0 if daemon has been started
    #   1 if daemon was already running
    #   2 if daemon could not be started
    start-stop-daemon --start --quiet --chuid $DAEMON_USER:$DAEMON_GROUP --pidfile $PID_FILE --make-pidfile \
        --background --oknodo --exec $DAEMON -- $DAEMON_ARGS
    return $?
}
```

とりあえず --exec の前に authbind をつけたり試行錯誤したりするもうまくいかないので、諦めて root で起動するように変更して無事にport=80で起動しました

```/etc/init.d/hivemq
#DAEMON_USER=hivemq
#DAEMON_GROUP=hivemq
DAEMON_USER=root
DAEMON_GROUP=root
```

#感想
これで動くのでしばらくこれで運用することにします。
本当はどうするのが行儀がよかったのでしょうかね？