OmniAICreator/Qiita-1.07M huggingface dataset:
PHPで使うGoFパターン ひとり Advent Calendar - コマンド


## コマンドってなに?

要するにコマンド(命令)を統一シグニチャでクラスにまとめて、
一連で実行出来るような仕組みとして実装するパターンです。
身近なところの実装例としては以下

* undo, redo
* エディタのキーボードマクロ(場合によってはスクリプト保存付きも可能)
* キュー管理のバッチジョブコントローラ

## コマンドパターンの構造

* Invoker - コマンドをスタックに保持したり、コマンドを実行したり
* Receiver - コマンドに操作される対象のクラス。内部に状態を持っていてCommandの操作によって内部の状態が変化したりする
* Client - Invokerを操作するコントローラ
* Command - 実コマンド。Receiverを操作することでコマンドを実現。Invokerに利用される

```
<?php

/* Reciever */
class FileSystem   {
  private $_Path = null;

  public function __construct ( $path ) {
    $this->_Path = $path;
  }

  // コマンドに利用されるAPIだよ
  public function changeDirectory () {
    return `cd $this->_Path`;
  }

  // コマンドに利用されるAPIだよ。
  public function makeDirectory () {
    return `mkdir $this->_Path`;
  }

  // コマンドに利用されるAPIだよ。
  public function removeDirectory () {
    return `rm $this->_Path`;
  }

  // コマンドに利用されるAPIだよ。
  public function createFile () {
    return `touch $this->_Path`;
  }
}
```


```
<?php
/* command interface */
interface ICommand {
  public function execute ();
  public function undo ();
}

/* 実コマンド */
class MakeDirectoryCommand implements ICommand {
  private $_FileSystem = null;

  public function __construct ( $fs ) {
    $this->_FileSystem = $fs;
  }

  public function execute () {
    $this->_FileSystem->makeDirectory ();
  }

  public function undo () {  
    $this->_FileSystem->removeDirectory ();
  }
}

 class RemoveDirectoryCommand implements ICommand {

  private $_FileSystem = null;
  public function __construct ( $fs ) {
    $this->_FileSystem = $fs;
  }

  public function execute () {
    $this->_FileSystem->removeDirectory ();
  }

  public function undo () {  
    $this->_FileSystem->makeDirectory ();
  }
}
```

```
<?php
/* Client */
class ShellScript {
  private $_Queue    = array ();
  private $_Position = 0;

  public function add ( $cmd ) {
    $this->_Queue[] = $cmd;
  } 
//  // MEMO: 実行途中にnextしたり、undoしてポジションを戻して
//  //       中途からコマンド上書きしたりも出来るよ
//  public function next () { //    return ++$this->_Position;
//  }
//  public function undo ( $times = 1 ) {
//    $this->_Queue[$this->_Position]->undo();
//    for ( $i = 0; $times < $i; $i++ ) $this->_Position--;
//  }

  //
  // でも今回はサンプルなのでリニアに実行するだけにするよ
  //
  public function run () {
    foreach ( $this->_Queue as $q ) $q->execute();
  }
}
```

```
<?php
/* Clientです。クラスじゃないけど */
$sh = new ShellScript();
$fs = new FileSystem ( '/etc/tmp/sample' );
$sh->add ( new MakeDirectoryCommand ( $fs ) );
$sh->add ( new RemoveDirectoryCommand ( $fs ) );
$sh->run ();
```
再考 RESTful APIとしてのRailsとクライアントとしてのJavaScript

[Railsにおける RESTfulなURL設計 勉強会](https://github.com/sendagayarb/mokmok/tree/master/2012-07-23)で、[RESTful APIとしてのRailsとクライアントとしてのJavaScript](http://www.slideshare.net/naotokoshikawa/restful-apirailsjavascript)というお話をさせて頂きました。

その際に、[@tkawa](http://twitter.com/tkawa)さん、[@t_wada](http://twitter.com/t_wada)さん、[@moro](http://twitter.com/moro)さんのお話を聞いた後に考えたことをまとめておきます。

* RESTful APIとしてリソース設計する際に、あまりにもRailsのmodel = ActiveRecordという考えにとらわれ過ぎると何でも非同期処理で取得したくなってしまうのでよろしくないということ。
* 非同期処理でユーザーの体験を良くしようとするつもりが逆に体験を悪くしていては本末転倒であるということ。
* 非同期処理でもn+1問題に気をつける

どうしてもリソースをActiveRecord単位のmodelで分割していると非同期処理で全てを解決しよう考えがちです。

例えば、私の考えた例ですと、```/groups/1``` にアクセスした際に ```/groups/1/posts``` へ非同期処理を行っていましたが、グループに投稿された記事の最初の一ページ目は ```/groups/1``` を描写した際に同時に取得しておいたほうがユーザーにとっては良い経験を与えられるのではないかと思いました。

n+1問題に関しては、今回の例だと投稿記事にコメントが付けられるとしてその投稿を非同期処理で投稿の数だけ非同期処理で取得するような処理がそれに該当します。それを避けるには

* 各投稿に対して初めからhas_manyでコメントを取得する（これはサーバー側でn+1問題が発生するので ```includes``` 使うなど工夫が必要です)
* 非同期処理で取得する際に画面に表示されている投稿の分をすべて一気に取得する(以前メンテしていたアプリではこれで対応しました)

といった対応が必要かなと思いました。ちょうどいま開発中ものを例にしていたのでその辺の仕組みを見なおそうと思いました。

その他何度も擦り込まれたお話として**model = ActiveRecord**以外の論理モデルをリソースとしても良いということは目から鱗でした。これは[RESTful Webサービス](http://www.oreilly.co.jp/books/9784873113531/)を読んだ際にも感じていたのですが、[@joker1007](http://twitter.com/joker1007)さんのつぶやきでいろいろ繋がりました。

<blockquote class="twitter-tweet" lang="ja"><p>エンタープライズRailsを読んだ時は、データベースとアプリケーションが使うリソースにクッションになるオブジェクト層入れて、RDBMSのCRUDとは分離して捉えられるような構造を提案してた。 <a href="https://twitter.com/search/%23sendagayarb">#sendagayarb</a></p>&mdash; Tomohiro Hashidateさん (@joker1007) <a href="https://twitter.com/joker1007/status/227367119065583616" data-datetime="2012-07-23T11:38:40+00:00">7月 23, 2012</a></blockquote>
<script src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

そう、これ[エンタープライズRails](http://www.oreilly.co.jp/books/9784873114163/)で読んだ！あの論理モデルをリソースにしてもいいよというお話だったんですね、これでスッキリ繋がりました。

いやーそれにしても濃い勉強会でした。[Sendagaya.rb #9](https://github.com/sendagayarb/mokmok/tree/master/2012-06-25)にて[@tkawa](http://twitter.com/tkawa)さんにURLの設計相談をしたのをキッカケに開催することになったこの勉強会、開催してよかったです。発表者の皆様、参加者の皆様、会場提供頂きましたミクシィの皆様、ありがとうございました。

また、今回事前に相談内容を沢山いただきましたので次回は相談会をメインとした勉強会を開催したいと思っています。
Python de BDD (Lettuceで)


## インストール

いつも通り pip で。

```
$ pip install lettuce
```

## Feature を書く

拡張子を .feature にすればいいですが、features ディレクトリに書く方が気持ちいい気がすします。[日本語にも対応してるそうです。](http://d.hatena.ne.jp/aroma_black/20110711/1310391394)

```Cucumber:features/example.feature
Feature: a cookie in a bug
  In order to eat a cookie
  I carry a bug

Scenario: simple test
  Given I have a bug
  Then a cookie exists in the bug
```

で、lettuce を実行すると、書くべき step のテンプレを表示してくれます。

```python:
#You can implement step definitions for undefined steps with these snippets:

# -*- coding: utf-8 -*-
from lettuce import step

@step(u'Given I have a bug')
def given_i_have_a_bug(step):
    assert False, 'This step must be implemented'
@step(u'Then a coookie exists in the bug')
def then_a_cookie_exists_in_the_bug(step):
    assert False, 'This step must be implemented'
```

pending が無い・・・のかな？

## Step を書く

作った feature と同じディレクトリに、.py で作ります。まずはコピペ。

```python:features/example.py
# -*- coding: utf-8 -*-
from lettuce import step

@step(u'Given I have a bug')
def given_i_have_a_bug(step):
    assert False, 'This step must be implemented'
@step(u'Then a coookie exists in the bug')
def then_a_coookie_exists_in_the_bug(step):
    assert False, 'This step must be implemented'
```

このままでは、すべて Fail するので、それっぽく書き換えます。

```example.py
# -*- coding: utf-8 -*-
from lettuce import *
import sys
import bug # これから作る

@step(u'Given I have a (.*)$')
def given_i_have_a_bug(step, arg):
    cls = getattr(sys.modules[arg], arg[0].upper() + arg[1:])
    world.__dict__[arg] = cls()
    assert world.__dict__[arg], arg + ' must be an instance'

@step(u'Then a cookie exists in the (.*)$')
def then_a_coookie_exists_in_the_bug(step, obj):
    assert world.__dict__[obj].cookie, arg1 + ' should return True'
```
## テスト！

lettuce を実行するだけです。

## いざ実装

ちょっとしょぼすぎますが。。。

```python:bug.py
class Bug(object):
  def __init__(self):
    self.cookie = True
```


## まとめます

* ステップの import はテンプレから書き換える
* world で各ステップ共有の変数を作る
* @step は ruby と似てるので書きやすい
* @step の文字列と直後の関数名は同じじゃなくて良い
* ステップを書くのが難しい(これだけで２時間かかった）
* もっと良いサンプルが世の中にはたくさんある orz
jsonのマージイディオム

先日のqiita,meetup,#1で一部の方にお話ししたjsonのマージ関数、evalで解決できたので共有します。遅れてすみません。
jsonのマージ元のオブジェクトと、jsonのpathを"window['a'][3]['foo']"のような形で引数にあたえてやると、該当のオブジェクトをマージします。実際のコードからコピペしてます。

```coffeescript
func_pattern = /\(function\(\)\{return /

marge_json = (db_obj,path)->
  setw = (path,help_db)->
    eval_str = "#{path} = help_db"
    eval(eval_str)
  helper = (help_db,path)->
    switch true
      when help_db instanceof Array
        for v in help_db
          helper(v,"#{path}[#{_i}]")
      when typeof help_db is "object"
        for key,value of help_db
          helper(help_db[key],"#{path}['#{key}']")
      when typeof help_db is 'string' and help_db.match(func_pattern) isnt null
        setw path,eval(help_db)
      else
        setw path,help_db
    return
  helper(db_obj,path)
```
テストを書かないテスティングツール「Porky」をリリースしました

##コンセプト
テストを書かずにテストの自動化を実現する

##主な用途
リグレッションテスト
一部を修正したときに他に影響がないかを確認するときに効果的です

##テストの登録
下記の関数をテストケースに登録する場合を考えます。

```coffeescript:テスト対象の関数
append = function(){$("body").append("test case1");};
```

javascriptコンソールから、下記を実行します。

```javascript:console
>porky.register({name:"test1",func:"append"})
```

nameはテストの名称、funcは関数の名前です。
これでテストの登録は完了です。

##テストの実行
Chromeのjavascriptコンソールから下記を実行します。

```javascript:console
>porky.run()
```

pokry.runを実行すると、下記のようにテスト結果がconsole上に出力されます。

```yaml:結果
Porky 
  Runner
  test1 
    UI test 
      success 
    JSON test 
      success 
  test1: 13ms 
Porky: 25ms 
```


##仕組み
###registerしたときにやっていること
1.registerした瞬間のhtmlを保存する。オプションで監視対象のjsonも指定している場合は、対象のjsonオブジェクトも保存。
2.指定された関数を実行する
3.1番と同様に、関数実行後のhtmlやjsonを保存する
\#保存先は、ローカルのindexedDB
###runしたときにやっていること
テストケースごとに、下記を実行している
1.テストケースから、関数実行前のhtmlとjsonの状態を復元する
2.関数を実行する
3.関数実行後のhtmlとjsonの状態と、テストケースで保存されている関数実行後のhtmlとjsonを比較して、差がないかテストする

##導入
[https://github.com/puriketu99/porky](https://github.com/puriketu99/porky)からcloneして、必要なファイルを読み込む

```sh:clone
git clone https://github.com/puriketu99/porky.git
```

```html:必要なjavascriptファイルを読み込む
<script src="/porky/jquery.js"></script>
<script src="/porky/indexeddb.shim.js"></script>
<script src="/porky/jquery.indexeddb.js"></script>
<script src="/porky/porky.js"></script>
```


詳細は、githubをご覧ください。
chaikaのportを自動的に変える

特にsuspendから復帰した時とか、chaikaが使えなくなることがたまにある。
使うportを変えればいいという話をどこかで見た気がした。
以下を _keysnail.js に追加。

```js
// change chaika port every time firefox starts
util.setIntPref("extensions.chaika.server_port.firefox",
                8800 + Math.floor(Math.random() * 30));
```
virt-install の --location オプション

詳しくは man を参照してほしい（雰囲気はつかめたけど、詳しくはわからないw）が、
--location オプションを指定すると iso ファイルがローカルになくてもインストールできる。

```bash
$ sudo virt-install \
--name fedora17 \
--ram 2048 \
--disk path=/var/lib/libvirt/images/fedora17.img,size=20 \
--network bridge=virbr0 \
--location=http://ftp.jaist.ac.jp/pub/Linux/Fedora/releases/17/Fedora/x86_64/os/
```
Rails で (Rack の) セッション情報を Cookie に保存する仕組み


Rails では特に (config/initializers/session_store.rb などで) 設定しない場合、セッションの情報をクライアントの Cookie に直接、(事実上) 平文で保存する。

実際に見てみよう。

```bash
$ rails new todo
$ cd todo
$ rails g scaffold tasks name
$ rake db:migrate
$ rails s
```

```ruby
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery
  before_filter do
    # アクセスした日時を session に保存
    session[:last_accessed_at] = Time.now
  end
end
```

```bash
$ curl localhost:3000/tasks -i -s | grep Set-Cookie
Set-Cookie: _todo_session=BAh7CEkiD3Nlc3Npb25faWQGOgZFRkkiJTE0YTYyZmNlYmVhODVmNjU5NGZmNjlhN2M0MTM1ZjQ0BjsAVEkiFWxhc3RfYWNjZXNzZWRfYXQGOwBGSXU6CVRpbWUNREscgLb0JXIHOgtAX3pvbmVJIghKU1QGOwBUOgtvZmZzZXRpApB%2BSSIQX2NzcmZfdG9rZW4GOwBGSSIxU1llVWZyclBzVU9oUG0rclRMQ1hkUzNpYUU1RlpRWGI0QUU2alJ5UDJEYz0GOwBG--b7446faf0dcddf99f358ce40525f7eade939d1be; path=/; HttpOnly
```

```ruby
require "uri"
require "base64"
require "pp"

# 上で Set-Cookie ヘッダに書かれてる文字列
session_in_cookie = "BAh7CEkiD3Nlc3Npb25faWQGOgZFRkkiJTYxMzE4MDQ5ZDA2ZjM1NjlhNGJmM2I2ZDMwYjJmMDA4BjsAVEkiFWxhc3RfYWNjZXNzZWRfYXQGOwBGSXU6CVRpbWUNREscgJmmKHsHOgtAX3pvbmVJIghKU1QGOwBUOgtvZmZzZXRpApB%2BSSIQX2NzcmZfdG9rZW4GOwBGSSIxOHcrUGlocmJIRDhpR01QZVRVMkVzZ0xsOVVJQnk4eEU0bzlpa3RoYVNvbz0GOwBG--394e1c8682803d5109d2bfbffe4254430e41098e"

# URI デコード、-- の前を取り出し
session_base64, digest = URI.decode(session_in_cookie).split("--")

# Base64 デコードして Marshal.load でオブジェクト復元
pp Marshal.load(Base64.decode64(session_base64))
# {"session_id"=>"61318049d06f3569a4bf3b6d30b2f008",
#  "last_accessed_at"=>2013-03-26 13:30:50 +0900,
#  "_csrf_token"=>"8w+PihrbHD8iGMPeTU2EsgLl9UIBy8xE4o9ikthaSoo="}
```

このように Base64 のデコードと Marshal.load で簡単に復元できてしまう。これだといっけんユーザがセッションの内容書き換え放題にみえるが、実際にはそんなことはない。

上のコードでさらっと split しているが、Cookie に格納される情報は Marshal.dump -> Base64 エンコードした文字列のあと -- に続いて、ハッシュ値が書かれている。これは -- より前の文字列と秘密鍵を使って OpenSSL::HMAC.hexdigest で作成したもので、Cookie 生成時に付与され、受け取ったときに一致するか検証される。

```ruby
# rack-1.4.1/lib/session/cookie.rb より
module Rack
  module Session
    class Cookie
      def generate_hmac(data, secret)
        OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, secret, data)
      end
    end
  end
end
```

このため、セッションの中身を書き換えたところで、秘密鍵を知らない限り、適切なハッシュ値を付与することができず、改ざんを防げるわけだ。

この秘密鍵は Rails アプリケーション作成時にランダムに生成されるもので、下記のように設定されている。長い。

```ruby
# config/initializers/secret_token.rb
Todo::Application.config.secret_token = 'aeb84aaf07fb5b4f8ebbfcbd8e524b64e595a436fffe0b64a54d4367c99c02bf9bef939755af13a49117fa3e526502fc297948f936e33984b9503afbeb1b359c'
```

素人目には充分なように安全にみえる (詳しい方のつっこみ歓迎)。

なお、最初に見たように session の内容は、リクエストした人本人には丸見えなので、秘密にしておくべき情報をセットしないよう注意。

また、CookieStore 以外の方式、たとえば DB にセッションの情報を記録する場合では、Cookie には session_id のみを持たせる一般的な実装になる。
JavaScriptのエラーログをDBに保存


「なんか動かないんだけど？」って言われたとき用に。

```javascript
window.onerror = function( errorMsg, url, lineNumber ) {
    $.ajax({ 
		url:"js_error_log.php",
		data:{errorMsg:errorMsg, url:url, lineNumber:lineNumber},
		type:"post" 
	});        	
};
```

・受け取り側のjs_error_log.phpは、POSTされた値をDBに書き込んでるだけ。
・トークンを発行するなど、CSRF対策はした方がいいかも。
・DBに書き込む際に、日時とユーザーエージェントも取得しておく。
MySQLで接続にSSLを要求する


ユーザの設定方法：

```
mysql> GRANT USAGE ON *.* TO 'encrypted_user'@'%' REQUIRE SSL;
```

ユーザの解除方法：

```
GRANT USAGE ON *.* TO 'encrypted_user'@'%' REQUIRE NONE;
```

mysqlクライアントからの接続方法

```
$ mysql -u name -p -h myhost --ssl --ssl-ca=/path/to/mysql-ssl-ca-cert.pem
```
ブランチを自由自在に操る

通常gitのブランチは自分が今扱っているHEADを基準に操作することが多いと思いますが(git checkout -bとか)、自分が扱っていないブランチを操作する時に役に立つのが次のコマンド

```bash:
$ git branch -lf
```

これは現在のブランチ(HEAD)以外の名前のブランチを自由な場所に強制移動します。（なければ新規ブランチ作成）

ユースケースとしては、リモートとローカルのブランチ（沢山）を同期したい時で、リモートの複数ブランチを取得(git fetch -p)したら、forced updateされていてgit pullとかやっても変なことになりそうなときなどに使えます。

```bash:
$ git branch -lf master origin/master
$ git branch -lf hoge origin/hoge
$ git branch -lf piyo origin/piyo
```

gitのGUIツールではこれと同じことが結構簡単にできるみたい。

---

ちなみにgitのエイリアスとして

```bash:
bl = branch -lf
```

にしています。

---

ヘルプを参照すると

```bash:
$ git branch -h
-l                    create the branch's reflog
-f, --force           force creation (when already exists)
```

他のユースケースとしてあったのが、自分がブランチhogeだったつもりがmasterにいてコミットしてしまった時など、通常だとgit resetとか使いそうですが

```bash:
# On master
$ git bl hoge
#=> 今のHEAD(間違えて進んだmaster)にhogeが移動

# On master
$ git checkout hoge

# On hoge
$ git bl master HEAD^
#=> masterを一つ戻す(hogeと入れ替わった)
```

git reset(--soft,--hard), git checkoutなどは実際のファイルやステージにどんな影響があるかを思い出して考えつつ使わないといけないのですが、このgit blはそういったものをまったく意識せずにただあるブランチを動かす（ファイルを何も変更しない）という気楽なイメージで使えるので個人的に良く使っています。
godとRailsを合わせて使うとNumeric#daysやNumeric#kilobytesなどが上書きされる

## 環境
god v0.12.1
Rails v3.2.6

## 状況
godのsuger.rbではNumericクラスに`days`や`kilobytes`といったメソッドを実装しているが，これがActiveSupportの`core_ext/numeric/time.rb`や`byte.rb`と衝突して意図しない数値が返ってくる．

```
[1] pry(main)> DateTime.now                      
=> Mon, 23 Jul 2012 16:23:53 +0900
[2] pry(main)> DateTime.now.end_of_week
=> Tue, 22 Nov 3431 23:59:59 +0900
```

## 対処
https://github.com/mojombo/god/issues/61 によると"godとRails混ぜて使うな"とのこと．Gemfileに以下のように書いてauto loadを避ける

```ruby:Gemfile
gem 'god', :require => false
```
Audio Data APIのタイミング制御について

FirefoxでAudio Data APIを使ってリアルタイムにインタラクティブなオーディオ処理をするとき、信号データを書き込むタイミングは自分で制御しないといけません。
制御しないと未来に再生する音がガンガン作られてしまって、UIで操作したのものがなかなか反映されないように聞こえるからです。

```audioprocess.js
var audio = new Audio();
audio.mozSetup(channels, samplerate);

var written = 0; // 書き込んだサンプル数

var onaudioprocess = function() {

    // ここでタイミング制御を行う (*1)
    var offset = audio.mozCurrentSampleOffset(); // 今再生しているサンプル数
    if (offset > 0 && written > offset + 16384) {
        return;
    }


    var samples = MAKE_WAVE(); // 信号をつくる
    audio.mozWriteAudio(samples); // 書き込む
    written += samples.length;    // 書き込んだサンプル数を更新
};

// 20msec間隔でオーディオ処理を行う
setInterval(onaudioprocess, 20);
```

*1 の箇所でタイミングの制御を行います。
上の例では今再生しているサンプル数よりも書き込んだサンプル数が大きすぎる場合は書き込み処理を行わない。などして先に進み過ぎないように調整しています。

注意が必要なのは、ある程度データを書き込まないと再生が始まらず `mozCurrentSampleOffset()` が更新されず 0 のまま返ってくる点。しかも環境によって更新されない量が異なっていて、Linux版のFirefoxはかなり遅いです。
なので `offset > 0` のように `mozCurrentSampleOffset()` の更新が始まったら、タイミング制御を始めるようにしたほうが良さそうです。
でないと書き込んだ量が大きい状態のまま再生が始まらず、いつまでたっても差が埋まらず音が出ないという状態になってしまいます。
BlobBuilder でなく Blob のコンストラクタを使う

[BlobBuilder](https://developer.mozilla.org/en/DOM/BlobBuilder) は deprecated です。

今までこんな感じで書いていたのなら、

```old.js
builder = BlobBuilder();
builder.append(src);
blog = builder.getBlob();
```

[Blob](https://developer.mozilla.org/en/DOM/Blob)でこういう風に書きます。

```new.js
blob = new Blob([src]);
```
`src` は `[src]` と配列で書きます。

たとえば WebWorker に渡すURLをつくりたいなどで src が JavaScript の場合は、

```blob.js
blob = new Blob( [src], {type:"text\/javascript"} );
url = URL.createObjectURL(blob);
worker = new Worker(url);
```
2番目の引数でMIMEタイプを指定してあげます。
正規表現を対話的に作成する: M-x re-builder

`M-x re-builder`とすると、対話的に正規表現を作成できて便利です。使い方を簡単にまとめておきます。

新しく開かれたバッファ内の""に正規表現を入力していくと、バッファ内でマッチした文字列がハイライトされます。`C-c C-r (reb-prev-match)`や`C-c C-s (reb-next-match)`でマッチ部分へジャンプします。`C-c C-w (reb-copy)`で作成した正規表現をコピーすることができます。`C-c C-q (reb-quit)`で終了します。

Emacsの標準機能なのですね。長年Emacs使っていましたが知らなかった。。。
バッチ処理用にloggerを追加する

Railsでバッチ処理をしていて標準のログとは別のファイルに出力したかったので、バッチ処理のログを別のファイルに出力する方法をまとめておきます。

標準のLoggerでもいいのですがLog4rを使用したので、`Gemfile`に下記を追加します。

```ruby:Gemfile
gem 'log4r'
```

Log4rの初期設定を下記に記述します。

```ruby:config/initializers/batch_logger.rb
formatter = Log4r::PatternFormatter.new(:pattern => "%d %C [%l]: %M", :date_format => "%Y/%m/%d %H:%M:%S")
if Rails.env == "development"
  outputter = Log4r::StdoutOutputter.new(STDOUT, :formatter => formatter)
else
  outputter = Log4r::StdoutOutputter.new(File.expand_path("log/batch_log_#{Rails.env}.log", Rails.root), :formatter => formatter)
end
BatchLogger = Log4r::Logger.new("My App")
BatchLogger.add(outputter)
```

これで、scriptの中で`BathLogger.error`や`BatchLogger.info`と記述してログに出力します。
Tkinterを使うときの環境変数

Windows環境で、Tkinterを使おうとするとTcl/Tkライブラリが見つからず、このようなエラーがでた時の対応方法。

```
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: Can't find a usable tk.tcl in the following directories: 
    {C:\Python27\tcl\tk8.5} C:/Python27/tcl/tcl8.5/tk8.5 C:/lib/tk8.5 C:/library
```

TCL_LIBRARYと、TK_LIBRARYの環境変数を指定すると動くようになる。
複数のバージョンのPythonやTcl/Tkが入っていて、環境変数をいじりたく無い時はプログラムの先頭でos.environを直接いじっても上手く行く。

サンプルプログラム

```python
# -*- coding: utf-8 -*-
__author__ = 'Natsutani'

import os
from matplotlib.pyplot import *;

def main():
    # 環境変数の設定
    os.environ['TCL_LIBRARY'] = 'C:/Python32/tcl/tcl8.5'
    os.environ['TK_LIBRARY'] = 'C:/Python32/tcl/tk8.5'

    x = (5,11,3,5)
    y = (3,5,3,5)
    scatter(x,y)
    show()

if __name__ == "__main__":
    main()
```
よく使うgitコマンド


## クローン

githubからクローン

```
git clone git@github.com
```

クローン先のディレクトリを指定する

```
git clone git@github.com:user/repo hoge
```

ブランチを指定してクローン

```
git clone -b hoge git@github.com:user/repo
```


## ブランチ

ローカルブランチ一覧

```
git branch
```

リモートブランチ一覧

```
git branch -r
```

カレントブランチ切替

```
git checkout hoge
```

ローカルブランチ作成

```
git branch hoge
```

ローカルブランチ削除

```
git branch -d hoge
```

ローカルブランチをリモートにプッシュ

```
git push origin local-branch:remote-branch
```

リモートブランチ削除

```
git push origin :remote-branch
```

ローカルブランチの名前変更

```
git branch -m old new
```

## コミット

コミット

```
git commit -m 'message' .
```

差分を確認する

```
git status
```

最新のソースを取得する

```
git pull
```

コミットをプッシュする

```
git push
```

## チェックアウト

ローカルの変更取り消し

```
git checkout .
```

リモートブランチをチェックアウトする

```
git checkout -b branch origin/branch
```

タグをチェックアウトする

```
git checkout -b name refs/tags/name
```

特定のコミットをチェックアウトする

```
git checkout commit
```

特定のコミットをチェックアウトした状態を別ブランチにする

```
git checkout commit -b branch
```

## リベース/マージ

別のブランチの変更をリベースする

```
git rebase hoge
```

別のブランチの変更をマージする

```
git merge hoge
```

特定のコミットを適用する

```
git cherry-pick commit
```

## 差分

差分の内容を確認する

```
git diff
```

コミットやブランチ間の差分を確認する

```
git diff hoge fuga
```


## ログ

カレントブランチのログ表示

```
git log
```

別のブランチのログ表示

```
git log hoge
```

リモートブランチのログ表示

```
git log origin/hoge
```

対象ファイル表示

```
git log --stat
```

ログ検索

```
git log --grep hoge
```

## 管理対象

管理対象に追加

```
git add .
```

ファイルを管理対象から削除

```
git rm hoge
```

フォルダ配下を管理対象から削除

```
git rm -r hoge
```

管理対象外のファイルを確認

```
git clean --dry-run
```

管理対象外のファイルを削除

```
git clean -f
```

## タグ

タグを一覧表示する

```
git tag
```

タグを付ける

```
git tag -a name -m 'message' commit
```

タグを削除

```
git tag -d name
```

タグをプッシュする

```
git push origin name
```

タグの名前変更

```
git tag new old
git tag -d old
git push origin :refs/tags/old
git push origin new
```

## stash

変更を退避

```
git stash save
```

変更を適用

```
git stash pop
```

stash一覧

```
git stash list
```

stash全削除

```
git stash clear
```

## その他

upstreamを設定する

```
git branch --set-upstream-to=origin/branch branch
```

originを変更する

```
git remote set-url origin git@github.com:org/repo
```
PlayFramework1.2 で Amazon S3 とうまく連携させる

Model内でファイルを扱う、かつ、Amazon S3にそのファイルを置く場合に便利

S3Blobs
https://github.com/jamesward/plays3upload

```conf/dependencies.xml
# 追記
play -> s3blobs 0.1
```

例によって、依存関係の設定とeclipseでライブラリが見えるように以下を実行

```
play clean
play dependencies
play eclipsify
```

これで

```java:HogeModel.java
@Entity
public class HogeDocument extends Model {
    public S3Blob file;
}
```

とするだけで、ファイルのアップロードやダウンロード、管理が簡単になる。

実行時にAmazon関連の環境変数を設定しないといけないことに注意。

```sh
S3_BUCKET=HOGE
AWS_ACCESS_KEY=HOGE
AWS_SECRET_KEY=HOGE
export S3_BUCKET AWS_ACCESS_KEY AWS_SECRET_KEY
```

rootでないとポート割付できない設定で動かしている場合は特に要注意。
PHPで使うGoFパターン ひとり Advent Calendar - シングルトン


## シングルトンってなに?


要するに割と安全なグローバル変数です。
ポイントは以下

* コンストラクタを private にする
* 自身を保持するprivate static な変数を作る
* 自身を返すpublic static なメソッドを作る


```
<?php
class Singleton {
  // シングトンの実装 ここから << 
  private static $_Self = null;
  private function __construct () {} 
  public static function getInstance () {
     if ( !self::$_Self )self::$_Self = new Singleton();
     return self::$_Self;
  }
  // ここまで >>

  // 以下は普通に実装する
  public function doSomething ( $param ) {
  }

  public function doSomething2 ( $param ) {
  }

  public function doSomething3 ( $param ) {
  }
}

function main () {

  // こうやって呼び出して
  $obj = Singleton::getInstance ();

  // こうやって使う
  print $obj->doSomething ();
}

```

## どういう時に使うの?

* ロガー
* 設定ファイル

等、システム中にひとつ居れば良いような変数をシングルトンにします。そうすると、至るところでnew しなくても良くなり、new するコストを減らすことが出来る、場合によってはデータの一貫性も取り易くなったりします。

## 単体テスト的にどうなの?
 実は単体テストで癌になり易いです。

* 普通には new 出来ない
* メソッド内で気軽に直接参照され易い

等の問題があります。
結局、単体テストのために

* 引数でオブジェクトを渡すように修正
* コンストラクタをpublic に書き換える

など、無惨な末路を辿る結果になります。

ご利用は計画的に
githubとgithub pagesでウェブアプリを作ってすぐ公開

githubとgithub pagesを駆使するとhtml+JS+cssで作られたウェブアプリを簡単に公開できます。

*やり方*
1. hogeレポジトリを作ります。
2. ルートにindex.htmlを置きます。
3. index.htmlからアクセスできるようにJSやcssを置きます。
4. コミットします。
5. gh-pagesブランチを作ります。
6. gh-pagesブランチをgithubにpushします。

作ったものはusername.github.com/hogeに公開されます。誰がどんなものを作ったのかURLで判断できるというのは中々の利点ではないでしょうか(更新も楽)。

sample(という名の宣伝): http://ukyo.github.com/js-epub-editor/
第一回オフラインリアルタイムどう書く

第一回 オフラインリアルタイムどう書く(http://atnd.org/events/30285)
の問題をJavaで解いてみました。
問題のURL(http://nabetani.sakura.ne.jp/hena/1/)
所要時間は、問題を見てから1週間以上、
書き始めてから1時間ほどです。

``` TickTackToe.java
public class TickTackToe {
    private static final String DRAW_MESSAGE = "Draw game.";
    private enum Player {
        FIRST( "o won.", "Foul : x won.") {
            @Override Player next() { return SECOND; }
        },
        SECOND( "x won.", "Foul : o won." ) {
            @Override Player next() { return FIRST; }
        },
        ;
        Player( String won, String foul ) {
            WON_MESSAGE = won;
            FOUL_MESSAGE = foul;
        }
        private final String WON_MESSAGE;
        private final String FOUL_MESSAGE;
        abstract Player next();
        String won() { return WON_MESSAGE; };
        String foul() { return FOUL_MESSAGE; };
    }

    private static final int BOXES_MAX = 9;
    private static final int[][] LINES = {
        {0, 1, 2},
        {3, 4, 5},
        {6, 7, 8},
        {0, 3, 6},
        {1, 4, 7},
        {2, 5, 8},
        {0, 4, 8},
        {2, 4, 6},
    };

    public String match( String process ) {
        Player[] boxes = new Player[BOXES_MAX];
        Player move = Player.FIRST;
        int indexSize = process.length() < BOXES_MAX
            ? process.length()
            : BOXES_MAX;
        for ( int i = 0; i < indexSize; i++ ) {
            String result = put( process.charAt(i), move, boxes );
            if ( result != null ) {
                return result;
            }
            move = move.next();
        }
        return DRAW_MESSAGE;
    }

    private String put( char place, Player move, Player[] boxes ) {
        int boxesIndex = place - '1';
        if ( boxes[boxesIndex] != null ) {
            return move.foul();
        }
        boxes[boxesIndex] = move;
        for ( int[] line : LINES ) {
            if ( isFullLine( move, line, boxes ) ) {
                return move.won();
            }
        }
        return null;
    }

    private boolean isFullLine( Player move, int[] line, Player[] boxes ) {
        for ( int boxIndex : line ) {
            if ( boxes[boxIndex] != move ) {
                return false;
            }
        }
        return true;
    }
    
    public static void main( String[] args ) {
	if ( args.length == 0 ) {
	    System.out.println( "argument error." );
	    return;
	}
	TickTackToe ttt = new TickTackToe();
	for ( String process : args ) {
	    System.out.println( ttt.match(process) );
	}
    }
}
```
"フォロー中のタグ"に登録しているタグの更新をまとめるRSSを作った

["フォロー中のタグ"に登録しているタグの更新をまとめるRSSを作……ろうとしたが上手くいかない #Qiita #Pipes - Qiita](http://qiita.com/items/e232e95541757bc90c44)
で書いてた奴。どうやら上手く動いてるようなので公開。

**[Qiita following tags feed](http://pipes.yahoo.com/amaisaeta_/qiitafollowingtagsfeed)**

feedを取得したいユーザーのアカウント名を"Input a user name."テキストフィールドに入力しRun Pipe。後は"Get as RSS"のリンクをフィードリーダーに登録するなりなんなりお好きなように。

[自blogに書いてる](http://amaisaeta.seesaa.net/article/282172574.html)けど、稀にtimeoutしてるようだ。Pipesでは対処しようがないので、これは仕様って事で。
第2回 オフラインリアルタイムどう書くの参考問題 

オフラインでリアルタイムに「どう書く」をやるイベント第二回の
http://atnd.org/events/30900
atnd を立てた。
で、問題の例を出しておく。難易度と分量はこれを目安に。
## 二値画像の回転

正方形の二値画像を時計回りに回転する。

画像フォーマットは、x:d　のようになっており、x が画像の一辺の長さ（常に正方形）、d は16進表記の画像データ。

例えば、"3:5b8" であれば、3が一辺の長さを表す。
5b8 は ２進数で 0101 1011 1000 となる。
3x3 の画像なので必要なのは 9bit。右端の 3bit を捨ててから三桁ずつに分けて

> 010
> 110
> 111

となる。これが回転前の画像。
これを時計回りに 90度回すと

> 110
> 111
> 100

となる。一列に並べて、16進表記用に末尾に 0 を3つ足すと、

> 1101 1110 0000

となるので、もとめる答えは "3:de0" となる。
というのが今回のお題。
ただし：

* : の前にあるのは10進数。
* 不正な入力への対処は不要。
* 余ったから捨てる bit はゼロとは限らないが、回転後に末尾に足す bit はゼロ。
* 少なくとも 9x9 の画像に対処できること。

## 入力と出力の例
以下、「入力 → 出力」という形式で。（Qiita で表が書けないのが不満…)

* 3:5b8  →  3:de0
* 1:8  →  1:8
* 2:8  →  2:4
* 2:4  →  2:1
* 2:1  →  2:2
* 3:5d0  →  3:5d0
* 4:1234  →  4:0865
* 5:22a2a20  →  5:22a2a20
* 5:1234567  →  5:25b0540
* 6:123456789  →  6:09cc196a6
* 7:123456789abcd  →  7:f1a206734b258
* 7:fffffffffffff  →  7:ffffffffffff8
* 7:fdfbf7efdfbf0  →  7:ffffffffffc00
* 8:123456789abcdef1  →  8:f0ccaaff78665580
* 9:112233445566778899aab  →  9:b23da9011d22daf005d40

ruby と C99 でそのうち解答例を書く予定。

　
　
　
　
　
　


　
　
　
　
　
　

コメントで解答例が出てます。
解答を見たくないかたは要注意。
Coding Style


単項演算子の後はスペースをいれる。ただし+/-はスペースを入れない。

```perl
if (! $foo) {
	# …
}
if (not $foo) {
	# …
}
my $foo = +10;
my $foo = -10;
```

二項演算子は前後にスペースを入れる。

```perl
print $foo + $bar;
```

if, whileなどの後はスペースを入れる。

```perl
if ($foo) {
	# ...
}
while ($foo) {
	# ...
}
```
関数呼び出し演算子 `() ` の前はスペースを入れない。

```perl
foo();
$self->foo();
```

ブロック閉じ括弧 `}` の後は改行する。`if (…) ` の後は改行しない。 

```perl
if ($foo) {
    ...;
}
else {
    ...;
}
```
MonadTransControl型クラス

[Control.Monad.Trans.Control](http://hackage.haskell.org/packages/archive/monad-control/latest/doc/html/Control-Monad-Trans-Control.html) がよくわからないのでいろいろ調べてみた。

``MonadTransControl`` がやりたいのは、```MaybeT```と```runMaybeT```、もしくは```ListT```と```runListT```、のようにXxxxTとrunXxxxTの組の操作を抽象化したいということだと思われる。

例えば、```MaybeT [] a```に```reverse```を適用したい場合、```MaybeT [] a```は```[Maybe a]```のことなので、```runMaybeT```でラップを外してリストを処理してから```MaybeT```で再ラップすることで以下のように書ける。

```haskell:
reverseMaybeT :: MaybeT [] a -> MaybeT [] a
reverseMaybeT = MaybeT . reverse . runMaybeT
```

``MonadTransControl``型クラスを使えば、reverseMaybeTを様々なモナド変換子に対して一般的に定義できる。

```haskell:
reverseT :: (Monad (t []), MonadTransControl t) => t [] a -> t [] a
reverseT t = liftWith (\run -> reverse $ run t) >>= restoreT . return
```

``run``が``runMaybeT``、``restoreT``が``MaybeT``(コンストラクタ)、``StT t``は``Maybe``の役割を果たす。``run t``によってラップを剥がしてリストにしてくれるのだが、その型は当然``t``によって違い``[StT t a]``のような型で返ってくるので、総称的にリストを操作する関数だけが利用できる。

ちなみに``reverseT``の定義の末尾の``return``が非常に気持ち悪いのだけど、これはどう解釈すればいいんだろ。型を見れば必要なのはわかるんだけど、最初の``reverseMaybeT``の定義と比較すると乖離が激しくて、ちょっと気持ち悪い。

ここまでわかれば、``MonadBaseControl``型クラスも``MonadTransControl``とほぼ同じ物と見なせばいいと思う。``MonadIO``が重要なのと同様に、``MonadBaseControl``の方が用途は広い気がする。
Sublime Text の複数選択機能


Sublime Text の特色の一つに複数選択機能があります。カーソルを複数にして、同時に複数の場所を編集できる強力な機能です。

以下 Mac 向けのメモです。

## 選択範囲を行毎に分ける
複数行の塊を選択している状態で Cmd+Shift+L を押すと、選択がそれぞれの行に分割されます。
左キーを押すと、行頭に。右キーを押すと行末に移動するので、行の前後を編集できます。
ちなみに、そのままタイプすると選択しているものを消して上書きしてしまいます。

## 同じ言葉を選択する
言葉の上にカーソルを置くと、ファイル内の同じ言葉がハイライトされます。
Cmd+D で、ハイライトされた部分をもう一つ選択。
Cmd+Ctrl+G で全て選択。
pythonbrewでの複数バージョン＆ライブラリ管理メモ


1.ダウンロード&インストール

``` shell
$ curl -kL http://xrl.us/pythonbrewinstall | bash
```
2. .bashrc, .zshrcに設定を追加

``` 追加文言
[[ -s $HOME/.pythonbrew/etc/bashrc ]] && source $HOME/.pythonbrew/etc/bashrc
```

3. pythonbrewに複数バージョンをインストール

``` command
$ pythonbrew install 2.7.3
$ pythonbrew install 3.2.3
```

4.pythonのバージョンきりかえ

``` command
$ pythonbrew switch 2.7.3 #2.7.3を使う
$ pythonbrew switch 3.2.3 #3.2.3を使う
```

5.ライブラリ複数管理方法

``` command
$ pythonbrew venv create sample1 #現在利用しているバージョンでvenv(sample1)を作成できる。作成後はpipでライブラリ管理が行える
$ pythonbrew venv use sample1 #venvのsample1を利用する
$ pythonbrew venv list #venvの現存リストを表示する

$ pip install Django #利用しているvenv環境にDjangoがインストールされる
```
MySQL レプリケーション

Ubuntu Server 12.04 LTS で MySQL 5.5 のレプリケーション設定してみた。
参考にしたページ。 
http://dev.mysql.com/doc/refman/5.5/en/replication-howto.html
http://techblog.zabuchy.net/2011/master-slave-replication-in-mysql-5-5/

## master/slave 共通作業

### MySQL のインストール
$ sudo aptitude install mysql-server-5.5```


## master での作業

### マニュアルに書いてあるので MySQL を止めた
$ sudo service mysql stop

### 設定ファイルの変更
$ sudo vi /etc/mysql/my.cnf

外部から接続できるようにする
bind-address            = 127.0.0.1
↓コメントアウト
\# bind-address            = 127.0.0.1

master の設定
\# server-id               = 1
\# log_bin                 = /var/log/mysql/mysql-bin.log
↓ server-id と バイナリログの設定のコメントを外す
server-id               = 1
log_bin                 = /var/log/mysql/mysql-bin.log

$ sudo service mysql start

### データベースでの作業
$ mysql -u root -p
replication のユーザを作る
mysql> grant replication slave on *.* to repl@'192.168.1.%' identified by 'slavepass';
データベースを作っておく
mysql> create database reple_sample;

## slave での作業
### 設定ファイルの変更
slave の設定
$ sudo vi /etc/mysql/my.cnf
\# server-id               = 1
↓ server-id は一意の値
server-id               = 2

$ sudo service mysql restart

### データベースでの作業
$ mysql -u root -p
slave の開始
mysql> CHANGE MASTER TO MASTER_HOST='192.168.1.10', MASTER_USER='repl', MASTER_PASSWORD='slavepass';
mysql> START SLAVE;

データベースの確認
mysql> show databases;
マスターで作ったデータベースができている
Thorで終了ステータス 1 で終了する

[Thor][thor]を勉強していて気が付いたのだけど、コマンドに失敗した時にも終了ステータスが0（正常終了）になる。

    $ loga lookup
    loga lookup requires at least 1 argument: "loga lookup [TERM]".
    $ echo $?
    0

※ `loga` コマンドを例に出しているのに他意はありません。たまたまこの時気が付いただけで。

これは気持ち悪い。
勿論、`abort` とか `exit 1` とか呼べば1で終了できるのだけど、コマンド作成ツールのThorがその辺対応してないとかあり得ないだろう、と思ってちょっと `gem open` したりググったりした。

[thor]: https://github.com/wycats/thor

どうやら、`Thor` のサブクラスのクラスメソッド `exit_on_failure?` が `true` を返せばいいみたい。`Thor` 自体はいつでも `false` を返している。

https://github.com/wycats/thor/blob/ffbc56c0c2865aa098b706089f46fb67e81f4c72/lib/thor/base.rb#L607

```ruby:lib/thor/base.rb
class Thor
  # ...
  module Base
  # ...
    module ClassMethods
    # ...
        def exit_on_failure?
          false
        end
```

なのでこれを変えてやればよい。

```ruby:my-command
#!/usr/local/bin/ruby
require 'thor'
  
class MyCommand < Thor
  class << self
    def exit_on_failure?
      true
    end
  end
  
  desc 'subcommand ARG', 'My subcommand'
  def subcommand(arg)
  end
end
  
MyCommand.start
```

    $ ./my-command subcommand
    my-command subcommand requires at least 1 argument: "my-command subcommand ARG".
    $ echo $?
    1

ちゃんと失敗したのでこれで安心して寝られる。
Back to the…

***Delorean.back_to_the Time.zone.local(2012, 7, 18) do***

テストを書いている時に、境界値分析で特定の時刻をテストしたいということがよくあります。日をまたぐ場合とか、経過時間であれこれするとか、ゲームなんかだとよくありますね。
そういう時にテストケースを書く助けになるのが[Delorean](https://github.com/bebanjo/delorean)です。

```ruby:Gemfile
group :development, :test do
  gem 'delorean'
end
```

**特定の時刻にジャンプ**

```ruby:back_to_the_future.rb
Delorean.time_travel_to Time.zone.local(2015, 10, 21, 4, 30, 45)
p Time.zone.now #=> Wed, 21 Oct 2015 04:30:45 JST +09:00
```

**一日前**

```ruby:yesterday.rb
Delorean.time_travel_to 1.day.ago
```

**現在に戻る**

```ruby:today.rb
Delorean.back_to_the_present
```

**ブロック**

```ruby:block.rb
Delorean.time_travel_to 3.year.ago do
  p Time.zone.now
end
```

なお、ブロックの中でも時間は経過するので、

```ruby:block.rb
Delorean.time_travel_to Time.zone.local(2015, 10, 21, 4, 30, 45)
  sleep 30
  p Time.zone.now #=> Wed, 21 Oct 2015 04:31:15 JST +09:00
end
```

のようになります。ぴったりある時刻になるようなテストケースを書くには工夫が必要です。

なお、**back_to_the_present**は**back_to_the_1985**とも書けます。1985年には戻りません。

***end***
pushState未サポート時にhash fragmentを使わない設定


```backbone.js``` のデフォルトでは、pushState未サポート時は、 ```/``` に ```hash fragment``` を付与した動作となるため画面遷移を伴うWebアプリと相性が悪い。

```coffee版
window.App =
  Models: {}
  Collections: {}
  Views: {}
  Routers: {}
  init: (options)->
    options = {} unless options
    options.pushState = true
    options.hashChange = false # don't want to rewrite /pathname to #pathname

    # override getHash
    # this can fire backbone router when url doesn't has hash fragment
    Backbone.history.getHash = ->
      if window.location.search
        search = window.location.search
      else
        search = ''
      return window.location.pathname
    if Backbone.history && !Backbone.History.started
      Backbone.history.start(options)
```

```js版
window.App = {
  Models: {},
  Collections: {},
  Views: {},
  Routers: {},
  init: function(options) {
    if (!options) {
      options = {};
    }
    options.pushState = true;
    options.hashChange = false;
    Backbone.history.getHash = function() {
      var search;
      if (window.location.search) {
        search = window.location.search;
      } else {
        search = '';
      }
      return window.location.pathname;
    };
    if (Backbone.history && !Backbone.History.started) {
      return Backbone.history.start(options);
    }
  }
};
```

```options.hashChange = false``` によって、Hash Fragmentでの遷移を行わなくなる。しかしこのままだと、Routerのfireが動かなくなってしまうので、 ```Backbone.history.getHash``` をoverrideする。



```backbone.js```を、[JavaScript Url DispatcherとかRouterについて調べた](http://aligach.net/diary/20110306.html)にあるような使い方でも使えるようになる。

[gist:pushState未サポート時にfragment hashを使わない設定](https://gist.github.com/3155466)
OnLabへの行き方

Qiita/Kobito Meetup #1が開催されたOpen Network Lab(OnLab)への行き方です。
次のMeetupの時に迷わないようにメモしておきます。

googlemapが明後日の位置を示したりしてましたが、正確な場所はこのへんです。

![地図](http://maps.google.com/maps/api/staticmap?center=35.646226,139.703837&zoom=15&markers=35.646226,139.703837&size=500x300&sensor=true)

JR恵比寿駅からは西口を出て、目の前の大通りを左手に向かい、道路の左側をずっと歩いて行きます。
10分ほど歩くと通りから少し奥まった所にガラス張りの入り口があり、デジタルガレージさんの表札が出ています。
そのビルの11Fです。
KVM インストール

Ubuntu 12.04 LTS に KVM をインストールした。
[Quick Start Guide for installing and running KVM](http://publib.boulder.ibm.com/infocenter/lnxinfo/v3r0m0/index.jsp?topic=/liaai/kvminstall/liaaikvminstallstart.htm) を見ながら作業した。

### cpu が対応しているか調べる
このコマンドの結果が何も出力されない場合対応していない。

```bash
$ egrep '(vmx|svm)' --color=always /proc/cpuinfo
```

### kvm のインストール

```bash
$ sudo aptitude install kvm
$ sudo aptitude install virt-manager libvirt-bin virt-viewer
```

### kvm モジュールを入れる

```bash
$ sudo modprobe kvm
```

### intel 用のモジュール入れる

```bash
$ sudo modprobe kvm-intel
```

ここでサポートしていないというエラーが出た。
BIOS で Virtualization の項目をすべて Enable にし OS 起動したら
kvm_intel モジュールが入っていた

### モジュールの確認

```bash
$ lsmod | grep kvm
kvm_intel             137721  0
kvm                   415549  1 kvm_intel
```

### ゲスト OS のインストール

```bash
$ sudo virt-install \
--name mysql_0 \
--ram 1024 \
--disk path=/var/lib/libvirt/images/mysql_0.img,size=20 \
--network bridge=virbr0 \
-c ~/Downloads/ubuntu-12.04-server-amd64.iso
```

### クローン

```bash
$ sudo virt-clone -o mysql_0 -n mysql_1 -f /var/lib/libvirt/images/mysql_1.img
```

hostname がクローン後も同じだったので /etc/hostname, /etc/hosts を変更した。
quickrun.vim でテストを実行する

`<Leader>r` でファイルを実行する設定はそのままに、 `<Leader>t` ではテストを実行できるようにしてみた。

```vim:~/.vim/after/plugin/quickrun.vim
" キーマップの設定
nnoremap <buffer> <silent> <Leader>t :<C-u>QuickRun -mode n -type test:<C-r>=&filetype<CR><CR>

" テスト用の設定変数
" データ構造は g:quickrun_config と同じ
let s:quickrun_test_config = {}

" D言語の設定例
let d_type = copy(g:quickrun#default_config['d']['type'])
if d_type != ''
	let s:quickrun_test_config[d_type] = copy(g:quickrun#default_config[d_type])
	let s:quickrun_test_config[d_type]['cmdopt'] = '-unittest'
endif

" Rustの設定例
let s:quickrun_test_config['rust'] = copy(g:quickrun#default_config['rust'])
let s:quickrun_test_config['rust']['cmdopt'] = '--test'

" テスト用の設定を g:quickrun_config に追加
for k in keys(s:quickrun_test_config)
	let g:quickrun_config['test:' . k] = s:quickrun_test_config[k]
endfor

```
tmuxinatorで一瞬で開発環境を起動する

前回は[dr6kaiz](http://qiita.com/users/d6rkaiz)さんの[pow + rbenvで手軽なRack環境構築](http://qiita.com/items/0f0b15b800fcd8a742f9)でした。

今回は[tmuxinator](https://github.com/aziz/tmuxinator/)を使って、コマンド一発で開発環境を起動する話をします。

## tmuxinator とは
tmuxinatorとは、tmuxで起動するセッションを予め定義しておき、コマンド一発でそのセッションを起動できるようにしたものです。ちなみに、screenで同じことをする[screeninator](https://github.com/jondruse/screeninator)というツールもあります。こちらが先に開発されたようです。

## インストール

```sh
$ cd
$ gem install tmuxinator
$ echo "[[ -s $HOME/.tmuxinator/scripts/tmuxinator ]] && source $HOME/.tmuxinator/scripts/tmuxinator" >> .zshrc
$ source .zshrc
$ echo $EDITOR
/usr/bin/vi
$ echo $SHELL
/bin/zsh
```

- tmuxinatorはgemで提供されているので、`gem install`します。
- その後、補完スクリプトを`.zshrc`や`.bashrc`に追加して読み込みます。
- tmuxinatorは環境変数`$EDITOR`と`$SHELL`を使うそうなので、確認しておきます。

## 設定

```sh
$ mux new cui-aboutme
```

- `tmuxinator`とそのaliasの`mux`というコマンドが用意されています。
- `mux new [project name]`でプロジェクトの設定ファイルを作成します。
- このコマンドを実行すると、`$EDITOR`で設定されたエディタで以下のような設定ファイルが開きます。

```yml:~/.tmuxinator/cui-about.yml
# ~/.tmuxinator/sample.yml
# you can make as many tabs as you wish...

project_name: Tmuxinator
project_root: ~/code/rails_project
socket_name: foo # Not needed.  Remove to use default socket
rvm: 1.9.2@rails_project
pre: sudo /etc/rc.d/mysqld start
tabs:
  - editor:
      layout: main-vertical
      panes:
        - vim
        - #empty, will just run plain bash
        - top
  - shell: git pull
  - database: rails db
  - server: rails s
  - logs: tail -f logs/development.log
  - console: rails c
  - capistrano:
  - server: ssh me@myhost
```

- `rvm`で利用するrubyのバージョンを指定したり、`pre`でセッション起動時に実行するコマンドを指定できたりします。
- `tabs`でセッション内で起動するウィンドウを定義します。この初期設定だと、8つウィンドウを起動します。
- `tabs`内では、`editor`や`shell`といったキーがウィンドウ名を表し、値がそのウィンドウが起動したときに実行されるコマンドとなります。この初期設定だと、セッション起動と同時に8つのウィンドウが起動して、自動的に`git pull`したり`rails s`したり`ssh`したりします。
- `layout`と`panes`で、そのウィンドウ内のペインとその配置を定義します。`editor`を例にとると、ウィンドウ内に`vim`のペインと何もしないペインと`top`のペインが`main-vertical`で表示されます。

## 起動

```sh
$ mux cui-aboutme
```

- このコマンド一発で、上記で設定したセッションを起動します。
- 起動と同時に設定されたコマンドも自動で実行されます。

## カスタマイズ例

```yml:~/.tmuxinator/cui-aboutme.yml
# ~/.tmuxinator/sample.yml
# you can make as many tabs as you wish...

project_name: cui-aboutme
project_root: ~/workspace/rails/cui-aboutme
tabs:
  - main:
      layout: tiled
      panes:
        - git fetch --prune && git status --short --branch
        - curl http://cui-about.me/users
        - tig
  - vim: vi
  - app:
      layout: even-horizontal
      panes:
        - rails c
        - powder log
  - test: guard
```

- 僕の場合は「tigを中心としたgitの作業をするウィンドウ」「エディタのウィンドウ」「コンソールやログをみるウィンドウ」「自動テストを行うウィンドウ」の4つを一度に起動できるようにしてます。
- あと、起動時に`git fetch`でリポジトリの更新を確認したり、`guard`で自動テストを開始したりしてます。

## tips

- 一度に同時に起動するウィンドウを一度にすべて閉じるための設定

```.tmux.conf
bind-keys C-b kill-session
```

- 複数のプロジェクトに共通する設定は`~/.tmuxinator/default.yml`で設定できます。

## おまけ

- テキストベースの自己紹介サービス[cui-about.me](http://cui-about.me)やってます。よかったらどうぞ。
Mac OSX Lion に php mongodbドライバを入れる 


##概要
mongodbのドライバはpeclでインストールするのだが、
lionのphpには標準で入っていない。
peclはpearを入れると一緒に入る。

pearのインストーラーは、
/usr/lib/php/install-pear-nozlib.phar に入っている

##pearをインストール

```bash:
$ sudo php /usr/lib/php/install-pear-nozlib.phar
```


```bash:
$ sudo vi /etc/php.ini
```

で以下の行を付け加える

```ini:/etc/php.ini
include_path = ".:/php/includes:/usr/lib/php/pear"
```

##mongoドライバのインストール

```bash:
$ sudo pecl install mongo
```

以下の行を/etc/php.iniに付け加える

```ini:/etc/php.ini
extension=mongo.so
```

##確認
apacheを再起動

以下のファイルを表示してみる

```php:test.php
<?php 
phpinfo();
```

以下のような項目が見えることを確認する

```
mongo

MongoDB Support	enabled
Version	1.2.11

Directive	Local Value	Master Value
mongo.allow_empty_keys	0	0
mongo.allow_persistent	1	1
mongo.chunk_size	262144	262144
mongo.cmd	$	$
mongo.default_host	localhost	localhost
mongo.default_port	27017	27017
mongo.is_master_interval	60	60
mongo.long_as_object	0	0
mongo.native_long	0	0
mongo.no_id	0	0
mongo.ping_interval	5	5
mongo.utf8	1	1
```

mongoDBの入れ方は以下で
http://docs.mongodb.org/manual/tutorial/install-mongodb-on-os-x/
IEnumerable<T> を List<T>に変換するには .ToList() を使う

ちょっとつまづいたのでメモ。

C# の LINQ to Objects は、var で結果を受け取る限り、普段は変数の型をそれほど意識する必要はないのですが、メソッドの返り値として渡そうとしたところ、型が違うために以下のエラーが発生しました。

```
型 'System.Collections.Generic.IEnumerable<string>' を'System.Collections.Generic.List<string>' に暗黙的に変換できません。明示的な変換が存在します。(cast が不足していないかどうかを確認してください) (CS0266)
```

# 解決方法

.ToList()メソッドで、 IEnumerable<T> 型から List<T> 型に変換することで解決。

```csharp:sample_linq_tolist.cs
public static List<string> GetFileListWildcardExpanded(List<string> OriginalFileList)
{
	var newFileList = new List<string>();
	
	// (中略)

	// Distinct - 重複削除
	//return newFileList.Distinct();	// (CS0266)
	return newFileList.Distinct().ToList();
}
```
MonadTrans型クラス

いわゆるモナド変換子。[定義](http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/Control-Monad-Trans-Class.html)はこんなの。

```haskell:
class MonadTrans t where
    lift :: Monad m => m a -> t m a
```

以下の法則を満たす。

```haskell:
lift . return = return
lift (m >>= f) = lift m >>= (lift . f)
```

今まではなんとなく[モナドの分配則](http://en.wikipedia.org/wiki/Distributive_law_between_monads)で語るべき話かと思ってたんだけど、微妙に違うっぽい。具体的には、```lift```はモナド間の射(monad morphism)として[定義されている](http://www.fceia.unr.edu.ar/~mauro/pubs/mmt/mmt.pdf)。確かに、求められる法則を見ると```return```と```(>>=)```の構造を保持するような規則と読み取れる。

ところで、モナドは関手なので、その間の射であれば自然変換であるべきだ。```lift```も計算してみるときちんと自然変換になっている。```f :: a -> b```について可換性を見てみる。

```haskell:
(lift . (fmap f)) mx
 = lift(fmap f mx)
 = lift(mx >>= (return . f)) -- fmapの定義
 = lift mx >>= (lift . return . f) -- 法則2
 = lift mx >>= (return . f) -- 法則1
 = fmap f (lift mx) -- fmapの定義
= ((fmap f) . lift) mx
```

きちんと可換になっている。```fmap```や```return```が型が違うのに同じ表記になるのが見づらいが、要は```ξ_b ∘ Mf = Tf ∘ ξ_a```を示したことになる(ただし、```Monad m```はM、```Monad (t m)```はT、```lift```はξで表記)。

とここまで書いて、Monad (t m) は定義に入ってないことに気がついた。```return :: a -> t m a```とかを暗黙に期待しているから、別に要らないだろってことでいいのかな。
端末の向きが変わった回数をカウントする

端末の向きが変わる度にonDestroy→onCreateの順に呼び出されることを確認する簡単なアプリケーション。

```Java:OrientationChange.java
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;

public class OrientationChange extends Activity {
	private static int count = -1;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle bundle) {
    	super.onCreate(bundle);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        count++;
        setContentView(new OrientationChangeView(this, count));
    }
    
    @Override
    public void onStop() {
    	super.onStop();
    }
}

```

```Java:OrientationChangeView.java
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;

public class OrientationChangeView extends View {
	private int count;

	public OrientationChangeView(Context context, int count) {
		super(context);
		this.count = count;
        setBackgroundColor(Color.WHITE);
        setFocusable(true);
	}

	//描画時に呼ばれる
    @Override 
    protected void onDraw(Canvas canvas) {
        //描画オブジェクトの生成
        Paint paint=new Paint(); 
        paint.setAntiAlias(true);
        paint.setTextSize(16);
        
        //タッチXY座標の描画
        canvas.drawText("OrientationChanged>",0,20,paint);
        canvas.drawText(""+count,0,40,paint);
    }
}
```

端末の向きが縦→横→縦→横→…と変わる度に、向きが変わった回数がカウントされていくことを確認できた。

ただし、現状ではバックキーでホームに戻った後もアクティビティは起動したまま(メモリに残ったまま)になるためカウントがリセットされない。

キータッチイベントを検知して無理矢理リセットさせるなどの方策を採るようにしたい。
kobitosticker #kobito #qiita

![@naoya_tさん](https://p.twimg.com/Ax-uNpuCMAAxJ68.jpg)
![@pg_my](http://desmond.yfrog.com/Himg532/scaled.php?tn=0&server=532&filename=ku9im.jpg&xsize=640&ysize=640)
![@ppworks](https://p.twimg.com/Ax1QuMYCAAACmDG.jpg)
![@ongaeshiさん](https://p.twimg.com/AyQh6N0CEAE0BJB.jpg)
![@nysalorさん](https://s1-05.twitpicproxy.com/photos/large/629310449.jpg?key=43102868)
bashのトレースログ

-xオプションをつけるとトレースが出力される。ほへ〜。

```bash
$ bash -c 'for i in 1 2 3 ; do echo $i ; done'
1
2
3
$ bash -x -c 'for i in 1 2 3 ; do echo $i ; done' 
+ for i in 1 2 3
+ echo 1
1
+ for i in 1 2 3
+ echo 2
2
+ for i in 1 2 3
+ echo 3
3
```
test -e はワイルドカードを使えない


testコマンドのファイルの存在確認(-eオプション)でワイルドカードは使えない。代替としてはlsを使うとか…

```bash
$ ls
a.txt    b.txt
$ test -e *.txt && echo "exists"
$ (ls *.txt >& /dev/null) && echo "exists"
exists
```
Photoshopのちょっとした操作メモ(1)

* ```tab``` キーでワークスペースに表示されているツールパネルとパネル類の表示/非表示が出来る
* ```ズーム```
	* 長押しで、段階的にズームしていく
	* ```option``` キー押すと縮小
* ```space``` キー押しながら作業すると常に ```手のひら``` ツールになる
Rails 3.2 migrationメモ


## migration をつかったデータベーススキーマの操作

### migration ファイルの生成

あとから「必要なカラムが増えた」「カラムの名前を変更したい」「やっぱりこのテーブル要らない」など 保存するデータに変更があったときに、rails generate migration コマンドによるmigrationファイルの生成が役に立つ。

おおまかな手順としては、

1. 追加(/削除/変更)したいカラムやテーブルのマイグレーションファイルの生成
2. マイグレーションファイルの統合(rake db:migrate)
3. 手動で手を加える必要があるところを編集

----

eg. 生年月日カラムを追加するマイグレーションファイルの生成

```
rails g migration add_column_date_of_birth_to_students dateOfBirth:date
```
生成されたファイルの内容：

```ruby:YYYYMMDDHHMMSS__add_column_date_of_birth_to_students.rb
class AddColumnDateOfBirthToStudents < ActiveRecord::Migration
  def change
    add_column :students, :dateOfBirth, :date
  end
end
```

----

命名規約に沿わずにファイルを生成した場合(後述)、以下のファイルが生成される。

```ruby:YYYYMMDDHHMMSS__add_column_date_of_birth_to_students.rb
class Students < ActiveRecord::Migration
  def up
    
  end

  def down
   
  end
end
```
その場合、upにはテーブル、カラムの変更内容を、downには変更を戻す内容を記述する。

```ruby:YYYYMMDDHHMMSS__add_column_date_of_birth_to_students.rb
class Students < ActiveRecord::Migration
  def up
    add_column :students, :dateOfBirth, :date
    
  end

  def down
    remove_column :students, :dateOfBirth
  end
end
```

----

* データベースのカラムを追加する

```
rails g migration add_column_name_to_tableName column:dataType
```

* データベースのカラムを削除する

```
rails g migration remove_column_name_from_tableName columnName:dataType
```

* migration ファイルの適用

```
rake db:migrate
```
----
名前は自由に決めることができるが、生成するmigrationファイルの命名の中にaddやremove、changeなどがあると、それに反応して追加や削除など 命名に適したファイルを生成してくれる。

この、名前に応じたファイルを用意してくれるのは、リストにあげると、以下のとおり。

* add_column
* add_index
* change_column
* change_table
* create_table
* drop_table
* remove_column
* remove_index
* rename_column

----
※追加したり削除したカラムは、ファイルまでは自動で編集されないので、手動で編集する必要がある。(これでハマったことがあった。)


カラムを追加、データベースの統合もしたけど、なんかエラーが出る例：

```
rails g migration add_column_phone phone:string
```
```
rake db:migrate
```
ファイルを見てみると...

``` ruby:member.rb
class Hoge < ActiveRecord::Base
  attr_accessible :name, :address #「:phone」が追加されてない
end
```
-
### 参照
* [Ruby on Rails Guides: Migrations](http://guides.rubyonrails.org/migrations.html)
Railsデフォルトのjqueryは圧縮されてない

## 注記（7/21追記）

- production環境ではassets precompileによって圧縮されるため、下記の設定は不要です。
- assets pipelineを理解する上での参考程度にしてもらえればと思います。

---

```js:app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require_tree .
```

```sh
[1] pry(main)> puts Rails.application.config.assets.paths
/Users/naoty/workspace/sample/app/assets/images
/Users/naoty/workspace/sample/app/assets/javascripts
/Users/naoty/workspace/sample/app/assets/stylesheets
/Users/naoty/workspace/sample/vendor/assets/javascripts
/Users/naoty/workspace/sample/vendor/assets/stylesheets
/Users/naoty/workspace/sample/vendor/bundle/ruby/1.9.1/gems/jquery-rails-1.0.14/vendor/assets/javascripts
```

- `rails new`で生成されるapplication.jsでロードするjqueryは、上記のコマンドで確認できる通り、`jquery-rails`というgemに同梱されている`jquery.js`。ちなみに現時点では最新のv1.7.2。
- なので、圧縮されてないものがデフォルトではロードされてしまう。これは、けっこう気づきにくい罠だと思う。

```sh
$ cd `bundle show jquery-rails`
$ tree vendor/
vendor/
└── assets
    └── javascripts
        ├── jquery-ui.js
        ├── jquery-ui.min.js
        ├── jquery.js
        ├── jquery.min.js
        └── jquery_ujs.js
```

- `jquery-rails`の中を見てみると、`jquery.min.js`がある。
- 圧縮版あるんだから、こっち使う。
- `jquery-ui.min`もあるから、jquery-ui使う場合も同じ。まあ、jquery-uiは必要なコンポーネントだけに絞るべきなので、`jquery-rails`内のjquery-uiは使うことないと思う。

```js:app/assets/javascripts/application.js
//= require jquery.min
//= require jquery_ujs
//= require_tree .
```

- これで圧縮版のjqueryをロードする。