OmniAICreator/Qiita-1.07M huggingface dataset:
パッケージ名は、単数形？複数形？

[Should package names be singular or plural?](http://programmers.stackexchange.com/questions/75919/should-package-names-be-singular-or-plural) をざっと翻訳 (as of 2013.8.31)

> 訳注：意外と見逃しがちなネームスペースの単数形と複数形の問題。比較的シンプルにまとまったQAを見つけたので訳してみました(コメントは訳していません。java.beans は例外であったり、リレーションについては異論があったりするようです)。

# Question (42 votes) by NickC

しばしば、ライブラリにおいてパッケージはひとつの概念で構成されるクラス群を含みます。たとえば、 **xml** 、 **sql** 、 **user** 、 **config** 、 **db**です。皆さん、至って自然にこれらのパッケージ名は単数であることが正しいと感じるのではないかと思います。

>com.myproject. **xml** .Element
>com.myproject. **sql** .Connection
>com.myproject. **user** .User
>com.myproject. **user** .UserFactory

しかし、もし、同一タイプの実装の集まりを含むようなパッケージの場合、たとえば、 **tasks**、 **rules**、 **handlers**、 **models** などですが、以下のどちらが好ましいですか？

>com.myproject. **tasks** .TakeOutGarbageTask
>com.myproject. **tasks** .DoTheDishesTask
>com.myproject. **tasks** .PaintTheHouseTask

または

>com.myproject. **task** .TakeOutGarbageTask
>com.myproject. **task** .DoTheDishesTask
>com.myproject. **task** .PaintTheHouseTask

# Answer (54 votes) by Matthew Rodatus

_**同質な(homogeneous、ホモジーニャス、ホモ)内容で構成されるパッケージには複数形を使い、異種混合な(heterogeneous、ヘテロジーニャス、ヘテロ)内容で構成されるパッケージには単数形を使うこと**_

クラスはデータベースのリレーションに似ています。データベースのリレーションは単数形の名前がつけられべるべきです。なぜなら、そのレコードはリレーションのインスタンスとみなされるからです。リレーションの役割とは、単純なデータから複雑なレコードを構成することです。

一方で、パッケージはデータの抽象化ではありません。パッケージはコードの組織化と名前衝突の解決を支援します。もし、パッケージが単数形であれば、それぞれのメンバーはパッケージのインスタンスでないことを意味します。そのときパッケージは関係するけれども異質な概念を含むのです。もし、パッケージが複数形であれば(よくあるケース)、パッケージが同質な概念を含むことを期待します。

たとえば、Task のインスタンスを含むコレクションである時、型の名称は、"TasksCollection" ではなく、 "TaskCollection" であるべきです。com.myproject.task という名称のパッケージならば、含まれるクラスは task のインスタンスではありません。TaskHandler や TaskFactory といったものでしょう。一方で、com.myproject.tasks という名称のパッケージは、すべて Task であるが異なる型を含むでしょう。たとえば、TakeOutGarbageTask や DoTheDishesTask などです。
String.prototype.indexOfって結構速いみたい

こんなSuffixArray（ハッシュ使ってるけど）を作ってみた。

```js:suffixarray.js
function SuffixArray(str) {
  var
  i, c, sa = {};
  this.str = str;

  for (i = 0; c = str.charAt(i); i++) {
    (sa[c] || (sa[c] = [])).push(i);
  }
  this.sa = sa;
}

SuffixArray.prototype.search = function (word, start) {
  if (!word) return 0;
  start = start || 0;

  var
  i,
  is = this.sa[word.charAt(0)], l = (is || []).length;

  for (i = 0; i < l; i++) {
    if (is[i] >= start && this.str.substr(is[i], word.length) === word) return is[i];
  }
  return -1;
}
```

SuffixArrayって言うとバイナリサーチが一般的な気がするけど、バイナリサーチよりハッシュの方が速い（し書くのが楽）に決まってるのでハッシュで書いてみた。（JavaScriptのオブジェクトをハッシュと呼んでいいのか？）

で、`String.prototype.indexOf`と、ついでに`String.prototype.search`(正規表現版indexOf)で速度を比較してみる。
[jsPerf](http://jsperf.com/)というのがあるのを知ったので、そこでやってみた。

ここにあります↓。
[String.prototype.indexOf vs String.prototype.search(RegExp) vs my SuffixArray · jsPerf](http://jsperf.com/indexof-vs-search-vs-suffixarray)

結果は、

![jspref1.jpg](https://qiita-image-store.s3.amazonaws.com/0/11219/3425f122-369b-6a5b-6fe7-36b02b1a4ff9.jpeg)

という感じです。Opera 17って何だよ、って感じですが中身は八割ぐらいChromeなのでChromeだと思えばいいはずです。

これ、長いほど速いみたいなので、indexOfが一番速いということになります。しかもSuffixArrayより倍以上速いです。

うーん、`indexOf`って線形探索じゃないんだろうな…。

ちなみにFirefoxでもほぼ同じ結果でした（時間は八倍ぐらいかかりましたが）
コマンドプロンプトのfcコマンド

windowsのコマンドプロンプトでファイル比較を行う場合、fcコマンドを使用すると思いますが、
よくわからない挙動をしました。

～手順～

①比較するファイルを2つ用意する。
　改行とか文字コードとか細かい部分の差異がでるといけないのでtest.txtを作成したあとに
　文字列をコピーするのではなくファイルをコピーしてファイル名をリネームする

```
D:\>
D:\>type test.txt
aaa
bbb
ccc

D:\>type test2.txt
aaa
bbb
ccc

D:\>
```

②この時点で差異がないことを確認する

```
D:\>
D:\>fc /n test.txt test2.txt
ファイル test.txt と TEST2.TXT を比較しています
FC: 相違点は検出されませんでした


D:\>
```

③test2.txtを編集する。
　これも改行コードとか他のものが変わらないように真ん中の文字を変更（ccc　⇒　cdc）

```
D:\>
D:\>type test2.txt
aaa
bbb
cdc

D:\>
```

④ファイルを再度比較する。

```
D:\>
D:\>fc /n test.txt test2.txt
ファイル test.txt と TEST2.TXT を比較しています
***** test.txt
    2:  bbb
    3:  ccc
***** TEST2.TXT
    2:  bbb
    3:  cdc
*****


D:\>
```

となります。
予想では3行目だけ差異が検出されると思ってますが、
実際には2行目も差異が検出されているようです。

これってなんででしょう。

単純に差異が出たところの上下の行も表示する仕様？
Chromeをシークレットウィンドウで起動する

ブラウザでChromeを使用している人は多いと思いますが、
このブラウザにはシークレットウィンドウというモードが存在します。

ブラウザを閉じる際に履歴なども削除されるのでweb開発時に重宝するんですが、いちいちブラウザを開いてから「新しいシークレットウィンドウを開く」を選択するのがめんどいです。

ということでデスクトップ上のアイコンをクリックしたときにいきなりシークレットウィンドウで開くようにできたらいいなと思っています。

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
調べるとWindowsでは以下の方法でできます。

デスクトップアイコンを右クリックする
プロパティを開く
リンク先の部分の最後に「--incognito」を追記する

以上でできます。
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

これと同様にmacとandroidでもシークレットウィンドウで起動したいのですが
何か方法はあるのでしょうか。
Railsのモデル関係図を自動的に吐き出してくれるRails ERDをRails4,ruby2.0で使う

自分で書いたはずのソースコードなのに2週間ぶりに見たら何がどうなってるかまったく記憶に残っていませんでした。

まずはモデルの関係でも確認しようとしたけど、いちいちテキストファイルを一つずつ開いて確認するのはめんどくさいので、モデル図を自動生成するRails ERDを試して見ることにしました。

ところが公式サイトの説明にはRails3、ruby1.8,1.9に対応という事で Rails4,ruby2.0で使いたい自分の環境にはあわないらしい、困った。

ダメ元でとりあえずインストールして見ることにしました。これを書きながらインストール作業してるので成功するかどうかはまだわかっていません。

## 環境

Ubuntu１２.04
Rails4
ruby2.0

## Graphvizのインストール

`$ sudo apt-get install graphviz` でインストール

インストールしたバージョンを確認しようと思って `$ graphviz -v` ってしてみたけどプログラムがないと怒られる。
調べてみると graphviz を使うには `dot` というコマンドを使うらしいので `$ dot -V` でバージョンが 2.2 より上だと確認しておく。

（ImageMagickもコマンドは `convert` とかだし、こういうのってLinuxだと結構多いのかな？）

## Gemfile に rails-erd を追記

```Ruby:Gemfile
group :development do
  gem "rails-erd"
end
```
とGemfileに書いておいて、いつもどおり `$ bundle install` しておく

## 試してみる

プロジェクトフォルダに移動して `$ rake erd` すると、無事にインストールできてるなら `erd.pdf` が出力される。

`$ evince erd.pdf` で開いて無事に生成されてることを確認して便利さに感動すれば作業は完了！

(2013-09-05 追記)
mac の場合は `$ open erd.pdf` で開けます。

## まとめ

結局Railsやrubyのバージョンが変わっても何の変更もせずにそのまま使えるようです。

## 参考

Rails ERD – Installation instructions
http://rails-erd.rubyforge.org/install.html

Linux系OSでpdfをコマンドラインから開く - Knowledge On Karai
http://blog.livedoor.jp/techrebornpublic/archives/52009667.html
apt-get で Chrome入れたら Duplicate sources だと怒られた時の対処法

Ubuntuにaptを使ってChromeを入れたかったので、Googleの公式に書いてある解説どおりにパッケージの提供者リストにGoogleを追加すると、こんなエラーに出くわすという理不尽な仕打ちを受ける模様。

>W: Duplicate sources.list entry http://dl.google.com/linux/chrome/deb/ stable/main i386 Packages (/var/lib/apt/lists/dl.google.com_linux_chrome_deb_dists_stable_main_binary-i386_Packages)
>W: You may want to run apt-get update to correct these problems

ダブってるパッケージのソースリストを

`$ sudo rm /etc/apt/sources.list.d/google.list`

で削除すればエラーは消える。

このパッケージを提供してくれるそれぞれのソース呼び方は「パッケージのプロバイダー（提供者）」でいいのかな？
特定の呼び方はないんだろうか？


## 参考
Linux Mint Forums • View topic - duplicate sources.list entry- howto correct ?
http://forums.linuxmint.com/viewtopic.php?f=47&t=99093
s3cmdでファイルを暗号化して保存する

[s3cmdを使ってEC2からS3にDBバックアップ][s3cmd-backup]という素晴らしい記事を見ながら[s3cmd][s3cmd]の設定している時に、「Encryption password」という項目があったのが気になったので確認してみた。

---

まず、パスワードあり版の設定をする。

    $ s3cmd -c ./.s3cfg-encryption --configure

これで`./.s3cfg-encryption`というファイルが出来て、途中で入力した「Encryption password」が書かれているのだけど、これだけでは暗号化する設定になっていないので、ファイルを開いて、

    encrypt = False

となっている所を

    encrypt = True

に書き換えておく。

---

次に、パスワード無し版の設定をする。

    $ s3cmd -c ./.s3cfg-no-encryption --configure

---

今回暗号化するファイルを準備する。


    $ echo 'This is a secret file' > secret.txt

---

で、確認。

パスワードあり設定を使ってファイルをS3に置く。

    $ s3cmd -c ./.s3cfg-encryption put ./secret.txt $BUCKET

パスワード無し設定を使ってダウンロードする。

    $ s3cmd -c ./.s3cfg-no-encryption get $BUCKET/secret.txt ./downloaded-encrypted.txt
    $ cat ./downloaded-encrypted.txt
    （暗号化されている）

パスワードあり設定を使ってダウンロードする。

    $ s3cmd -c ./.s3cfg-encryption get $BUCKET/secret.txt ./downloaded-decrypted.txt
    $ cat ./downloaded-decrypted.txt
    This is a secret file

というわけで、パスワードを平文で保存しているようなデータベースのバックアップでも、ある程度安心してかつ簡単にS3を使えますね。

---

あと、パスワードが分かっていれば`gpg`コマンドで直接復号することもできます、勿論。

    $ gpg -d ./downloaded-encrypted.txt
    （パスワード入力）
    This is a secret file

[s3cmd-backup]: http://qiita.com/hilotter/items/94765ee7be61e30ba67f
[s3cmd]: http://s3tools.org/s3cmd
[Pixelmator] オシャレぼかし画像の作り方 3Step


海外のおしゃれ系アプリで背景とかスプラッシュとかによく使われてる

![bg.png](https://qiita-image-store.s3.amazonaws.com/0/3063/f3a9cbea-ce94-8f17-7b7a-796a30ef685b.png)

なんかこういうやつをプログラマーだって作らないといけないときがある。
Pixelmatorで。そうです、Photoshopを買えないぐらいには貧しいです。

## 1. 丸を何個か書く

適当なサイズで新しいキャンバスを作ったら[⌘3]でエフェクトブラウザを表示。「焦点ぼけ」をタブルクリック。

![ss2.png](https://qiita-image-store.s3.amazonaws.com/0/3063/1d251603-d8dc-44f8-9fe4-6f351b9daec9.png)

なんか出てくるのでそれっぽく値を入れてみる。あとでぼかすので「ブラー」は0でもいい。色は
http://paletta.mrk1869.com/
この辺から2色えらぶ。

![ss1.png](https://qiita-image-store.s3.amazonaws.com/0/3063/979fbe49-7279-9be2-2641-3ac809e1f796.png)

## 2. グラデーションっぽい色をつける

エフェクトブラウザから「ライトリーク」を選んでダブルクリック。「星雲」を選んで「日照量」は適当に。50%前後がそれっぽい気がする。

![ss4.png](https://qiita-image-store.s3.amazonaws.com/0/3063/53b7c8ec-22a4-964d-80c5-fc9be2d383c6.png)

キャンバスの上に白い円の上に黒い点みたいのが出てくるので、それを動かすと角度と大きさが変えられる。ほどよさそうなところまで大きくする。

![ss5.jpg](https://qiita-image-store.s3.amazonaws.com/0/3063/a413b722-4118-1a64-ad4b-86c1fc55c5b0.jpeg)

## 3. ぼかす

エフェクトブラウザで「ズーム」を選択。「量」を1.0から1.8ぐらいの間で程よさそうな値に変更すると

![bg.png](https://qiita-image-store.s3.amazonaws.com/0/3063/f3a9cbea-ce94-8f17-7b7a-796a30ef685b.png)

ができる。

## 結論

センスがないようなのでフリーで使える画像をググりましょう。
plenvのchefのcookbook

perl-buildまでやるやつ書いた。

参考元：[plenvによるPerl環境を構築するchefのオレオレサンプルレシピ - hirobanex.net](http://hirobanex.net/article/2013/06/1372382206)


[https://github.com/kenjiskywalker/mychefrepo/tree/master/site-cookbooks/plenv](https://github.com/kenjiskywalker/mychefrepo/tree/master/site-cookbooks/plenv)  
  
これでchef使って一撃でPerlの環境用意できます。
「第5回オフラインリアルタイムどう書くの参考問題」をPHPで解く

http://qiita.com/Nabetani/items/0ddde0164a745cd09c34
http://nabetani.sakura.ne.jp/hena/ord5railsontiles/

懐かしチクタクバンバン。
ただしこちらはパネルは動きません。
進むラインを求めます。

```php
<?php
	class TICKTUCK{

		// 入力方向から次の入力方向を求める ←0↑1→2↓3
		private $panel = [
			0=>[0=>0, 1=>1, 2=>2, 3=>3],
			1=>[0=>1, 1=>0, 2=>3, 3=>2],
			2=>[0=>3, 1=>2, 2=>1, 3=>0],
		];
		
		// 入力方向による現在値の変化 ←-1↑-13→+1↓+13
		private $direction = [0=>1, 1=>13, 2=>-1, 3=>-13 ];
		
		// 侵入許可パネル
		private $okPanel = [10=>1, 11=>1, 12=>1, 23=>1, 24=>1, 25=>1, 36=>1, 37=>1, 38=>1];
		
		/**
		* チクタクバンバン
		* @param  String 「101221102」みたいな文字列
		* @return String 「BEDGHIFEH」みたいな文字列
		*/
		public function get($input){
			// 現在地
			$nowPanel = 11;
			// 現在の方向
			$nowDirection = 1;
			// 進んだ順
			$ret = '';
			
			do{
				// 現在地
				$ret .= chr(65 + $nowPanel%10);
				// 次の方向を求める
				$nowDirection = $this->panel[$input[$nowPanel%10]][$nowDirection];
				// 次の現在地を求める
				$nowPanel += $this->direction[$nowDirection];
			
			// 進める限り繰り返し
			}while(isset($this->okPanel[$nowPanel]));
			
			return $ret;
		}
	}
	
	// テスト
	$test = [
		['101221102','BEDGHIFEH'],
		/* 省略 */
	];

	$ticktuck = new TICKTUCK();
	foreach($test as $key=>$data){
		$answer = $ticktuck->get($data[0]);
		if($answer !== $data[1]){
			print('えらー');
		}
	}
```

パネルのA～Iをそれぞれ0～8に割り当て、パネルの形状によって移動する次のパネルを求める、という基本的には単純な作りです。
ただ普通に0～8とすると2→3の移動がOKとみなされてしまうため、侵入許可パネルという微妙なプロパティを作る羽目になりました。
あとPHPは
	private $okPanel = array_flip([10, 11, 12, 23, 24, 25, 36, 37, 38]);
とか書けないから微妙にめんどい。

かかった時間は1時間くらい。
完成した後で考えなおしてみたら'ABC-DEF-GHI'の位置とかでやったほうがずっと簡単そうだった。
まあいいか。
Operaのキーボードショートカット設定ファイルで"(ダブルクオート)が使えない問題

# 問題

Operaのキーボードショートカット設定ファイルで

```
a="Go to page, "javascript:alert(0);""
```

などとすると任意のjavascriptを実行するブックマークレットを１keyショートカットに設定することができますが、
この設定ファイルにおいて"(ダブルクオート)が特殊文字扱いになっているため、
javascriptのストリングリテラルをつくるのにシングルクオートしか使えないという事になっています。

じゃあシングルクオート縛りでjs書けばいいじゃんと思いきや、JSONにおける文字列型はダブルクオートしか使ってはいけないという制約があります。

というわけで、この設定ファイル内のjavascriptでvalidなjsonを文字列として含めたいという場合、困ります。

# 解決策

```js:
var dq=String.fromCharCode(34);
```
とすることでダブルクオートを含んだ文字列を表現することができます。

以下具体例

```
a="Go to page, "javascript:(function(){var dq=String.fromCharCode(34);var i=new Image();i.src='http://fluentd/tag?json='+'{'+dq+'title'+dq+':'+dq+escape(document.title)+dq+','+dq+'url'+dq+':'+dq+escape(location.href)+dq+'}';document.body.appendChild(i);})();""
```

-----

誰かの役に立つんだろうかこのノウハウ
ubuntu server で、ミュートを解除する方法

ずっと悩んでたがさすがArchWiki様。[参考](https://wiki.archlinux.org/index.php/Advanced_Linux_Sound_Architecture_(%E6%97%A5%E6%9C%AC%E8%AA%9E)#.E3.83.81.E3.83.A3.E3.83.B3.E3.83.8D.E3.83.AB.E3.81.AE.E3.83.9F.E3.83.A5.E3.83.BC.E3.83.88.E3.82.92.E8.A7.A3.E9.99.A4.E3.81.99.E3.82.8B)

```bash:
$ amixer sset Master unmute
```
JPEGファイルのEXIFヘッダは危険（かもしれない）

　これ以上ない小ネタですｗ

　JPEGファイルのEXIFヘッダは、位置情報を埋め込んだりできて便利（？）ですが、先日このEXIFヘッダにPHPコードを仕込むマルウェアが発見されており、画像を自由に登録できるサービスを提供している場合は注意が必要です。
（実際には、この方法でサイトの閲覧者に任意のコードを実行するにはEXIFヘッダに埋め込まれたコードを取得＆実行するスクリプトを事前にサーバに配置しておかなければならないため、危険度はそれほど高くはないと思われます）

　ただ、ジオタグ（位置情報）など、個人情報が含まれる画像が意図せずアップロードされることは可能性としてあると思いますので、サービス側としては不要なEXIFタグは削除して登録したいものです。

こういう場合、対応手段としては

- コマンドで一括して削除する
- [PHP Exif Library](http://lsolesen.github.io/pel/)などEXIFヘッダを読み書きできるライブラリを使い削除する

といった方法が考えられますが、一般的にはどうするものなのでしょうか？

　とりあえず、ライブラリは使いたくない、コマンドも嫌だという人のために、GDを利用したEXIFヘッダ削除関数を作成してみました。

```php:jpeg_clean.php

<?php
function jpeg_clean( $src_file, $dest_file, $quality = 90 )
{
	$info = getimagesize($src_file);

	if ($info === false) {
		throw new Exception('画像ファイルではありません。');
	}

	if ( !is_numeric($quality) || $quality < 0 || $quality > 100 ){
		throw new Exception('品質は０～１００の間で指定してください。');
	}

	// 幅と高さ、画像の種類を取得
	list( $width, $height, $type ) = $info;

	// JPEG画像か確認する
	if ( $type != IMAGETYPE_JPEG ){
		throw new Exception('JPEG画像ではありません。');
	}

	// 画像リソースを生成
	$img = imagecreatefromjpeg($src_file);
	if (!$img) {
		throw new Exception('画像リソースの生成に失敗しました。');
	}

	// 画像ファイルを作成
	$copy_img = imagecreatetruecolor($width, $height);
	imagecopyresampled($copy_img, $img, 0, 0, 0, 0, $width, $height, $width, $height);
	if (!imagejpeg($copy_img, $dest_file, $quality)) {
		throw new Exception('JPEG画像の変換に失敗しました。');
	}
}
function get_exif($file)
{
	return print_r(exif_read_data($file),true);
}

$src_file  = isset($argv[1]) ? $argv[1] : NULL;
$dest_file = isset($argv[2]) ? $argv[2] : NULL;
$quality   = isset($argv[3]) ? $argv[3] : NULL;

try{
	if ( !$src_file || !$dest_file ){
		throw new Exception( "入力および出力画像ファイルを指定してください" );
	}
	if ( !$quality ){
		$quality = 90;
	}
	echo "EXIF情報（変換前）:" . get_exif($src_file) . PHP_EOL;
	jpeg_clean( $src_file, $dest_file, $quality );
	echo "変換成功:$dest_file" . PHP_EOL;
	echo "EXIF情報（変換後）:" . get_exif($dest_file) . PHP_EOL;
}
catch( Exception $e ){
	echo $e->getMessage() . PHP_EOL;
	echo "usage:" . PHP_EOL;
	echo "jpeg_clean in-file out-file [quality]" . PHP_EOL;
}

```

関数だけ使いたい場合は、jpeg_cleanだけコピーしてください。コマンドラインから使う場合は以下のようにもできます。

```php:コマンドラインから使う

php jpeg_clean.php in.jpg out.jpg 85

```

関数、コマンドラインともに第１引数に元画像のパス、第２引数に出力先のパス、第３引数に画像品質（100が最高ですがファイルサイズが大きくなる）を指定してください。

削除の仕組みですが、ただ単にimagecreatefromjpegで空のイメージを作って、ビットマップデータをコピーするだけです。imagejpegでファイルとしてセーブする際、少しだけヘッダを出力しますがほぼ空の状態です。
（僕の環境ではCOMMENTセクションに「CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 90」などと記録されていました）

１００にしても品質を保持することはできない（どころか大抵ファイルサイズが増えてしまう）のですが、qualityに８５～９０を指定しておけばかなりいい感じになると思います（適当）。
EXIFヘッダにでかいデータが入っていた場合は、ファイルサイズの削減にもなり一石二鳥（？）。

ちなみに、画像処理に関しては下記の記事を参考にさせていただきました。感謝。

アップロードされた画像ファイルをリサイズして保存するサンプル:
http://qiita.com/mpyw/items/73ee77a9535cc65eff1e
ttyrec でターミナルの録画・再生

プレゼンの中でデモを行おうと思ったが、処理に時間がかかって時間内に収まりそうにないということで、そういえばと昔々使った `ttyrec` で録画しておいて倍速再生することを思いついたのでその手順をメモっておきます。

環境は  CentOS 6.4 x86_64 です。（32bit なら rpm も転がってるし、make で困ったりしない）

[ttyrec](http://0xcc.net/ttyrec/ "ttyrec") は高林哲さんが2000年から2006年に書かれたソフトウェアです。

ちょっと古いので今時の環境ではちょっと手を入れてあげないと動きませんでした。

```bash
$ sudo yum -y install compat-glibc-headers
$ git clone git://git.kitenet.net/ttyrec.git
$ cd ttyrec
$ make CFLAGS="-DSVR4 -D_XOPEN_SOURCE=500 -I/usr/lib/x86_64-redhat-linux5E/include"
```

これで `ttyrec` と `ttyplay` と `ttytime` コマンドがコンパイルされました。
 PATH の通った任意の場所にコピーするなりしてください。

```
$ ttyrec aaa
```

で、以降 Ctrl-D で抜けるまで引数で指定したファイル（上記の場合 `aaa`） というファイルに録画されます。再生は

```
$ ttyplay aaa
```

で行います。`-s N` でN倍速再生することができます。
再生中に `f` や `s` をタイプすることで再生速度を速くしたり、遅くしたりできます。
マニュアルページもあるので使い方はそちらを参照。man 用のディレクトリにコピーしなくても

```
$ nroff -man ttyplay.1 | less
```

で読めます。

コンパイルはこちらを http://pastebin.com/Mm7cUr1L 参照しました。
dictをarrayに変換


特徴量をdictで持っている時に、scipyとかscikit-learnで使うようなarray形式のベクトルにしたい時

```
from sklearn.feature_extraction import DictVectorizer

features = [{"poko":2, "hoge":1}, {"hoge":2, "pokopoko":10}, {"poko":5, "hogehoge":1}]
vec = DictVectorizer()
array_vectors = vec.fit_transform(features).toarray()
```

でいける。特徴量のラベルを見たい時は

```
vec.get_feature_names()
```
で
svn 自分用コマンドメモ

WinはトータスSVNで事足りる。

Macで個人的にしっくりくるGUIがなく、
CUIをお勧めされたので、覚えようと思いました。
随時追加修正



* SVN導入手順　概要
MacPorts導入→Xcode導入→Xcodeコマンドラインツール導入</br>
→ターミナルからsudo port install subversion



```
//動作確認
svn --version
```
---

```
//リポジトリ作成
svnadmin create  PATH...

//例:デスクトップのsvnRepoフォルダをリポジトリに指定
svnadmin create /Users/(userName)/Desktop/svnRepo 
```

---

```
//作業領域の作成（チェックアウト）（chekout →coでも可）</br>
svn checkout URL[@REV]... [PATH]

//作業領域を作成したい場所まで移動し、コマンドを叩く（workフォルダの作業領域を作成）
 svn co file:///Users/(userName)/Desktop/svnRepo work
```

---

 
```
//ファイルの追加
svn add PATH...

//対象ファイルのディレクトリまで移動し、コマンドを叩く(A追加）
svn add sample.txt 
```

---


 
```
//ファイルの削除
svn delete PATH...

//対象ファイルのディレクトリまで移動し、コマンドを叩く(D削除）
svn delete sample.txt 
```

---


```
//編集の取り消し（属性も取り消される）
svn revert PATH...

//対象ファイルのディレクトリまで移動しコマンドを叩く
svn revert sample.txt 
```

競合状態の修正などにも使用

---

```

//コミット
svn commit 

//対象ファイルのディレクトリまで移動しコマンドを叩く（””内はコメント）
svn commit -m "サンプルボタン追加しました" 

```

---


```
//ログ確認（リポジトリに反映されたか確認）
svn log

//対象ファイルのディレクトリまで移動しコマンドを叩く
svn log sample.txt

```


---


---


```
//アップデート（作業領域更新）
svn update 

//対象ファイルのディレクトリまで移動しコマンドを叩く
svn update 

```

---

```
//作業領域のディレクトリ、ファイルの状態確認
svn update PATH...

svn status
```

---


```
//クリーンアップ
svn cleanup PATH…

```


---


* 備考
使いそうだけど今のところあまり使ってないコマンドメモ

* 作業領域、リポジトリの削除
svn delete PATH...
svn delete URL...

* ロック
svn lock TARGET...

* 差分チェック
svn diff
gollum(githubのwiki)を入れてみた

[参考サイト](http://sunnyone41.blogspot.jp/2012/11/gitwikigollum.html)

```bash:
$ sudo apt-get install git ruby-bundler 
$ git clone https://github.com/gollum/gollum
```

```bash:bundleinstallの速度アップ
$ cd gollum

以下書き換え
$ vim Gemfile
# source 'http://rubygems.org'
source 'http://bundler-api.herokuapp.com'

$ bundle install --path vendor/bundler
```

```bash:リポジトリ作成
$ mkdir ~/wikidata
$ cd ~/wikidata
$ git init
```

```bash:実行
$ cd -
$ nohup bundle exec bin/gollum --port 5080 --base-path wiki ~/wikidata &
```

あとは http://localhost:5080/wiki/ にアクセスすればOK.
WEBrickがA server is already runningの場合の対処


```
$ rails s
=> Booting WEBrick
=> Rails 3.2.14 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
A server is already running. Check /worktest/sample/tmp/pids/server.pid.
Exiting
```


```
#起動中のプロセス一覧を表示
$ ps ax
　　：
　　：
　　：
　　：
 5441 pts/0    Tl     0:06 /home/vagrant/.rbenv/versions/1.9.3-p448/bin/ruby script/rails s
 5582 ?        S      0:00 pickup -l -t fifo -u
 5855 pts/0    R+     0:00 ps ax

```

```
#起動中のプロセスを終了
$ kill -9 5441
```
svnリポジトリをgit-new-workdirをつかって複数のbranchで運用したい

## 目標:
SVNリポジトリをgitでチェックアウトして、trunk/branchそれぞれで作業したい。
あわよくば、git-new-workdirで別個の作業ディレクトリを確保したい。
おそらく、だけど、これをやるとbranchをまたがった git cherry-pick が非常にやりやすそう。

 
で、gglってもこんな記事しか出てこない。直接ひょっとするとあんまりお勧めできないうんようなのだろうか?? まあでも以下のように作業したら、なんとなく出来た様なので、とりあえずめでたい記念にメモ。

http://stackoverflow.com/questions/9596412/how-do-i-remove-a-working-copy-created-via-git-new-workdir-without-hosing-the-or
 
 
## 0.前提 
 
svnのリポジトリは、http://somewhere/svn-repositoriesこのリポジトリには{trunk,branches,tags}と標準レイアウトである。またsvnのリポジトリにはすでにbranchがある事を前提とする（無ければ自分で作ってね ;）。

somewhere/working_dirをメインの作業ディレクトリとする。gitでいうところのmaster, svnでいうところのtrunk。

作業結果の確認にはsvnリポジトリを直接ブラウズ出来る様な仕組み(今回はUSVN)で確認しました。

  
## 1.標準レイアウト{trunk,branches,tags}のSVNリポジトリをgit svnでチェックアウト
参考: http://transitive.info/article/git/command/svn/

```shell-session
$ cd somewhere/working_dir
$ git svn clone -s http://somewhere/svn-repositories
``` 

( -sが標準レイアウトをそのままgitに適用してくれる )

 

## 2. svnのbranchで作業できるかを確認

参考: http://sessan.hatenablog.com/entry/2012/11/04/132746

branchの確認

```shell-session
$ git branch -a
* master
  remotes/origin/master
  remotes/origin/other_branch
``` 
 
svnのbranchを git のbranch 'my_branch'としてチェックアウト

```shell-session
$ git co -b my_branch remotes/other_branch
:
do something
:
$ git commit -a -m "done something"
$ git svn dcommit
``` 

するとsvnのother_branchのみ"do somethingな"変更を確認できた。

 

## 3. git-new-workdirでbranchのコピーを別ディレクトリにつくる
2の手順でローカルにremotes/other_dirのbranch,"my_branch"ができたので、これを利用する事が出来そうだ。my_branch用のディレクトリをother_dirとしようか。

```shell-session
$ git-new-workdir . ../other_dir my_branch
$ cd ../other_dir
:
do something
:
$ git commit -a -m "done something part2"
$ git svn dcommit
```
 

するとsvnのother_branchのみ"do somethingな"変更を確認できた!

元のディレクトリに戻って、master (trunk) で作業してみる

```shell-session
$cd ../working_dir
$ git co master
:
do something on master
:
$ git commit -a -m "done something on working_dir"
$ git svn dcommit
```
 
するとsvnのtrunkのみ"do something on working_dir"な変更を確認できた!

これでなんとか楽に運用できそう!!
Mountain Lion環境への「rbenv」のインストール手順 + 設定方法


## 1. はじめに

本書では、Rubyのバージョン管理をする際に使用する「rbenv」のMacOS環境でのインストール手順及び設定方法について記述します。

## 2. 前提条件

* MacOSのバージョンが 10.8.4 であること。(2013/8/30時点の最新バージョン)
* Homebrewがインストールされていること。 (バージョン : 0.9.4)

## 3. インストール手順

(1) Homebrewを使ってrbenvとruby-buildをインストールします。

```sh
$ brew install rbenv ruby-build
```

(2) rbenvのパスを追加します。

```sh
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ echo 'export PATH="$HOME/.rbenv/shims:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile
```

## 4. 設定方法

(1) 以下のコマンドを実行し、rbenvでインストールが可能なRubyのバージョンを確認します。

```sh
$ rbenv install -l
```

(2) インストールしたいRubyのバージョンを指定し、Rubyをインストールします。

```sh
$ rbenv install (バージョン名) # バージョンが1.9.3-p392のRubyをインストールする場合は 「rbenv install 1.9.3-p392」を実行します。
```

(3) 以下のコマンドを実行します。

```sh
$ rbenv rehash
```

(4) 以下のコマンドを実行し、上記のRubyがインストールされていることを確認します。

```sh
$ rbenv versions
```

(5) 以下のコマンドを実行し、MacOSでRubyが使えるように設定します。
*) ここでは「1.9.3-p392」をインストールしていることを前提にしています。必要に応じて読み替えてください。

```sh
$ rbenv shell 1.9.3-p392 # 現在実行しているシェル環境上の設定
$ rbenv global 1.9.3-p392 # システム全体の設定
```

## 5. 不要なバージョンのRubyを削除する場合

以下のコマンドを実行します。

```sh
$ rbenv uninstall -f (バージョン名) # バージョンが1.9.3-p392のRubyを削除する場合は 「rbenv uninstall -f 1.9.3-p392」を実行します。
$ rbenv rehash
$ rbenv versions # 対象のバージョンが削除されていることを確認します。
```
Backbone.Viewの不要な再描画を避けるようにする


[前回の続き](http://qiita.com/mozquito/items/bd8a2674ec9739b52de1)でもあるんですが、複数のViewが連携して再描画（render）するとき、再描画のきっかけとなったViewは再描画しなくてもいいということがあります。

色々試した結果、view.cidをrenderを呼び出すtriggerに渡してあげてcidをチェックすることで不要な再描画が避けれました。
逆にcidを管理してcidが一致したら処理といったことにも使えるかも


```ts:view.ts
class View extends Backbone.View{
	constructor(options?){
		super(options)
		this.listentTo(this.event,'render',this.render);
	}
	render(cid?){
		//cidが一致すれば何もしない
		if(this.cid == cid) return this;
		…//処理内容
		return this;
	}
	
}
View.prototype.event=_.extend({},Backbone.Events);
```

```ts:呼び出し側
var view1 = new View();
var view2 = new View();
view1.event.trigger('render',view1.cid);
//view1はrenderされない

```
AIR android / iOS 振り分け ※モバイルプラットフォーム限定

コンパイラ引数使うのがめんどくさい人のための簡易にandroid / iOS　を振り分けるためのサンプル
※desktopは含まない

```as3
import flash.system.Capabilities;

if (Capabilities.os.indexOf("iPhone") >= 0) {
	//iOSの場合の処理

}else{
      //androidの場合の処理(desktop含む)
}

```
【Unity】GUITextureの画像を真ん中に表示する２つ方法

###概要
GUIはViewPortを通じてScreenに表示します。
Screen Viewを今回は画像サイズから真ん中に表示する方法とスクリプトで真ん中に表示する方法
２つを公開します。

###今回真ん中に表示する画像
![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/18411/47f42c3b-2ba6-d5a3-fe91-a7eee64b9905.jpeg)

画像サイズは256 * 256です。

###画像サイズに合わせてスクリーンに表示する方法1
1. GameObject -> Create Other -> GUI Textureをクリック
2. ScreenViewの真ん中に表示するためにPosition X, Yに各0.5値を入れる
ScreenViewに関してはhttp://docs-jp.unity3d.com/Documentation/Components/class-GuiTexture.html
を参考してください。
![2.jpg](https://qiita-image-store.s3.amazonaws.com/0/18411/99de6afc-6051-5271-1f92-ceb5f47787d7.jpeg)

3. GUITextureのTextureに画像をDrog&Drop
4. 今回使う画像のサイズは256 * 256だからPixel InsetのWidthとHeightに256を入れる
5. Pixel InsetのXとYに画像サイズの半分-128を入れる

これでOK. 真ん中に表示される。

###画像サイズに合わせてスクリーンに表示する方法2
この方法はスクリプトで操作するため、もっと柔軟にマルチデバイスの画面にあわせることができる

1. GameObject -> Create Other -> GUI Textureをクリック
2. 以下のコードをC#で作り、コンポーネントをGUITextureにつける

```csharp:center.cs
void Start () {
    background = GetComponent<GUITexture>().texture;
}
	
void OnGUI(){
    GUI.DrawTexture(new Rect(Screen.width / 2 - 128, Screen.height / 2 - 128, background.width,   
    background.width), background);
}
```

上記の二つ方法は両方ともスクリーンに関係なく真ん中に表示してくれるが、
スクリプトで操作するのがもっと柔軟にできると思う。
CSSのmask-imageを使った表示切り替え演出

ノベルゲームの場面転換の演出アニメーションを作ってるときに書いたやつ。

グラデーションでmaskをかけると画像の透明な部分が透明になる。
maskのポジションをずらすとサーッと消えていくような表現に。

## デモ

[ここ (http://jsdo.it/nakajmg/enKV)](http://jsdo.it/nakajmg/enKV)

## コード

```html
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<style>
.wrapper{ position:relative; }
.bg1, .bg2{
	position: absolute;
	width:330px;
	height:100px;
	text-align: center;
	color:#fff;
	font-size:24px;
}
.bg1{ background-color: blue; }
.bg2{ background-color: red; }

.mask{
	-webkit-mask-size:106%;
	-webkit-mask-repeat:repeat-y;
}

.mask:hover{
	-webkit-mask-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0) 10%, rgb(0, 0, 0) 30%);
	-webkit-mask-image: linear-gradient(to right, rgba(0, 0, 0, 0) 10%, rgb(0, 0, 0) 30%);
	-webkit-mask-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAAABCAMAAACYPYflAAAA1VBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOZVIRAAAARnRSTlP2Q6sHbMgpi9j9FlvknH03uUseDeeTccxgTzDvwqWCsDvQAvdoIlfddhAKGb2X8j+H1DO1R4+hLSYT4XrsZVT7BRwIAfwA9oNAXgAAAFpJREFUeNrlwVUOggAAAFAaRimttHSHghLKgA3ufyT/uQLvAduRM8NrIsQ9mS6832Ef9XmxS7Dh7lNA3X4eIkcja1Z4K+XM24Cs1zXTUeVRE+FAi1+tAPZTcf8Ab04F4m5bVQAAAABJRU5ErkJggg==);
	    
	-webkit-transition: -webkit-mask-position 1500ms ease;
	-webkit-mask-position:330px;
}
	</style>
</head>
<body>
<div class="wrapper">
	<div class="bg2">した</div>
	<div class="bg1 mask">うえ</div>
</div>
</body>
</html>

```

## ※
一部のAndroidでgradientのマスクをアニメーションさせたときに表示がおかしくなる。
[参考 http://tenderfeel.xsrv.jp/css/1261/](http://tenderfeel.xsrv.jp/css/1261/)

デモはbase64エンコードしたグラデ画像を使用。
iPhoneならgradientでいけます
zshのプロンプトにジョジョの奇妙な冒険ASBトレインの最新状況を表示する

```
$ curl "http://jojoasbtrain.jp/api/getTrainInfo"
{"success":true,"status":220,"data":{"update":"2013.08.30 15:17","news":"8\/30 \u305f\u3060\u3044\u307e\u8eca\u4e21\u57fa\u5730\u3067\u4f11\u61a9\u4e2d\u30c3!!"}}%
```

こんな感じで curl で情報を取得できる。結果を jq コマンドに渡してみると

```
$ curl -s "http://jojoasbtrain.jp/api/getTrainInfo" | jq "."
{
  "data": {
    "news": "8/30 ただいま車両基地で休憩中ッ!!",
    "update": "2013.08.30 15:17"
  },
  "status": 220,
  "success": true
}
```
こんな感じなので、ここから必要な部分を

```
$ curl -s "http://jojoasbtrain.jp/api/getTrainInfo" | jq ".data.news"
"8/30 ただいま車両基地で休憩中ッ!!"
```

取り出すといい感じ。あとはこれを zsh のプロンプトに組み込むだけ。

```
precmd() {
    JOJO_TRAIN_STATUS="$(curl -s -S 'http://jojoasbtrain.jp/api/getTrainInfo' | jq '.data.news')"
}
PROMPT='($JOJO_TRAIN_STATUS)%(!.#.$) '
```

ぼくのプロンプトはこんな感じになりました。捗るゥ捗るゥウ！！

![jojo-train-status.png](https://qiita-image-store.s3.amazonaws.com/0/794/290a4f1f-e5ff-3997-e6a0-040378841733.png)

### 9月3日 9:30頃 追記

API から返ってくるレスポンスの形式が変わったぽいので、なにかやりたい人は、新しいレスポンスの形式と向き合ってうまいことやりましょう！
kaminari 使い方


簡単にページャーが実装できるgemであるkaminariの使い方

[前提]
スカフォードでオブジェクトを作成している。

##インストール
Gemfileに下記の記述を追加した後にbundle installを行う。

```Gemfile
gem 'kaminari'
```

```
bundle install
```

##ページャー設定
コントローラを変更する。
indexの処理でDBから全てレコードを取得している処理を書き換える。

```cats_controller.rb
@cats = Cat.order("id").page(params[:page]).per(5)    
```

ビューにページャーを追加する。
下記の記述を追加する。

```index.html.erb
<%= paginate @cats %>
```

これでindexページでページャーが使えるようになる。
ELBのHealthyHostCountは全AvailabilityZoneの合計値をモニタリングできない？

CloudWatchでELBをモニタリングし、正常インスタンス数が一定数を下回った時にメールで通知されるように設定したいです。しかし、HealthyHostCountは一つのAvailabilityZoneのデータを取っているらしく、2台稼働しているのに1台しか動いてないように認識されてしまいます。全AvailabilityZoneの合計値を出す方法は不明。
UnHealthyHostCountも同様でした。
pflogsummの'-e'オプションについて

#概要

postfixのmaillogを解析する優れたツールであるpflogsummですが、
ちょっと立ち入ったログを吐き出したいときに使う '-e' オプションがあります。 
(extended ? extreme ?)

これを使うと　MessageID 送信者 , 受信者のリスト を表示してくれますが
日付が入らないのが不便に思っていました。

#勝手に改造

    ***************
    *** 799,806 ****
            $addr = "from=<>"
            }
            $msgSizes{$qid} = $size;
    !       my $eDateStr = sprintf "%d-%02d-%02d %02d:%02d:%02d ", $msgYr, $msgMon, $msgDay,  $msgHr, $msgMin, $msgSec;
    !       push(@{$msgDetail{$qid}}, $eDateStr . $addr) if($opts{'e'});
            # Avoid counting forwards
            if($rcvdMsg{$qid}) {
            # Get the domain out of the sender's address.  If there is
    --- 799,805 ----
            $addr = "from=<>"
            }
            $msgSizes{$qid} = $size;
    !      push(@{$msgDetail{$qid}}, $addr) if($opts{'e'});
            # Avoid counting forwards
            if($rcvdMsg{$qid}) {
            # Get the domain out of the sender's address.  If there is

MessageIDの後ろに日付が入ります。
Go言語で円周率計算してみた(math/bigパッケージ利用)

円周率計算してみたかった。ちなみにテイラー展開してgoルーチン使って書いてる人は[ここ](http://ikautak.hatenablog.com/entry/2012/04/21/193000)にいるんだけど、精度がfloat64だったから…。

Go言語にはちょうどいいことに多倍長浮動小数点数パッケージがあったので使ってみた。

アルゴリズムについては[ここ](http://d.hatena.ne.jp/nowokay/20081116)の三つ目のオイラー加速したものを参照。

```go:pi.go
package main

import (
	"fmt"
	"math/big"
)

func main() {
	max := int64(1000)
	two := big.NewRat(2, 1)
	pi := big.NewRat(1.0, 1.0)
	a := big.NewRat(1.0, 1.0)
	b := big.NewRat(1.0, 2.0)
	x := new(big.Rat)
	for i := int64(2); i < max; i += 2 {
		y := big.NewRat(i, i + 1)
		a.Mul(a, y)
		x.Mul(a, b)
		pi.Add(pi, x)
		b.Quo(b, two) //割り算はQuoっぽい。第二引数が0だとpanic飛ばすらしいから、それが嫌なら予め篩うかInvで逆数を求めるか…
	}
	fmt.Print(pi.Mul(pi, two).FloatString(100))
}
```

やっぱGo言語情報少ないな…。
IP固定の時、DNSの指定もする

/etc/resolv.conf が勝手に書き換わって困っていたので調べてみました。
[参考](https://help.ubuntu.com/12.04/serverguide/network-configuration.html#name-resolution)

```bash:/etc/network/interfaces
auto eth0
iface eth0 inet static
    address 192.168.11.191
    netmask 255.255.255.0
    gateway 192.168.11.1
    dns-nameserver 192.168.11.254 8.8.8.8 8.8.4.4
    dns-search local
```

と記述し、`$sudo /etc/init.d/networking restart`すると、

```bash:/etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 192.168.11.254
nameserver 8.8.8.8
nameserver 8.8.4.4
search local
```
alpha値のみで指定色にimage


imageWithRenderingMode :UIImageRenderingModeAlwaysTemplateのような処理。
アルファ値のみを対象に指定した色で出力

```objc:mimage
@interface UIImage (mimage)
-(UIImage*)templated:(UIColor*)color
@end

@implementation UIImage (mimage)
-(UIImage*)templated:(UIColor*)color
{
	UIGraphicsBeginImageContextWithOptions(self.size, NO, 0);
	[color set];
	CGRect rc = {CGPointZero, self.size};
	UIRectFill(rc);
	[self drawInRect:rc blendMode:kCGBlendModeDestinationIn alpha:1.0];
	UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
	return img;
}
@end

```

最初に指定色をベタ塗りして自前画像のalpha成分で抜き
bundle execを書かなくていいようにする

rbenv-binstubsとrbenv-gem-rehashを導入したら幸せになれました。ただし各々のプロジェクトの最初のbundle install時に `bundle install --binstubs=.bundle/bin` とする必要があります。

* https://github.com/ianheggie/rbenv-binstubs
* https://github.com/sstephenson/rbenv-gem-rehash

## 追記

ほとんど同じ内容のポストがあった。

http://qiita.com/naoty_k/items/9000280b3c3a0e74a618
sinatra + redis 事始め (mac)


ためしにクラシックなWebチャットを作ってみることにする。

# sinatra, redis をインストール。

gem と brew で入れる。

```
gem install sinatra sinatra-contrib redis hiredis --no-ri --no-rdoc -V

brew install redis
```

# redis サーバを起動

特に難しく考えずデフォルト設定で起動する。

```
redis-server
```

port 6379 で起動しています。

# irb で redis につなげることを確認

簡単！

```
irb> require 'redis'
irb> rd = Redis.new host:"127.0.0.1", port: "6379"
irb> puts rd.keys
[]
irb> rd.set :hello, "world"
irb> rd.keys
 => ["hello"] 
irb> rd.get :hello
  => "world"
```

でもリスト系の操作はけっこう癖がある。これは redis 側の癖のようだ。

リストの「右に追加する」「左に追加する」「右から取り出す」みたいな。スタックの概念を上下にしなかったのがとても新鮮。

キューでもスタックでもナチュラルに理解できる。うまいなぁ。

# アプリを作成

実は sinatra も全然知らないのである。

## URL構成

 - /main
   - ログを表示する
   - 発言フォームを表示する

 - /talk
    - ログに追記する
    - /main へリダイレクトする

テンプレートは erb とする。

## 作成する

- 名前をセッションに入れる。
- 表示は10件まで
- 発言は一行のテキストで無限に redis のリストに突っ込む。

```ruby:mychat.rb
require 'sinatra'
require "sinatra/reloader" if development?
require "rdiscount"
require "redis"

redis = Redis.new host:"127.0.0.1", port:"6379"

configure do
  enable :sessions
end

get '/main' do
  @name = params[:name]
  @logs = redis.lrange :logs, 0,9
  erb :main
end

post '/talk' do
  msg = params[:msg]
  session[:name] = name = params[:name]
  redis.lpush :logs, sprintf("[%s] : %s" , name, msg)
  redirect '/main'
end
```

views ディレクトリを作成し、main.erb を作成する。

```erb:views/main.erb
<form action="/talk" method="post">
  <input type="text" name="name" value="<%= session[:name] %>" size="10">
  <input type="text" name="msg" value="" size="80">
  <input type="submit" value="送信"/>
</form>
<hr/>
<% @logs.each do |log| %>
  <p><%= log %></p>
<% end %>
```

# 実行する

```
ruby mychat.rb
```

html ヘッダすらないし、ログを無限に格納していくのですぐ破綻するけど、とにかく動いた。
Text::XslateでMojolicious風のタグヘルパーを使う


[Mojolicious::Plugin::TagHelper](http://mojolicio.us/perldoc/Mojolicious/Plugin/TagHelpers)にあるtag関数をText::Xslateで使えるようにします。
ほぼそのまま置き換えただけなので問題なく使えると思います。


```pl:test.pl
use Text::Xslate qw(html_builder html_escape);
my $tx   = Text::Xslate->new(
  function => {
      tag => sub {
          my ( $name, $attrs ) = @_;
          $attrs //= {};
          return html_builder {
              my $html = shift;
              my $tag  = "<$name";
              for my $key ( sort keys %{$attrs} ) {
                  $tag .= qq{ $key="}
                      . html_escape( $attrs->{$key} // '' ) . '"';
              }
              if ($html) {
                  $html = ref $html ? $html : html_escape($html);
                  $tag .= '>' . $html . "</$name>";
              }
              else { $tag .= ' />' }
              return $tag;
          };
      },
  },
);     

```

```html:tag.tx
: my $link = 'http://yahoo.co.jp/' 
:'サンプルテキスト' | tag('a',{href=>$link});

:->{
<h1>セクションを囲む</h1>
<p>aaa</p>
:}() | tag('section');
```

```html:result.html
<a href="http://yahoo.co.jp/">サンプルテキスト</a>

<section>
<h1>セクションを囲む</h1>
<p>aaa</p>
</section>
``` 

だいたいこんな感じで出力されるはずです。
ストーリーボードを使ったお手軽アプリ作り(画面遷移)

#ストーリーボートを使って、簡単にアプリを作ってみよう。#
**初心者でも大丈夫です。**ストーリーボードを使うと、マウスでドラッグアンドドロップするだけでアプリが作れます。


今回は画面遷移までを作ってみました。
ストーリーボードだけで画面遷移したことない人にもおすすめですよ。

***

新規プロジェクトを作成して、use storyboardの欄にチェックを入れて作りましょう。
mainstoryboardを見ると、このようになります。

![スクリーンショット 2013-08-30 2.36.39.png](https://qiita-image-store.s3.amazonaws.com/0/18934/73bffaf0-9585-86ba-bc0f-fcfe7fbb1432.png)

***


右側のメニューの下から、欲しいオブジェクトをえらびましょう

![スクリーンショット 2013-08-30 2.40.37.png](https://qiita-image-store.s3.amazonaws.com/0/18934/32ea7a4a-96a2-b554-1b6c-62b41d753d91.png)

***


試しにViewControllerをドラッグして、画面の中央にもってくると、このように出ます

![スクリーンショット 2013-08-30 2.42.24.png](https://qiita-image-store.s3.amazonaws.com/0/18934/7f52e982-df02-d43a-31d4-047d60f63516.png)

***


これをDetailViewContorllerの右側に設置、さらに、DetailViewContorllerに、ぼたんとラベルをおいてみます。これも右側のメニューの下から選びます

![スクリーンショット 2013-08-30 2.44.36.png](https://qiita-image-store.s3.amazonaws.com/0/18934/851c9c7c-d8d7-1453-8cb8-35632ba09888.png)

***


この右側の白いのが、さきほど中央においたViewControllerです
ここで、Controlを押しながら、さっきおいたボタンをドラッグして、右のViewまでひっぱってみましょう
そうすると、青い線が伸びて、このように出ます

![スクリーンショット 2013-08-30 2.49.55.png](https://qiita-image-store.s3.amazonaws.com/0/18934/8e8a4f8e-5718-6946-84a5-954e4b77ccc6.png)

***


ここで、pushを選ぶと、

![スクリーンショット 2013-08-30 2.50.52.png](https://qiita-image-store.s3.amazonaws.com/0/18934/775a81c2-5972-80f2-3145-01bf7c8508b4.png)

***


これで完成！
シュミレーターでボタンを押すと、隣の画面に遷移できます！

ストーリーボードを使うと、一切コードを書かずに画面遷移が簡単にできますね。
maven プロジェクトで利用する JDKのバージョンを指定する。

メモ

```xml:pom.xml-スペニット
	<profiles>
		<profile>
			<activation>
				<jdk>1.7</jdk>
			</activation>
		</profile>
	</profiles>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
```
crossing.rb

問題はこちら
http://nabetani.sakura.ne.jp/hena/ord14crosscircle/

他の解答例はこちら
http://qiita.com/Nabetani/items/66806c9dc14a96f2fd42

解説はこちら
http://qiita.com/saihon2013/items/115b448577b9d722a82f

```rb
def solve(q)
	pnt = 0
	a = [q.chars.map{|c| c},Array.new(q.length){|i| 0}]
	a[0].each_with_index {|c, i|
		tp = 0
		a[0][i+1, a[0].length-i].each_with_index {|d, j|
			pos = j+i+1
			if c == d
				pnt += tp
				tp += a[1][pos]
				a[1][pos] += 1
			else
				tp += a[1][pos]
			end
		}
	}
	pnt.to_s
end

DATA.readlines.each do |line|
	no,q,a = line.split(/\s+/)
	ans = solve(q)
	print no + "\t" + ans
	puts ans == a ? " (^o^)/~": " _(TAT)_"
end

__END__
0 	aabbca1bcb 	14 	
1 	111ZZZ 	0 	
2 	v 	0 	
3 	ww 	0 	
4 	xxx 	0 	
5 	yyyy 	1 	
6 	zzzzz 	5 	
7 	abcdef 	0 	
8 	abcaef 	0 	
9 	abbaee 	0 	
10 	abcacb 	2 	
11 	abcabc 	3 	
12 	abcdabcd 	6 	
13 	abcadeabcade 	23 	
14 	abcdeedcba 	0 	
15 	abcdeaedcba 	8 	
16 	abcdeaedcbad 	16 	
17 	QQQQXXXX 	2 	
18 	QwQQmQXmXXwX 	14 	
19 	111222333 	0 	
20 	aaAAaA 	4 	
21 	121232313 	12 	
22 	1ab1b 	1 	
23 	abcdefbadcfe 	12 	
24 	abxcdefbadcfex 	14 	
25 	dtnwtkt 	0 	
26 	mvubvpp 	0 	
27 	moggscd 	0 	
28 	kzkjzpkw 	2 	
29 	fbifybre 	1 	
30 	rrrfjryki 	1 	
31 	wrbbdwsdwtx 	2 	
32 	vvucugvxbvgx 	9 	
33 	ojkjzyasjwbfjj 	5 	
34 	ggffyuxnkyypifff 	5 	
35 	vcgtcqlwrepwvkkogl 	4 	
36 	xeqtmmgppwcjpcisogxbs 	4 	
37 	lukltpeucrqfvcupnpxwmoj 	6 	
38 	zpzswlkkoqwwndwpfdpkhtzgtn 	31 	
39 	bkfeflagfvluelududqjcvfyvytfw 	45 	
40 	rvqbhfmcjjqlpqzulzerxgyowiwrfkmhw 	26 	
41 	qyxvpdtoeexbqsethwjwmqszcxxjnsdoeaet 	144 	
42 	rjmsgmswhcolmpbhmpncziymydyalrcnevsrespj 	133 	
43 	oxetnyjzjbysnwktfwzndlejfndsqeetsnjvsicyjehd 	395 	
44 	wzvddnddzogywcqxbyvagbzmsmtcmrrlbnebmvhaemjouaqim 	219 	
45 	karhphxcxqgsyorhusbumbqzocuzvnwzwcpxgsksrviihxrgsrhji 	461 	
46 	oxgbononhqdxzmkysgijwvxljpaazmgkurkpffeuwywwuyxhyfkicgyzyc 	441 	
47 	sdgsrddwsrwqthhdvhrjhgtxwgurgyiygtktgtughtogzaqmcafkljgpniddsvb 	1077 	
48 	qemhecchkgzhxmdcsltwhpoyhkapckkkzosmklcvzkiiucrvzzznmhjfcdumuflavxik 	1711 	
49 	ffqmsirwpxrzfkbvmmfeptkbhnrvfcywthkwkbycmayhhkgvuyecbwwofwthlmzruphrcujwhr 	2440
```
JavaScriptでAudioを操作する

自分のバンド用に音楽共有サービスを作ってるんだけど、やっぱりwebだけで視聴とかもしたいわけで。
HTML5のaudioタグを使うのも手なんだけど、やっぱりちょっとケータイからは使いづらい。

そこで、Audioクラスを使ってJavaScriptで操作する、みたいなことをやってみることにしたので、その備忘録的なアレ。

## とりあえずコーヒー置いときますね

コードに粗があったり汚かったり使い方間違ってたりしたら指摘していただきたく。

```coffeescript
class AudioPlayer
  constructor: (el) ->
    @el = $(el)
    @src = @el.find('audio')
    @playButton = @el.find('.play')
    @pauseButton = @el.find('.pause')
    @volumeBar = @el.find('.volume')
    @seekBar = @el.find('.duration')

    @pauseButton.hide()

    @audio = new Audio
    @audio.src = @src.attr('src')
    @audio.volume = 1.0

    @handleAudio()

    @audio.load()
  
  play: (ev) =>
    ev.preventDefault()
    @audio.play()
    @playButton.hide()
    @pauseButton.show()

  pause: (ev) =>
    ev.preventDefault()
    @audio.pause()
    @playButton.show()
    @pauseButton.hide()

  updateCurrentTime: =>
    current = @audio.currentTime
    @seekBar.val Math.ceil(current)

  updateTimeWithEnd: =>
    @seekBar.val(0)
    @audio.currentTime = 0
    @playButton.show()
    @pauseButton.hide()

  changeVolume: =>
    @audio.volume = @volumeBar.val() / 100

  handleAudio: =>
    @playButton.on 'click', @play
    @pauseButton.on 'click', @pause
    @volumeBar.on 'change', @changeVolume
    a = $(@audio)

    a
      .on 'loadeddata', =>
        @seekBar.attr('max', Math.ceil(@audio.duration))
      .on 'timeupdate', =>
        @updateCurrentTime()
      .on 'ended', =>
        @updateTimeWithEnd()

    @seekBar.on 'change', =>
      time = @seekBar.val()
      console.log time
      @audio.currentTime = time
```

こんな感じで、ちょっとデザインとか整えたりすると、こうなる。
![uploada_tracks_show.png](https://qiita-image-store.s3.amazonaws.com/0/2190/a33a3666-02b2-9e17-4c85-a9cfe450dece.png)

## Audioについて説明

Audioクラスは、JavaScriptから音楽ファイルを上手いこと扱うためのもので、例えば`play()`とか`pause()`とかっていうファンクションがある。

```coffeescript
audio = new Audio
```

みたいな感じで使って、

```coffeescript
audio.src = "音楽ソースのパス"
```

で音楽ファイルを指定する。そんで、

```coffeescript
audio.play()
```

とかやってやればなんとなくファイルが再生される、という仕組み。

書き途中だけど眠くなってきたので風呂入って寝る。（でも公開はする
Errbit の javascript notifier をまともに動くようにするために


2013/09/19時点

## for Exception Notifier
https://github.com/errbit/errbit
## memo
notifier.js にはバグあり。とりあえず動くように。
https://github.com/errbit/errbit/blob/master/public/javascripts/notifier.js

1. printstacktrace部分(49行目 - 491行目)を下記の最新からとってきてアップデート（backtraceを取れるようにする） 
  http://cloud.github.com/downloads/eriwen/javascript-stacktrace/stacktrace-0.4.js
  (http://stacktracejs.com/)

2. 下記を書き換え ※※ <%= airbrake_javascript_notifier %> を使わない場合

  792行目  

  ```792行目  
    Config = {
        options: {
            host: '[MY_HOST_SERVER]',
  ```

  497行目

  ```497行目
    var NOTICE_XML = '<?xml version="1.0" encoding="UTF-8"?>' +
        '<notice version="2.0">' +
            '<api-key>[my-api-key]</api-key>' +
  ```
  ※これって設計上の問題では？

3. notifyのgetリクエストを送る際に、iframeタグを生成しているけれど、エラーが出ることがあるので(Unsafe JavaScript attempt to access frame with URL)imgタグに変更する

  889行目

  ```889行目
  var request = document.createElement('img');
  ```

4. httpsのssl証明書も気をつけて！

## todo
知見が溜まってきたら、そのうちプルリ送る。
jsonを取得、表示するアプリケーション　その７

確認しないで放置してたところを修正しつつ入出力をモデルにバインドする
bind()にmutual: trueを指定すると入力値がモデルに反映される
（双方向にバインドされる感じ）

```groovy:json_client.groovy
import groovy.swing.SwingBuilder
import groovy.json.JsonOutput
import groovy.beans.Bindable
import javax.swing.*
import java.awt.*
import java.net.*

@Bindable
class Model {
	String method = 'GET'
	String url = ''
	String params = ''
	String json = ''
}
def model = new Model()

def tabPane

def prettyPrint = { text ->
	def result = JsonOutput.prettyPrint(text)
	(result =~ /\\u[0-9a-zA-Z]{4}/).each { match ->
		def code = match[2..5]
		def encTxt = new String([Integer.parseInt(code, 16)] as int[], 0, 1)
		result = result.replaceAll(/\\u${code}/, encTxt)
	}
	result
}

def sendRequest = {
	model.json = ''
	
	def method = model.method
	def url = model.url
	def params = URLEncoder.encode(model.params, 'utf-8').replaceAll('%3D', '=').replaceAll('%26', '&')
	if (method == 'GET') {
		url = "${url}?${params}"
	}
	
	def conn = url.toURL().openConnection()
	conn.requestMethod = method
	if (method == 'POST') {
		conn.doOutput = true
		conn.outputStream << params
	}
	
	model.json = prettyPrint(conn.inputStream.getText('utf-8'))
	tabPane.selectedIndex = 1
}

new SwingBuilder().frame(title:'jsonを取得、表示するアプリケーション', defaultCloseOperation:JFrame.EXIT_ON_CLOSE,
						size: [800, 600], show:true) {
	lookAndFeel('nimbus')
	borderLayout()
	hbox(constraints: BorderLayout.NORTH) {
		comboBox(items:['GET', 'POST'], selectedItem:bind(source: model, sourceProperty: 'method', mutual: true))
		textField(text:bind(source: model, sourceProperty: 'url', mutual: true))
		button(text:'送信', actionPerformed:sendRequest)
	}
	tabPane = tabbedPane(constraints: BorderLayout.CENTER) {
		scrollPane(name:'パラメータ') {
			textArea(text:bind(source: model, sourceProperty: 'params', mutual: true))
		}
		scrollPane(name:'レスポンス') {
			textArea(editable:false, text:bind {model.json})
		}
	}
}
```

![qiita-007.png](https://qiita-image-store.s3.amazonaws.com/0/17179/428a1454-aa93-b0ad-7b9a-d6f77958c3de.png)
オフラインどう書く14回参考問題解答例( Ruby )

```ruby
def solve(src)
    h = {}
    src.split("").each_with_index do |k, v|
        if h[k] then h[k] = [h[k], v.to_s].join(",") else h[k] = v.to_s end 
    end 
    p = []
    h.values.each { |v| v.split(",").combination(2) { |x, y| p << [x.to_i, y.to_i] } } 
    cc = 0 
    p.each_with_index do |v, i|
        i.upto(p.size - 1) do |j| 
            x, y, z, w = p[i][0], p[i][1], p[j][0], p[j][1]
            cc += 1 if ( (x < z and z < y) and (y < w) ) or ( (z < x) and (x < w and w < y) )
        end 
    end 
    cc.to_s
end

DATA.readlines.each do |line|
    no, src, expected = line.split(/\s+/)
    actual = solve(src)
    print "no => ", no, ", act => ", actual
    puts actual.to_s == expected ? ', o' : ', x'
end
__END__
0   aabbca1bcb  14  
1   111ZZZ  0   
2   v   0
```
wrap()関連まとめ

wrap(),wrapInner(),wrapAll(),unwrap()がごっちゃになるのでメモとしてまとめました。

##wrap()
要素を一個ずつ囲む。

```js+erb:js
$("a").wrap("<div />")
```

```html+erb:html
<a href="#">aaaa</a>
<a href="#">bbbb</a>
<a href="#">cccc</a>
```

実行するとこうなる

```html+erb:実行結果
<div><a href="#">aaaa</a></div>
<div><a href="#">bbbb</a></div>
<div><a href="#">cccc</a></div>
```

aタグが一個ずつdivで囲まれます。

　<br />

##wrap(fn)
要素を一個ずつ囲むwrap()のファンクションタイプ。
ファンクションはwrap()の他にwrapInner()でも可。

```js+erb:js
$("a").wrap(function(i){
     return '<div id="'+i+'" />'
}
```

returnに囲みたいエレメントを記述する

```html+erb:html
<a href="#">aaaa</a>
<a href="#">bbbb</a>
<a href="#">cccc</a>
```


実行するとこうなる

```html+erb:実行結果
<div id="0"><a href="#">aaaa</a></div>
<div id="1"><a href="#">bbbb</a></div>
<div id="2"><a href="#">cccc</a></div>
```

 <br />

##wrapInner()
要素の子要素を一個ずつ囲む。aの内側。

```js+erb:js
$("a").wrapInner("<div />")
```

```html+erb:html
<a href="#">aaaa</a>
<a href="#">bbbb</a>
<a href="#">cccc</a>
```


実行するとこうなる

```html+erb:実行結果
<a href="#"><div>aaaa</div></a>
<a href="#"><div>bbbb</div></a>
<a href="#"><div>cccc</div></a>
```
　<br />

##wrapAll()
要素をまとめて囲む。

```js+erb:js
$("a").wrapAll("<div />")
```

```html+erb:html
<a href="#">aaaa</a>
<a href="#">bbbb</a>
<a href="#">cccc</a>
```

実行するとこうなる

```html+erb:実行結果
<div>
     <a href="#">aaaa</a>
     <a href="#">bbbb</a>
     <a href="#">cccc</a>
</div>
```

まとめて囲まれる。便利。
この場合のdivが、要素全体の親要素になる。

　<br />

##unwrap()
要素の親要素を削除する。全部小文字。unWrap()とは書かない。

```js+erb:js
$("a").unwrap()
```

```html+erb:html
<div class="dmy">
     <div><a href="#">aaaa</a></div>
     <div><a href="#">bbbb</a></div>
     <div><a href="#">cccc</a></div>
</div>
```

実行するとこうなる

```html+erb:実行結果
<div class="dmy">
     <a href="#">aaaa</a>
     <a href="#">bbbb</a>
     <a href="#">cccc</a>
</div>
```

aタグを囲んでいた親要素のdivがなくなる、
またその上の要素（div class:dmy）には影響されない
IntelliJ, WebStorm, PHPStorm で矩形選択

## 流れ

### 1. こういうテキストを

![step1.png](https://qiita-image-store.s3.amazonaws.com/0/6752/16530fac-1e41-3226-c132-2dc220615446.png)

### 2. こういうところにペーストしたいとき

![step2.png](https://qiita-image-store.s3.amazonaws.com/0/6752/9ff6416e-03b4-2828-c6eb-ee47131c61c1.png)

### 3. option(alt)押しながら選択すると矩形選択できて

![step3.png](https://qiita-image-store.s3.amazonaws.com/0/6752/cdb6ce2e-dbcf-4729-d31d-f058f1bf57b1.png)

### 4. command(ctrl)+vでペーストすると

![step4.png](https://qiita-image-store.s3.amazonaws.com/0/6752/b1de9345-8bcb-5ea1-a7c2-da15ad693c41.png)

## 他にも

FinderやProjectパネルからファイルを複数選択してファイル名をペーストできるから、html書いててimg連打するときも複製(command+d)とコピー(command+c)と矩形選択(alt+drag)とペースト(command+v)で完結する。
こんなシチュエーションではコロンでそろえるコードスタイルは偉大。

![スクリーンショット 2013-09-18 21.19.19.png](https://qiita-image-store.s3.amazonaws.com/0/6752/31798b84-7a52-d68e-f3cb-389f414f6f6e.png)
Rubyでちょっとしたパーサー書くならstrscanなのかなぁ

Rubyでパーサーを書いてみたくなってちょっと調べてみたら、[strscan](http://doc.ruby-lang.org/ja/2.0.0/library/strscan.html)という標準ライブラリがあるらしいので、使ってみることにした。

以下、単純な四則演算パーサー。

```rb
#ライブラリの読み込み
require "strscan"

#構文木
module AST
  BinOp = Struct.new :op, :lhs, :rhs do
    def value
      op.to_proc.call lhs.value, rhs.value
    end
    def to_s
      lhss = lhs.instance_of?(BinOp) && opRank(op) > opRank(lhs.op) ? "(#{lhs})" : lhs.to_s
      rhss = rhs.instance_of?(BinOp) && opRank(op) > opRank(rhs.op) ? "(#{rhs})" : rhs.to_s
      "#{lhss} #{op} #{rhss}"
    end
    
    private
    def opRank(op)
      case op
      when :+, :-
        1
      when :*, :/
        2
      end
    end
  end
  UnOp  = Struct.new :op, :rhs do
    def value
      op.to_proc.call rhs.value
    end
    def to_s
      "#{op}#{rhs}"
    end
  end
  Num   = Struct.new :value do
    def to_s
      value.to_s.gsub(/\.?0+$/, "")
    end
  end
end

#パーサー
class Parser
  def parse(src)
    @scanner = StringScanner.new src
    parse_expr
  end

  private
  include AST

  #expr <- term (('+'|'-') term)*
  def parse_expr
    ast = parse_term

    while op = scan(/[+-]/)
      ast = BinOp.new op.intern, ast, parse_term
    end

    ast
  end

  #term <- fact (('*'|'/') fact)*
  def parse_term
    ast = parse_fact
    
    while op = scan(/[*\/]/)
      ast = BinOp.new op.intern, ast, parse_fact
    end
    
    ast
  end

  #fact <- ('+'|'-') fact
  #      | '(' expr ')'
  #      | float
  def parse_fact
    if op = scan(/[+-]/)
      ast = UnOp.new op.intern, parse_fact
    elsif scan(/\(/)
      ast = parse_expr
      raise "excepted ')'" unless scan /\)/
    else
      ast = parse_float
    end
    
    ast
  end

  def parse_float
    raise "unexcepted" unless value = scan(/([1-9][0-9]*|0+)(\.[0-9]*)?/)
    Num.new value.to_f
  end

  def scan(rex)
    space
    @scanner.scan rex
  end
  
  def space
    @scanner.scan(/\s+/)
  end
end

if __FILE__ == $0
  require "pp"

  parser = Parser.new

  while (print ">>> "; src = gets.chomp) != "quit"
    begin
      ast = parser.parse src
      puts "input  => #{ast}"
      pp ast
      puts "result => #{ast.value.to_s.gsub(/\.0+$/, "")}"
    rescue => e
      puts "parse error", e
    end
  end
end
```

パーサーの部分はそれなりに短く書けた感じ。

RParsecとかはメンテされてなさそうだけどどうなんだろう？