OmniAICreator/Qiita-1.07M huggingface dataset:
Zend\DbのHydratingResultSetでgetter/setter

## その１ - publicメンバーをもつPOPOに対しObjectPropertyを使う

``` php
<?php
use Zend\Db\Adapter\Adapter;
use Zend\Db\ResultSet\HydratingResultSet;
use Zend\Db\TableGateway\TableGateway;

use Zend\Stdlib\Hydrator\ObjectProperty;

$config = include 'bootstrap.php';

class News
{
    public $id;
    public $title;
}

$hydratingResultSet = new HydratingResultSet(new ObjectProperty, new News);
$adapter = new Adapter($config);

$table = new TableGateway('news', $adapter, null, $hydratingResultSet);
$select = $table->select();

var_export($select->current());
/**
News::__set_state(array(
   'id' => '1',
   'title' => 'Sample News',
   'project_id' => '1',
   'summary' => 'Working fine.',
   'description' => 'Worked
*YEAH!!*',
   'author_id' => '3',
   'created_on' => '2009-03-20 23:25:45',
   'comments_count' => '0',
))*/
```

宣言されてないメンバ変数にアサインされるの気持ち悪かったら中身のない__set()でも用意すればいいんじゃないでしょうか（いや、どうだろう）

## その2 - ClassMethodsハイドレータでsetterの手間を省く

``` php
<?php
use Zend\Db\Adapter\Adapter;
use Zend\Db\ResultSet\HydratingResultSet;
use Zend\Db\TableGateway\TableGateway;

use Zend\Stdlib\Hydrator\ClassMethods;

$config = include 'bootstrap.php';

class News
{
    protected $id;
    protected $title;

    public function setId($id)
    {
        $this->id = $id;
    }

    public function setTitle($title)
    {  
        $this->title = $title;
    }
}

$hydratingResultSet = new HydratingResultSet(new ClassMethods, new News);
$adapter = new Adapter($config);

$table = new TableGateway('news', $adapter, null, $hydratingResultSet);
$select = $table->select();

var_dump($select->current());
```


## その3 - Refletcionハイドレータでsetter/getterメソッドを用意する手間を省く

``` php
<?php
use Zend\Db\Adapter\Adapter;
use Zend\Db\ResultSet\HydratingResultSet;
use Zend\Db\TableGateway\TableGateway;

use Zend\Stdlib\Hydrator\Reflection as ReflectionHydartor;

$config = include 'bootstrap.php';

class News
{
    protected $id;
    protected $title;
}

$hydratingResultSet = new HydratingResultSet(new ReflectionHydartor, new News);
$adapter = new Adapter($config);

$table = new TableGateway('news', $adapter, null, $hydratingResultSet);
$select = $table->select();

var_dump($select->current());
```

Hydratorのまっとうな使い方は多分このへんです
https://github.com/speckcommerce/SpeckCart/blob/master/src/SpeckCart/Mapper/CartItemMapperZendDb.php
Zend\DbのProfilerを利用する

Zend\Dbを単体で使わず、SkeletonApplication使ってる場合は、[ZendDeveloperTools](https://github.com/zendframework/ZendDeveloperTools)で使われてるBjyProfilerでも使った方がいいと思います。
※ ちなみに、私が使ってるzf2のversionはdevelopです。

``` php
<?php
use Zend\Db\Adapter\Adapter;
use Zend\Db\Adapter\Profiler\Profiler;
use Zend\Db\Adapter\StatementContainer;
use Zend\Db\TableGateway\TableGateway;
use Zend\Db\Sql\Select;

$config = include 'bootstrap.php';
$adapter = new Adapter($config);


$profiler = new Profiler;
$adapter->setProfiler($profiler);

$table = new TableGateway('news', $adapter);

$profiler->profilerStart(new StatementContainer);

echo $table->select(function(Select $select){$select->where('id', 1);})->current()->id; // 1

$profiler->getLastProfile();
```
ifのネスト

条件がいっぱいある時、ifのifの〜見たいにネストしてしまうことがあると思います。書いている最中は、わかりやすいのでよいのですが、読むときって辛いですね。条件を満たさない場合は、途中リターンという手もありますが、コーディングルールなどreturnは、必ず最後、goto文は使うなというケースがたまにあります。そんな時にちょっとだけネストをなくせる方法です。
※私のスタンスとしては、途中returnはOK、goto文はエラーや多重ループから抜ける場合などだけ使うって感じです。

こんな例を考えてみます。

```c:sample.c
if( 条件A ) {
} else {
    if( 条件B ) {
    } else {
        if( 条件C ) {
        } else {
           処理実行
        }
    }
}
```

途中リターンやgoto文が禁止されている場合には、下のような感じで書くとネストが少なくなりますね。でもこれって、goto文と変わらないですね。

```c:sample.c
do {
    if( 条件A )
        break;
    if( 条件B )
        break;
    if( 条件C )
        break;
    処理実行
} while(0);
```
Windowsでvagrantプラグインsaharaをインストール

仮想マシンの状態を簡単にロールバックできるsaharaプラグインをwindowsにインストールする

##saharaインストール
```
vagrant gem install sahara
```
でインストールできるはずが、jsonのインストールでエラーになり以下の
メッセージが表示されるのでDevKitを先にインストールする

```
You have to install development tools first.
```

###DevKitのインストール

http://rubyinstaller.org/downloads/
DevKit-tdm-32-4.5.2-20111229-1559-sfx.exeをダウンロード実行し展開し、任意の場所におく

dk.rbのあるフォルダでコマンドラインを開き初期化

```
ruby dk.rb init
```

生成されたconfig.ymlにvagrant上にあるrubyのrootパスを記載する

```
- C:/vagrant/embedded
```

```
# DevKitをインストール
ruby dk.rb install

# すでにあると警告がでたら-fを付けて強制インストール
ruby dk.rb install -f
```

再度、`vagrant gem install sahara`でインストール。vagrant sandboxコマンドが使えるようになる
```

##sandboxコマンド
```
# sandbox モードに入る
vagrant sandbox on

# 変更を取り消し
vagrant sandbox rollback

# 変更を確定
vagrant sandbox commit
```
JavaScriptでカリー化関数を作る

## 実装

coffeeならなんと一行です。

```coffeescript
Function::curry = (args1...) -> (args2...) => @apply @, args1.concat args2
```

apply黒魔術最高！(黒って言う程でもないけど)


※ prototype拡張してるので信条に反する人は注意

JSならこうなる(↑をコンパイルしただけ)

```javascript
Function.prototype.curry = function() {
  var args1,
    _this = this;
  args1 = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
  return function() {
    var args2;
    args2 = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
    return _this.apply(_this, args1.concat(args2));
  };
};
```

## 使い方

```coffeescript
Function::curry = (args1...) -> (args2...) => @apply @, args.concat args2

add3val = (x, y, z) -> x + y + z
f1 = add3val.curry(1)(2, 3)
f2 = add3val.curry(1, 2)(3)
f3 = add3val.curry(1, 2, 3)()

console.log f1, f2, f3 #=> 6 6 6
```

これでより関数型っぽくなりましたね、必要かどうかはともかく
注意点として、カリー化した関数はその時点での参照を保持しているので、ちゃんとdeleteしないとメモリが漏れます。
vagrantをwindowsにインストール

##virtualboxのインストール
https://www.virtualbox.org/wiki/Downloads
最新バージョンはvagrantでサポートされていないので、4.1のインストーラをOld Buildsからダウンロードする

##vagrantインストール
http://downloads.vagrantup.com/
windows用のインストーラ、Vagrant.msiをダウンロードしてインストールする。

ここでは、C:\直下にインストール。C:\vagrant\フォルダが作成される

##仮想マシン(box)の追加と初期化
http://www.vagrantbox.es/

```
# VMの追加
vagrant box add {title} {url}
```
CentOS-6.3を追加する場合は

```
vagrant box add centos63 http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.3-x86_64-v20130101.box
```

```
# 初期化
vagrant init {title}
```
さきほど追加したcentos63を初期化してみる

```
# 作業ディレクトリに移動
cd C:\dev\vagrant_home\centos63

# 初期化
vagrant init centos63
```

設定ファイル、Vagrantfileがカレントディレクトリに作成される

##VMの起動
```
vagrant up
```
起動したディレクトリがVM上の/vagrantにマウントされる

##SSH
windowsではvagrant sshコマンドは使えないので、puttyなどで接続する

```
# 初期状態の接続情報
host:     127.0.0.1
port:     2222
User:     vagrant
Password: vagrant
```

## vagrantコマンド
```
#マシンの起動
vagrant up

#マシンのシャットダウン
vagrant halt

#マシンの再起動
vagrant reload

# boxのパッケージ化
vagrant package
オプション
--base NAME
--output NAME

#イメージの一覧
vagrant box list
```

####参考
http://www.ryuzee.com/contents/blog/4292
http://d.hatena.ne.jp/naoya/20130205/1360062070
http://kazuph.hateblo.jp/entry/2013/02/05/234243
Zend\DbでSelect FOR UPDATE、LOCK IN SHARE MODE を発行する

今のバージョンでやや強引にやろうとすると↓な感じ

```php
<?php
use Zend\Db\Sql\Sql;
use Zend\Db\Sql\Select;
use Zend\Db\Sql\Platform\Mysql\Mysql as PlatformMysql;
use Zend\Db\Sql\Platform\Mysql\SelectDecorator;

use Zend\Db\Adapter\AdapterInterface;
use Zend\Db\Adapter\ParameterContainer;
use Zend\Db\Adapter\StatementContainerInterface;

$adapter = include 'bootstrap.php';

class MySelectDecorator extends SelectDecorator
{
    public function prepareStatement(AdapterInterface $adapter, StatementContainerInterface $statementContainer)
    {
        // ensure statement has a ParameterContainer
        $parameterContainer = $statementContainer->getParameterContainer();
        if (!$parameterContainer instanceof ParameterContainer) {
            $parameterContainer = new ParameterContainer();
            $statementContainer->setParameterContainer($parameterContainer);
        }

        $sqls = array();
        $parameters = array();
        $platform = $adapter->getPlatform();
        $driver = $adapter->getDriver();

        foreach ($this->specifications as $name => $specification) {
            //$parameters[$name] = $this->{'process' . $name}($platform, $driver, $parameterContainer, $sqls, $parameters);
            $parameters[$name] = $this->select->{'process' . $name}($platform, $driver, $parameterContainer, $sqls, $parameters);
            if ($specification && is_array($parameters[$name])) {
                $sqls[$name] = $this->select->createSqlFromSpecificationAndParameters($specification, $parameters[$name]);
            }
        }

        //$sqls[] = 'FOR UPDATE';
        $sqls[] = 'LOCK IN SHARE MODE';

        $sql = implode(' ', $sqls);

        $statementContainer->setSql($sql);
        return;
    }

}

$sql = new Sql($adapter, null , new PlatformMysql(new MySelectDecorator));

$select = $sql->select()->from('news')->where(['id' => 1]);

$statement = $sql->prepareStatementForSqlObject($select);
$results = $statement->execute(); // SELECT `news`.* FROM `news` WHERE `id` = '1' LOCK IN SHARE MODE
```

まじめにやるならZend\Db\Sql\Selectのspecificationsにキー用意して、processForUpdateメソッドの実装とかresetとかを実装しなきゃいけないのは置いといて、そもそも
Zend\Db\Sql\Platform\*\SelectDecoratorたちは各プラットフォームの差異の吸収が目的っぽいのでSelectDecoratorだけのspecificationが存在しては一貫性なさそうでダメそう。
デジタル証明書ポップアップでWebDriverがエラーになるのをかわす

アクセスするとデジタル証明書を選択しろと促すポップアップが出るページに
WebDriverで普通にget()とかnavigate().to()すると。
AWT-EventQueue-0というところでModal Dialogエラーが出る。
デジタル証明書のポップアップがキャンセルされて落ちる。
という現象についてクリアするためにやったことまとめ


#### Alertクラスを使う
デジタル証明書のポップアップをAlertと捉え、
get(URL)した直後に `Alert alert = driver.switchTo().alert()` しようとした。

→エラーがAWT-EventQueue-0で起きてるということは
つまりget()のなかで起きているということで。
それはつまりget()の後に何書いてもそこまでいかないということで。
（取れませんでした）


#### クッションを入れる
一度ポップアップがキャンセルされたあと
「ページを表示できません」画面になったブラウザを更新すると
ポップアップが復活することを確認したので、
まず `driver.get("about:blank");` して、
そのあと `driver.navigate().to(目的のURL);` とごまかしてみた。

→ごまかせませんでした（理由は同上）


#### WebDriverを使わずに遷移(1) javascript
WebDriverを使うとポップアップをkillしてしまうのではないかと。
先程クッションとしてabout:blankを使ったが、
その代わりに空のHTMLを書いてその中でjavascriptでページ遷移させた。
いわゆるlocation.hrefというやつ。

→落ちない！うええいよっしゃあああ！！
とおもったけどブラウザのバーのところに警告が表示されて、
そこで毎回手でacceptしないとポップアップを表示してくれないので、
ちょっとめんどくさい。黙ってポップアップを出してほしい。


#### WebDriverを使わずに遷移(2) HTML
ならばmetaタグ書き換えはどうだ！
よくある、このページは移転しました。10秒後に自動的に移動します。
をやっているやつをクッションページに埋め込んでみた。
 `<meta http-equiv="REFRESH" content="遷移までの秒数;URL=目的のURL">`

→大成功。
get(クッションHTML)するとmetaタグで目的のURLに遷移、
そのとき先にデジタル証明書ポップアップを表示、
選択するとちゃんとページを表示してくれました。めでたしめでたし


#### まとめ
Selenium+WebDriverあんまり関係なかった
ターミナルの幅をC言語で取得

linuxのlsコマンドのオプションなしの場合、出力結果の1つのファイルが二つの行に分かれてしまうことがないです。これを実現するためには、端末のサイズ内にファイル名が収まるかという判定が必要になります。どうやって端末のサイズを取得するのかという疑問が浮かんだので、調べて見ました。以下は端末サイズを取得するためだけのサンプルです。

```:c
#include <sys/ioctl.h>
#include <unistd.h>

static size_t line_length = 80;
int main( int argc, char *argv[] )
{
    struct winsize ws;
    // get terminal size
    if( ioctl( STDOUT_FILENO, TIOCGWINSZ, &ws ) != -1 ) {
        printf("terminal_width  =%d\n", ws.ws_col);
        printf("terminal_height =%d\n", ws.ws_row);
        if( 0 < ws.ws_col && ws.ws_col == (size_t)ws.ws_col ) {
            line_length = ws.ws_col;
        } 
    }
    return 0;
}
```
coffeescript で簡単なアプリを express を使って作ってHerokuにデプロイする例

https://github.com/katoy/katoy-sample
に 
　　coffeescript で簡単なアプリを express を使って作ってHerokuにデプロイする例
を置いています。

commit 前に local マシン上でもテストをできるようにもしてあります。
（現状のテスト内容は とても単純なものだけど）
Hiveで配列で保存されたカラムを展開して集計する

LATERAL VIEW を使うと配列を展開しそれぞれの要素が結合されるのでそれを利用する。

ex)
users テーブル内の attributes にユーザの属性が登録されていて女性ユーザの人数を取得する場合。

* users table

| name              | type               |
|:------------|:------------|
| user_id           | string            |
| user_attributes| array             |

* attributes array

["female", "28", "orange"]
["male", "18", "car"]
["female", "32", "art"]

```sql
SELECT count(*) FROM tracks 
LATERAL VIEW explode(attributes) exploded_attributes AS attribute
  WHERE
    attribute = 'female'
```

下記の様に結合されるので条件を設定することで件数を集計できる。

| user_id           | attribute         |
|:------------|:------------|
| 1                    | female            |
| 1                    | 28                   |
| 1                    | orange             |
| 2                    | male            |
| 2                    | 18                   |
| 2                    | car             |
| 3                    | female            |
| 3                    | 32                   |
| 3                    | art             |

https://cwiki.apache.org/Hive/languagemanual-lateralview.html
一時的に除外したいソースは #if falseで。

一時的に動かしたくないソースは コメントアウトしていることがあります。

```csharp:コメントアウト
/*		int test = 0;

		for( int i = 0; i < 1000; i++){
			test=100;
		}
*/
```

しかし、コメントアウトにすると 折りたたむことができません。

そこで #if false を使用すると、折りたたむことができるようになります。

```csharp:＃if
#if false
		int test = 0;

		for( int i = 0; i < 1000; i++){
			test=100;
		}
#endif
```
```#if``` を書くときに 
　範囲を選択
　右クリック
　ブロックの挿入(S) Ctrl+K, Ctrl+T
　「#if」 と入力
で 書くこともできます(VisualStudio2010で確認)
C 中級者が意外と陥りやすいワナ

ある程度プログラミングにも慣れ、言語仕様もそこそこ理解した中級者にとって意外と陥りやすくセキュリティホールの温床になりがちなワナを幾つか。
勿論オンラインマニュアルにも仕様として明記されているのですが、直感とは反する仕様のなので特に中級者にこれらのミスが多い気がするので注意喚起を込めての記事です。

## *strncpy* (3) は **\0** 終端してくれない場合がある

*strcpy* (3) はバッファオーバーフローの危険性があるから *strncpy(3)* を利用する様によく言われますが、ここにワナが潜んでいます。

```c:
	strncpy(dst, src, len);

```

とした時に文字列 src の長さが len バイト未満の場合は dst は **\0** で終端されます。と言うか、終端どころか dst の残り領域は何故か 全て **\0** が詰められるという無駄とも思われる謎仕様。
ところが文字列 src の長さが len バイト以上の場合、dst に len バイトだけコピーするという *memmove* (3) 同様の動作となってしまい、dst が **\0** で終端されません。文字列操作の関数なのにも関わらず得られた結果が文字列として扱えないという不思議な仕様なのです。*snprintf* (3) などの様に len - 1 バイトを dst にコピーして **\0** で終端される事を期待していると痛い目に遭ってしまいます。

文字列操作関数なので、殆んどの場合 **\0** 終端が必要になると思うので、以下の様な処理が代替になります。

```c:mystrncpy.c
	
	char *
	mystrncpy(char *dst, const char *src, size_t len)
	{

		strncpy(dst, src, len - 1);
		*(dst + len - 1) = '\0';

		return(dst);

	}

```

## *strncat* (3) のサイズ指定はコピー先のサイズを指定するのではない

*strcat* (3) も同様にバッファオーバーフローの危険性があるので *strncat* (3) を利用する様によく言われますが、 ここにもワナが潜んでいます。

```c:
	strncat(dst, src, len);

```

とした時の len はコピーする src の長さであって、 *strncpy* (3) や *snprintf* (3)の様に dst のサイズ指定ではありません。ここで dst のサイズのつもりで len を指定するとバッファオーバーフローの原因になってしまいますので要注意。

殆んどの場合は dst の最大値が重要になると思うので以下の処理が代替になります。

```c:mystrncat.c

	char *
	mystrncat(char *restrict dst, const char *restrict src, size_t len)
	{

		return(strncat(dst, src, len - strlen(dst) - 1));

	}

```

## *snprintf* (3) は領域が重なってはいけない

前述した通りに使いやすいとは言いづらい *strncpy* (3) や *strncat* (3) の代用として、コピー先のサイズ指定が直感的な *snprintf* (3) を利用する場合も多いと思いますが、`strncat(dst, src, len)` の置き換えとして

```s:mystrncat.c
	snprintf(dst, sizeof(dst), "%s%s", dst, src)

```

とすると正しく動作しません（結果は処理系依存になる様です）。
ANSI X3.159-1989 (ANSI C) や ISO/IEC 9899:1999 (ISO C99)、IEEE Std 1003.1-1988 (POSIX.1) 等をざっと探したけど関連する記述は見つける事はできませんでした。しかし、*snprintf* (3) は重なった領域では正しく動作しない様です。

> FreeBSD のオンラインマニュアルには
>
>>	int
>>	snprintf(char * restrict str, size_t size, const char * restrict format, ...);
>
> となっているので確かに重なった領域はダメな様ですが規格的な根拠> はいずこ？

以上、C によるプログラミングに慣れた頃に陥りがちなワナでした
Scalaで競技プログラミング（入出力編）

入出力編以外が出来るかは不明。

最近Scalaで競技プログラミングをしていて入出力とその周辺が遅くてはまったのでメモ。
たぶん内容自体はJavaの入出力とその周辺。

実行時間は以下で計る。

```scala
object Utility {
  def measureTime(func: => Unit): Long = {
    val start = System.currentTimeMillis()
    func
    return System.currentTimeMillis() - start
  }
}
```

単純な出力
-------------

```scala
object Main {
  def main(args: Array[String]): Unit = {
    val rnd = Random
    System.err.println(Utility.measureTime {
      for (_ <- 1 to 1000000) println(rnd.nextInt())
    } + "ms")
    val pw = new PrintWriter(System.out)
    System.err.println(Utility.measureTime {
      for (_ <- 1 to 1000000) pw.println(rnd.nextInt())
      pw.flush()
    } + "ms")
  }
}
```

```text:結果
17045ms
389ms
```
単純なprintlnは遅い。

フォーマット付き出力
-----------------------

```scala
object Main {
  def main(args: Array[String]): Unit = {
    val rnd = Random
    val pw = new PrintWriter(System.out)
    System.err.println(Utility.measureTime {
      for (_ <- 1 to 1000000) pw.println(rnd.nextInt() + " " + rnd.nextInt())
    } + "ms")
    System.err.println(Utility.measureTime {
      for (_ <- 1 to 1000000) pw.println("%d %d".format(rnd.nextInt(), rnd.nextInt()))
    } + "ms")
    pw.flush()
  }

}
```

```text:結果
1068ms
6627ms
```
Stringのformatは遅い。

入力
------
一行にIntがスペース区切りに二つで1000000行のファイルを読み込む

普通に読み込みsplitで区切る
--------------------------------

```scala
object Main {
  def main(args: Array[String]): Unit = {
    System.err.println(Utility.measureTime {
      for (_ <- 1 to 1000000) readLine().split(' ')
    } + "ms")
  }
}
```

```text:結果
2269ms
```

入力クラスを作って使う
-------------------------
以下のクラス使います

```scala
class InputReader(stream: InputStream) {
  private val reader = new BufferedReader(new InputStreamReader(stream))
  private var tokenizer: StringTokenizer = new StringTokenizer(reader.readLine())
  def next(): String = {
    while (!tokenizer.hasMoreTokens()) {
      tokenizer = new StringTokenizer(reader.readLine())
    }
    tokenizer.nextToken()
  }
}
```

```scala
object Main {
  def main(args: Array[String]): Unit = {
    val in = new InputReader(System.in)
    System.err.println(Utility.measureTime {
      for (_ <- 1 to 1000000) {
        val a, b = in.next().toInt
      }
    } + "ms")
  }
}
```

```text:結果
1141ms
```
splitは遅い。

まとめ
----------

入出力というよりはStringのformatとかsplitが遅くてはまっていた。
今現在はformatとsplitを使わないようにしながらPrintWriterとInputReaderを使うようにしている。
RailsアプリにBootstrapを適用させる


対象となるgemのインストール
Gemfileに以下を追記する

```Gemfile
gem "therubyracer"
gem "less-rails" #Sprockets (what Rails 3.1 uses for its asset pipeline) supports LESS
gem "twitter-bootstrap-rails"
```

・twitter-bootstrap-railsはLESSを使用するため、therubyracerが必須
・LESSのスタイルシートを使うにはless-railsというgemが必要
・JavaScriptのエンジンであるv8*3をRubyから使えるようにするgem　(謎）
ということで上記３つのgemを入れます。

追記し終わったらgemの更新

>$ bundle install

それが終わったらbootstrapジェネレータを使ってassetsへincludeファイルをインストール

>$ rails generate bootstrap:install less

続いてlayoutファイルの生成

>rails generate bootstrap:layout application fixed

レスポンシブデザインに対応させたいときはこっちのコマンド

>rails generate bootstrap:layout application fluid

#####注意
layoutにtwitter-bootstrapを反映させることでfavicon_link_tagが挿入されるのでこのままdeployするとfavicon_link_tagがないことでassets_precompileの段階でエラーが起きます。
deployするときはlayoutからfavicon関連を削除してください。

##デザイン
bootstrap公式ページ(http://bootswatch.com/) から
気に入ったのを選び、variables.lessをbootstrap_and_overrides.css.lessへ追記すればデザインが変更できます。

##参考
・Twitter Bootstrap for Rails 3.1 Asset Pipeline https://github.com/seyhunak/twitter-bootstrap-rails

・twitter-bootstrap-rails ことはじめ
http://qiita.com/items/7b7e5934004a49591ed8
Railsで簡単なアプリをscaffoldで作ってHerokuにデプロイするまで


##local上にアプリを作成

>$ rails new app_name

本番用のdatabaseをpostgreSQL、開発、テスト用のdatabaseをsqliteに設定する。Gemfile内の

```Gemfile
gem 'sqlite3'
```

を

```Gemfile
gem 'sqlite3', :group => [:development, :test]
group :production do
  gem 'pg'
end
```

に変更する。
そして、gemの更新

>$ bundle install --path vendor/bundle

heroku上ではvendor/bundleでgemを管理できないことがわかった。なので以下でgemを更新するべき。

>$ bundle install

作成したアプリをgitの管理下においてコミットまでしておく

>$ cd app_name
>$ git init
>$ git add
>$ git commit -m "initial commit"


##heroku用の鍵を作成する
>$ ssh-keygen -C 'e-mail Address' -t rsa

鍵をherokuに登録するのも忘れずに（忘れるとpermission deniedとなりherokuにpush出来ない）

>$ heroku keys:add

##heroku上へのアプリ作成
heroku上にアプリ名を指定してアプリを作成する。app_nameに何も指定しないとランダムな名前が付けられる。(git管理下においた場所で以下のコマンドを打つことで'heroku'にリモートリポジトリが自動的に登録される）

>$ heroku create app_name

##herokuにソースコードをアップロード
gitのpushを使ってソースコードをアップロードしてみる。

>$ git push heroku master

herokuへのpushが成功すると http://appname.herokuapp.com/　 へpublic/index.htmlが表示される。

##scaffoldで簡単なアプリの作成
Railsのscaffold機能でアプリ（通院記録管理アプリ）を作成してみる。

>$ rails g scaffold complog commute_date:date hosp_loc:integer

終わったらdbの作成

>$ rake db:create

次にdatabase.ymlからデータベースの更新

>$ rake db:migrate

ローカル環境で動くか確認

>$ rails s
>$ open localhost:3000/モデル名s

動作を確認できたらgitでコミットしてherokuにpush
heroku上にdatabaseを作成、更新

>$ heroku run rake db:create
>$ heroku run rake db:migrate

これが終わったらherokuにもらったURLにアクセスして動作を確認

heroku app管理: https://dashboard.heroku.com/apps
Homebrewを使ったPostgreSQLのインストール(Mac OS Lion)

※こちら内容がかなり古くなっていたのでMac OS El CapitanでPostgreSQLをインストールした記事を書きました。
[Homebrewを使ったPostgreSQLのインストール(Mac OS El Capitan)](http://tstomoki.com/programming/posgre_inst)

heroku用にPostgreSQLを使ったアプリを作りたかったので確認用にPostgreSQLをインストールします。

##HomebrewでPostgreSQLのインストール
>brew install postgresql

##データベースの初期化 (文字コードはUTF-8)
>initdb /usr/local/var/postgres -E utf8

PostgreSQLサーバの起動

>postgres -D /usr/local/var/postgres

データベース一覧が取得出来ればインストール成功

>psql -l

Mac OS Lion だとこんなエラーが出ますが、LionにはデフォルトでPostgreSQLが既にバンドルインストールされてるらしいですね。

>psql: could not connect to server: No such file or directory
	Is the server running locally and accepting
	connections on Unix domain socket "/var/pgsql_socket/.s.PGSQL.5432"?

修正用バッチをファイルをcurlでインストールし適用。

>curl -o fixBrewLionPostgresql.sh http://nextmarvel.net/blog/downloads/fixBrewLionPostgres.sh

ファイル権限の変更

>chmod 777 fixBrewLionPostgresql.sh


バッチシェルの実行

>./fixBrewLionPostgresql.sh

これでもう一度

>psql -l

をすればデータベース一覧が取得できるはずです。

##環境変数の設定
環境変数PGDATAの設定。bashなら~/.bashrc、今回は~/.zshrcに以下を記述

```~/.zshrc
export PGDATA=/usr/local/var/postgres
```

変更を反映 (Terminalソフトの再起動でも可)

> source ~/.zshrc

PostgreSQLサーバの起動

>pg_ctl -l /usr/local/var/postgres/server.log start

PostgreSQLサーバの終了

>pg_ctl -D /usr/local/var/postgres stop -s -m fast

##PostgreSQLの自動起動設定
自動起動リストにPostgreSQLの追加

>cp /usr/local/Cellar/postgresql/9.3.2/homebrew.mxcl.postgresql.plist ~/Library/LaunchAgents/

自動起動リストの設定ファイルの読み込み

>launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist

##コマンドライン上でのPostgreSQLの起動とコマンド
###起動

>psql 'database名'

###終了(プロンプト上)

>\q

###データベース作成

>createdb 'database名'

###データベース一覧表示

>psql -l
fluent-plugin-twitter & fluent-plugin-datacounter


# fluent-plugin-twitter

https://github.com/y-ken/fluent-plugin-twitter

y-ken さんが公開して下さっている fluent-plugin-twitter を使うと tweetstream gem を使って streaming api でツイートを受信して fluentd で扱うことができるようになる。

# fluent-plugin-datacounter

https://github.com/tagomoris/fluent-plugin-datacounter

tagomoris さんが公開して下さっている fluent-plugin-datacounter を使うと指定した時間内に正規表現にマッチするログが何件あるかを数えてその結果を fluentd で扱うことができるようになる。

# ツイート数をリアルタイムにカウントする

今回はこの二つを使って、あるアカウントのホームタイムラインのツイートをカウントして mongodb に保存してみたい。

```xml:fluentd.conf
## fluentd conf

# fluent-plugin-twitter の設定
<source>
  type twitter
  consumer_key        ***
  consumer_secret     ***
  oauth_token         ***
  oauth_token_secret  ***
  tag                 input.twitter.test
  timeline            userstream
  output_format       nest
</source>

# fluent-plugin-datacounter の設定
<match datacount.**>
  type copy
  <store>
    type mongo
    host        localhost
    database    fluentd-test
    collection  datacountsample
  </store>
  <store>
    type stdout
  </store>
</match>

# 受信したツイートを処理する設定
<match input.twitter.**>
  type copy
  <store>
    type datacounter
    tag  datacount.twitter.5m
    count_interval 5m
    aggregate all 
    input_tag_remove_prefix input.twitter.test
    output_messages  true

    # ここの設定は変える必要ある
    count_key id_str
    pattern1 tweet ^\d*
  </store>
  <store>
    type mongo
    host        localhost
    database    fluentd-test
    collection  twittersample
  </store>
</match>
```
UTF-8文字列を指定バイトに収まるように短くする

ある理由により、UTF-8 な文字列を指定バイトに収まる最大長でぶったぎりたくなりました。
平たく言うと、Linux などで採用されているファイルシステムではファイル名の最大長が255バイトなので、Windows や Mac で作成されたファイルを保存できないことがあるのでなんとかしたいと思った訳です。
UTF-8は一文字あたりのバイト数が一定ではない文字コードなので、単に文字数でぶった切ると255バイトをオーバーしかねません。最大6バイトなので 255÷6で42文字にしておけば安全ですが、どうせならできるだけ長いファイル名にしたいってもんです。

Ruby/Rails 初心者の私は当然ながらそういうバイトぶった切りお手軽関数が用意されていることを期待したんですが、社内の達人に聞いたところ「ない」というにべもない答えが返ってきました。
ほんとかなと思って手を尽くして検索してみましたが、確かにないみたい・・・。
コピペプログラマとしては万事休すです。
しかしどう検索してもみつからないので、仕方なく自作しました。
あ、社内の達人もほんのちょっとだけ手伝っています。

```
      original_file_extension = File.extname(@original_filename)
      #@original_filename = File.basename(@original_filename)

      @original_filename.force_encoding("ascii-8bit")

      pp "ascii"
      pp @original_filename

      @original_filename = @original_filename[0, (configatron.uploadfilename.bytesize - original_file_extension.bytesize)]

      pp "slice"
      pp @original_filename

      @original_filename.encode!("UTF-16BE", "UTF-8", :invalid => :replace, :undef => :replace, :replace => '')
      @original_filename.encode!("UTF-8")

      pp "utf-8"
      pp @original_filename

      @original_filename += original_file_extension

      pp "bytesize"
      pp @original_filename.bytesize
```

configatron.uploadfilename.bytesize は255を設定しています。
ところどころデバッグライトしてますが、当然なくても動きます。
@original_filename はパスを含まないファイル名のみが渡ってくるの前提です。

+文字エンコーディングをASCII-8bitに変更してバイト単位のぶった切り
+String#encode を使用して、ぶった切りの際に発生した不正な UTF-8 文字列を更正

ってあたりが肝でしょうか。
後者については下記サイトを参考にしました。

[Rubyでinvalidなバイト列を含むUTF-8文字列を扱う](http://d.hatena.ne.jp/yarb/20110112/p1)
[Ruby の invalid byte sequence in UTF-8 例外を encode("UTF-8", "UTF-8") で回避するのはおかしいよ、という話](http://blog.livedoor.jp/sonots/archives/23652294.html)

2バイト〜4バイトの UTF-8 文字列が混在するようなファイル名をいろいろ付けてみてテストしましたが、うまく動いてくれているようです。
最終行でぶった切り後のバイト数を表示していますが、253あたりの数字が表示されると、無駄なく使えている感が感じられて思わずにんまりしてしまいました。

「ここはこう直した方がいいんじゃない？」「その目的のコードはここに書いてあるよ！」と言った情報をお持ちの方は、ぜひ教えてくださいね。
ログ監視スクリプト

linuxには、tail -fという便利なコマンドがあります。os.statというものがあるというのを今日知ったのでちょこっとソースを書いてみた。引数から渡されたファイルを監視するようにしています。ファイルの末尾への移動、現在のファイルポインタの位置の取得方法、ファイルからのデータの読み出し方法だけで実現しています。
※久しぶりにpython触りました。

```python:sample.py
#-*- coding: utf-8 -*-
import time
import os
import sys
from stat import *

def usage():
	print "Usage: # python %s filename" % argv[0]
	quit()


def init(filename):
	file = open(filename,'r')

	#ファイル末尾へ移動
	st_results = os.stat(filename)
	st_size = st_results[ST_SIZE]
	file.seek(st_size)

	return file

def tail_f(file, usec):
	msec = usec / 1000
	while 1:
		fpos = file.tell()
		line = file.readline()
		if not line:
			time.sleep(msec)
			file.seek(fpos)
		else:
			print line,
	# 未到達
	file.close()
	pass

if __name__ == '__main__':
	argv  = sys.argv
	argc  = len(argv)
	if( argc != 2 ):
		usage()

	filename = argv[1]
	file = init(filename)
	tail_f(file, 500)
```
ちなみにlinuxでしか使わないのであれば、tail -fのラッパースクリプトにしちゃうという手もありですね。

```python:sample.py
import sys
import os

if __name__ == '__main__':
	argv = sys.argv
	argc = len(argv)

	if argc != 2:
		print "test",
		quit()
	
	filename = argv[1]
	os.system('tail -f ' + filename )
```
linuxでゴミ箱は??

基本的にlinuxはCUIなので、rmコマンドで削除すると思います。
GUIで操作している時にゴミ箱へ移動するがあったので、調べて見ました。
Fedora17では、下記のようにTrashというディレクトリがありました。

```
/home/hogehoge/.local/share/Trash/
```

※1.ゴミ箱を使ったことがないとTrashディレクトリはないようです。
※2.他のディストリビューションでは違う場所かもしれません。
PostBack時のDivのスクロール位置を復元します

        /// <summary>
        /// Divでスクロールするものについて、PostBack後の位置合わせを行います
        /// </summary>
        /// <param name="Div"></param>
        public static void SetDivScrollLastPosition(System.Web.UI.HtmlControls.HtmlGenericControl Div)
        {
            string hiddenId = "__SetDivScrollLastPosition_" + Div.ClientID;

            System.Web.UI.WebControls.HiddenField h = new System.Web.UI.WebControls.HiddenField();
            h.ID = hiddenId;
            h.Value = "0";//スクロール初期値0
            Div.Parent.Controls.Add(h);

          
            string scrOnScroll = string.Format("document.getElementById('{0}').value = this.scrollTop;", h.ClientID);
            Div.Attributes.Add("onscroll", scrOnScroll);
            
            if (Div.Page.IsPostBack) {
                string setScroll = string.Format("document.getElementById('{0}').scrollTop = document.getElementById('{1}').value;", Div.ClientID, h.ClientID);
                System.Web.UI.ScriptManager.RegisterStartupScript(Div.Page, Div.Page.GetType(), hiddenId, setScroll, true);
            }


        }
SmartyでPHP側で定義した関数を呼べなくするには 

http://qiita.com/items/48219e6b80bafbd50fa5
は情報が古かったようなので訂正。

Smarty3系では下記を参考にすると良さそうだ。
http://www.smarty.net/docs/ja/advanced.features.tpl#id3148392

抜粋すると、下記のクラスを使わないやり方が取り回しがしやすそうなので活用。

```php
require 'Smarty.class.php';
$smarty = new Smarty();
$my_security_policy = new Smarty_Security($smarty);
// すべての PHP 関数を無効にします
$my_security_policy->php_functions = null;
// PHP タグを除去します
$my_security_policy->php_handling = Smarty::PHP_REMOVE;
// すべての修飾子を使えるようにします
$my_security_policy->$modifiers = array();
// セキュリティを有効にします
$smarty->enableSecurity($my_security_policy);
```
プロトコルのメソッドにデフォルト実装を与える

`@required` だが定型的な処理を行うようなメソッドをプロトコルで定義すると、それを実装するクラスにコピペの嵐が発生しがちである：

```objc
// Assume FooProtocol has `@required -(void)fooMethod`.

@implementation FooableA // conforms to FooProtocol.

// Do something.
- (void)fooMethod {
    [NSApp.delegate doSomething];
}

@end

@implementation FooableB // also conforms to FooProtocol.

// Do the same thing as FooableA#fooMethod. What a copy/paste hell.
- (void)fooMethod {
    [NSApp.delegate doSomething];
}

@end

```

[libextobjc](https://github.com/jspahrsummers/libextobjc) ライブラリが提供する [EXTConcreteProtocol](https://github.com/jspahrsummers/libextobjc/blob/master/extobjc/EXTConcreteProtocol.h) を使うと、プロトコルのメソッドにデフォルトの実装を与えることができる：

```objc:FooProtocol.h
#import <libextobjc/EXTConcreteProtocol.h>

@protocol FooProtocol

@concrete
- (void)fooMethod;

@end
```

```objc:FooProtocol.m
#import "FooProtocol.h"

@concreteprotocol(FooProtocol)

// Default implementation for -(void)fooMethod.
- (void)fooMethod {
    [NSApp.delegate doSomething];
}

@end
```

```objc:FooableA.h
#import "FooProtocol.h"

@interface FooableA : NSObject <FooProtocol>
@end

// Now an instance of FooableA can respond to fooMethod.
```

定義のしかたは見てのとおりで、デフォルト実装を与えたいメソッドを `@concrete` でマークする。メソッドの実装は `@concreteprotocol(ProtocolName) ... @end` の中に書く。

このプロトコルに適合したクラスはデフォルト実装のメソッドを使えるようになる。クラス内でデフォルトと同名のメソッドを定義すると、そちらが優先される。

**注意：**デフォルト実装の中では `super` にアクセスしてはならない。
arc4randomの罠


## arc4randomとは？
srandで初期化を行わなくてもランダムの値をとれる
Objective-Cで使える便利メソッド

そんなarc4random使っててiphoneアプリを作ってる際に
嵌ったのでそのケースを紹介します。

### なぜかマイナスの値が発生する
特定範囲のランダムな値が欲しかったので
randみたいな使い方をしてたらなぜかマイナスの値が入ってました。

```objectivec:
// 期待する値は1〜10
// ただ時々マイナスになってしまう…
int random = ((int)arc4random()) % 10 + 1;
```

### なんでや
arc4randomの戻り値を見るとu_int32_tなので**unsigned int**

ん？unsigned int?

あ！

### 原因
**unsigned intの値をintに変換してるから**

arc4randomで2147483647以上の値が戻って来た際に
intにキャストしてるからマイナスが発生してたわけです。
まぁ、最初っから戻り値確認しとけよって話ですね。

どこかのブログとかで強制的にintに変換してるのを見かけることが
結構あるので、皆さん嵌らないように気をつけてください。
PHPとかいう糞言語について


http://ameblo.jp/nikko-inma/entry-11122429825.html

最初見た時、あいかわらず酷でーwww
とか思ったんだが

あれ?っと思って試したら予想通りだった

作者の意図するコードは↓こうなる

```php:a.php
<?php

$array = array(1,2,3);

$ref &= $array[1];

$copy = $array;
$copy[0] = 'a';
$copy[1] = 'b';
$copy[2] = 'c';

foreach( $array as $v ) {
  print "${v}\n";
}

?>
```

実行結果

```sh
% php a.php 
1
2
3
```

修正前
<code>$ref = &$array[1];</code>
修正後
<code>$ref &= $array[1];</code>

* 考察
PHPの&は参照を生成する構文だった!

* まとめ
そんなの知るかー!

* 追試

```sh
% php -r '$arr = array(1,2,3); $ref &= $arr[1]; var_dump($arr); var_dump($ref);' 
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}
int(0)
```
あれ?

```sh
% php -r '$arr = array(1,2,3); $ref &= $arr[1]; $ref = "b"; var_dump($arr); var_dump($ref);'
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}
string(1) "b"
```
あれあれ??

うん <code>&=</code>は意味ないかも…
Rでマルコフ連鎖の周辺分布を厳密推論

PRML 8.4.1に記載の通り、N個のノードを持ちそれぞれのノードがK個の状態を取るようなマルコフ連鎖について、各ノードxnの周辺分布p(xn)を推論します。

まず、素朴に式8.50の通り、xが取り得る状態全ての場合について同時分布を求めて、それらの合計により周辺分布を求めます。全ての場合について同時分布を求めるので、計算量はO(K^N)となります。

一方、式8.52の通りポテンシャルの和積計算を、連鎖の前方および後方からのメッセージパッシングとして解釈することにより、O(N*K^2)の計算量で同じ結果が得られることを確認します。

なお、与えるマルコフ連鎖は、以下の条件付き分布の積として定義されるベイジアンネットワークを、式8.45に従って等価なマルコフ確率場に変換したものです。

|x1|p(x1)|
|--:|--:|
|0|0.1|
|1|0.1|
|2|0.8|

|x(n-1)|xn|p(xn｜x(n-1))|
|--:|--:|--:|
|0	|0	|0.8|
|0	|1	|0.1|
|0	|2	|0.1|
|1	|0	|0.1|
|1	|1	|0.8|
|1	|2	|0.1|
|2	|0	|0.1|
|2	|1	|0.1|
|2	|2	|0.8|

またノードx4に値1を観測したときの周辺分布も求めます。

![](https://dl.dropbox.com/sh/cwfemibvr7gk4cy/CANWK6Khny/18.MarkovChainExactInference.png)

```r
frame()
set.seed(0)
par(mfcol=c(2, 2))
par(mar=c(2, 2, 1, 0))
par(mgp=c(1, 0, 0))
N <- 7
K <- 3
potential1 <- function(n, x1, x2) {
	# p(x1)
	if (n == 1) {
		p <- ifelse(x1 == 2, 0.8, 0.1)
	} else {
		p <- 1
	}
	# p(xn|xn-1)
	p <- p * ifelse(x1 == x2, 0.8, 0.1)
	p
}
potential2 <- function(n, x1, x2) {
	# p(x1)
	if (n == 1) {
		p <- ifelse(x1 == 2, 0.8, 0.1)
	} else {
		p <- 1
	}
	# p(xn|xn-1)
	p <- p * ifelse(x1 == x2, 0.8, 0.1)
	# x4に1を観測
	OBSERVED <- 1
	if (n == 4) {
		p <- p * ifelse(x1 == OBSERVED, 1, 0)
	} else if (n + 1 == 4) {
		p <- p * ifelse(x2 == OBSERVED, 1, 0)
	}
	p
}

doplot.joint <- function(potential) {
	# 同時分布を求める
	d <- data.frame()
	for (i in 0:(K^N - 1)) {  # O(K^N)
		total.potential <- 1
		xs <- c()
		xs <- c(xs, (i) %% K)
		for (n in 1:(N-1)) {
			xn1 <- (i %/% K ^ (n - 1)) %% K
			xn2 <- (i %/% K ^ n) %% K
			xs <- c(xs, xn2)
			psi <- potential(n, xn1, xn2)
			total.potential <- total.potential * psi
		}
		d <- rbind(d, c(xs, total.potential))
	}
	names(d) <- c(paste0("x", 1:N), "p")
	cat("p(x)\n");print(rbind(head(d),tail(d)))

	# 同時分布の和により周辺分布を求める
	ps <- matrix(nrow=N, ncol=K)
	rownames(ps) <- 1:N
	colnames(ps) <- 0:(K-1)
	z <- sum(d$p)
	for (n in 1:N) {
		for (xn in 0:(K-1)) {
			ps[n, xn + 1] <- sum(d[d[, n] == xn, ]$p) / z
		}
	}
	cat("p(xn)\n");print(ps)
	barplot(t(ps), legend=0:(K-1), xlab="xn", ylab="p(xn)")
	title("sum of joint")
}

doplot.message <- function(potential) {
	# 前方からのメッセージパッシング
	mualpha <- matrix(nrow=N, ncol=K)
	colnames(mualpha) <- 0:(K-1)
	mualpha[1, ] <- rep(1, K)
	for (n in 2:N) {  # O(N*K^2)
		mu <- c()
		for (x2 in 0:(K-1)) {  # O(K^2)
			mu <- c(mu, sum(potential(n - 1, 0:(K-1), x2) * mualpha[n - 1, ]))
		}
		mualpha[n, ] <- mu
	}
	cat("mualpha\n");print(mualpha)

	# 後方からのメッセージパッシング
	mubeta <- matrix(nrow=N, ncol=K)
	colnames(mubeta) <- 0:(K-1)
	mubeta[N, ] <- rep(1, K)
	for (n in (N-1):1) {  # O(N*K^2)
		mu <- c()
		for (x1 in 0:(K-1)) {  # O(K^2)
			mu <- c(mu, sum(potential(n, x1, 0:(K-1)) * mubeta[n + 1, ]))
		}
		mubeta[n, ] <- mu
	}
	cat("mubeta\n");print(mubeta)

	# メッセージに基づく周辺分布の計算
	ps <- matrix(nrow=N, ncol=K)
	rownames(ps) <- 1:N
	colnames(ps) <- 0:(K-1)
	for (n in 1:N) {
		p <- mualpha[n, ] * mubeta[n, ]
		z <- sum(p)
		ps[n, ] <- p / z
	}
	cat("p(xn)\n");print(ps)
	barplot(t(ps), legend=0:(K-1), xlab="xn", ylab="p(xn)")
	title("message passing")
}

doplot.joint(potential1)
doplot.message(potential1)
doplot.joint(potential2)
doplot.message(potential2)
```
Windows Azure Virtual Machineの設定


1. SSH接続
ダッシュボードのSSH DETAILSを見てポートを確認

```(Bash)
# ssh  {username}@XXX.cloudapp.net -p {port}
```

2. 日本向け設定

* 日本語環境インストール

```(Bash)
$ yum groupinstall 'Japanese Support'
```

* LANG変更

```(Bash)
$ vi /etc/sysconfig/i18n

LANG="ja_JP.UTF=8"
```

* タイムゾーン変更

```(Bash)
$ cp /usr/share/zoneinfo/Japan /etc/localtime
```
kitcometalsから値段を持ってくる

先に書いておくけど、私の本職はプログラマでもSEでもありません。
解法がスマートじゃないのはきっとそのせいです。そういうことにしておきます。
あと有用かどうかは知りません。誰かの役に立つと言いかもしれないけど。

http://www.kitcometals.com/
金属の変動を書いているサイトがあるのですが、上司から「このサイトに書いてある価格の推移を数値にして、定期的に送ってね」と言われたので、入社からコレまで手打ちで頑張ってきたのですが、いい加減自動化してサボろうと思いたったので頭を悩ませながら手法を模索。

ちなみに価格は銅だとすると
http://www.kitcometals.com/charts/copper_historical_large.html#30days
のグラフ内にその日の終値の数値があるものの、テキストベースで落ちている場所はなく。

結果的にトップページの左側においてある数字を引っ張って、変動価格差を反映させれば値が取れるということで、
１：ページそのものを引っ張ってくる
２：中身をスクレイピングして欲しい数字を算出する
３：日付を添えてデータベースにぶち込む
という方法を使えばいいんじゃないかなという結論になりまして。
この記事では２までのメモ。

前置きが長くなったけど、とりあえずやってみようとソースコードを見て驚愕。
対策なのか単にレガシーすぎるだけなのか。tableを死ぬほど入れ子にしてサイトができているのでした。
せめて場所ごとにCSS使えよ！

愚痴っても始まらないので、とりあえずウェブを持ってくる。
色々調べた結果、phpQueryを使うことにする。記述時点では0.9.5。
http://code.google.com/p/phpquery/

```hoge.php
<?php
require_once('phpQuery/phpQuery.php');
$html = phpQuery::newDocumentFile('http://www.kitcometals.com/');
mb_language('Japanese');
$i=0;
$lists = $html['table'];
foreach ($lists as $list) {
echo "でぃすてーぶるいず　eq".$i;
echo pq($list)->htmlOuter();
echo "<br />";
$i++;
}
```

動かすと実に79個のテーブルが発生しやがりました。同じ文字が数回並んだりして見てられない……
銅のテーブルはどうやらeq15みたいなので、決め打ちで取ってくることに。
入れ子にできるみたいなので更にtr要素で回し、現在の価格を取得することに成功。

```hage.php
<?php

require_once('phpQuery/phpQuery.php');
$html = phpQuery::newDocumentFile('http://www.kitcometals.com/');
mb_language('Japanese');
$lists = $html['table:eq(15)']; //テーブル決め打ち
$hoge = $lists['tr:first td:eq(1)'];
$coppercurrent = pq($hoge)->text();
$hoge = $lists['tr:eq(1) td:eq(1)'];
$change = pq($hoge)->text();
//echo $coppercurrent -$change;
```

phpは型自動認識なのがこういう時には無駄に役立つようなどうでもいいような。
と言うか後々のエラーの温床になる気がするので、クローズ時間に現在値だけ持ってくるのが正解かな。
ともあれ、なんとか目的は果たしましたとさ。

……こんなメモでも残していいのかしら。テスト投稿も兼ねて。
jQueryで、Enterキーのサブミット禁止

2018.01.15穴があったので修正

Enterを利かせたいもの以外を止める考えに変更しました。

```
   $("body").on("keydown", function (e) {
        if (e.keyCode !== 13) { return true;}
        if ($(document.activeElement).prop("tagName") == "TEXTAREA"
            && !$(document.activeElement).is(':disabled')
            && !$(document.activeElement).attr('readonly')
            )
        {
            return true;
        }
        if ($(document.activeElement).is('input[type="button"],input[type="submit"],a')) {
            return true;
        }
        return false;
    });
```

この考え方の場合、本文のテキストにフォーカスがある場合にエンターでSubmitするため。
↓
TextBox等でEnterを入力するとSubmitするのを防止。

```
    <script type="text/javascript" >
        //エンターでのsubmitを禁止
        $(document).ready(function () {
            $('input,textarea[readonly]').not($('input[type="button"],input[type="submit"]')).keypress(function (e) {
                if (!e) var e = window.event;
                if (e.keyCode == 13)
                    return false;
            });
        });
    </script>
```
最短マッチ

[対象テキスト]
CMP1.NTTON as customer,CMP2.NTTON as partnerCode,LOC1.NTTON as ex_Place,

[正規表現での検索]

```
as.*,
```

[検索結果]
__CMP1.NTTON as customer,CMP2.NTTON as partnerCode,LOC1.NTTON as ex_Place,__

[正規表現での検索]

```
as.*?,
```

[検索結果]
__CMP1.NTTON as customer,__
Rails+unicornのアプリ｜環境毎に接続DBを分ける方法


複数で開発をしているプロジェクトではローカルで使用しているDBの設定が違う事が多い。  
Railsではdatabase.ymlに各環境毎の設定を記述する事が出来るのでステージング／本番サーバの記述する事は出来るがローカル環境（development）が人によって違う場合はgit等で管理している場合、pushしてしまうと競合してしまう。
これを解決するには、いろいろ方法があるが、今回は下記の様に行った。  

###１．database.ymlをテンプレート化
database.ymlをリポジトリ管理外にし、リネームしてし、.gitiginoreにdatabase.ymlを追加。
リモート



```
git mv config/database.yml config/database.yml.example
git -m commit -m "moved database.yml to an example file"

vi .gitiginore
config/database.yml
```

###２．rakeコマンドをローカルで実行した時に、database.ymlが存在しない場合にアラートしてくれるプラグインを入れる。

```
script/plugin install git://github.com/technicalpickles/wheres-your-database-yml-dude
```

###３．Capistrano deploy taskを編集

update_codeおよびsymlink_dbのタスク終了後に、database.ymlのシンボリックリンクをリリースフォルダに張るタスクを書きます。

```RAILS_ROOT/config/deploy.rb

after 'deploy:update_code', 'deploy:symlink_db'

namespace :deploy do
  desc "Symlinks the database.yml"
  task :symlink_db, :role => :app do
    run "ln -nfs #{deploy_to}/shared/config/database.yml #{release_path}/config/database.yml"
  end
end
```

###４．各環境用のdatabase.ymlを各サーバにscpやviなどで用意

```
cp config/database.yml my_server.com:/path_to_rails_app/shared/config/database.yml
```
markdownで書かれたgistを奇麗に表示。

CoffeeScript > 1.6。literateモードネタです。

##literateモードとは?

>If you name your file with a  .litcoffee extension, you can write it as a Markdown document. - coffeescript.org

つまりmarkdown文中のコードブロックをそのまま実行、またはコンパイルしてくれる事です。従来のコメント部分を返って重視し、コードを文書の様に書く事で、読みやすさの上昇を狙っています。[サンプル](https://gist.github.com/jashkenas/3fc3c1a8b1009c00d9df)。

Jeremy本人の[ブログエンジン](http://ashkenas.com/literate-coffeescript/)もliterateモードで書かれています。

##Gistでブログ
Gistに投稿したgistをそのままブログの文書にする。D3.jsでおなじみのMike Bostockが使っている方法です。D3.jsの[オフィシャルサンプル](https://github.com/mbostock/d3/wiki/Gallery)やMike本人の[ブログ](http://bost.ocks.org/mike/)がそうです。

##Gistでは足りない？
Gistはコードをブログなどに埋め込むとmarkdownは表示されますが、コードブロックはまず実行されません、Qiitaに投稿しても同様。況しては一度literateモードで書いたコードをブログ用の文書と、別に動くサンプルを準備するなど、**めんどくさい**。

##結局なにが欲しいのか

* literateモードでコードと文書をいっぺんに書く。
* Qiitaとgistに、**ポィ**！
* で、そのまま動く、奇麗なブログの出来上がり。
* URLでシェアー可能、サーチエンジンにも見つかる。

欲張りでごめんなさい m(_ _)m。

##プロトタイプ作りました
とりあえずHerokuに、**ポィ**！
http://liten.herokuapp.com

例えばgistにコードを投稿しました

```coffee-script
console.log 'Hey! you are writing in style'
console.log $('body')
```
https://gist.github.com/hden/5098183

gist番号を
http://liten.herokuapp.com/5098183

そのままシンタックスハイライト付きで読めます、実行します。
コンソールを開ければ

    Hey! you are writing in style
    [<body style="display: ;">…</body>]

以下のライブラリが内蔵されてますので、そのまま使えます。

* CoffeeScript 1.6.1
* jQuery
* Underscore
* Backbone
* D3.js
* Bootstrap / Bootswatch / strapdownjs

jQuery入ってますのでDOM弄り放題です。

## リリースログ
v0.0.02

* Coffee-script 1.6.2投入により[source map](http://tech.nitoyon.com/ja/blog/2013/01/29/jquery-source-map/)に対応しました。
* [Require.js](http://requirejs.org)。

##フィードバックよろしくお願いします
* [@_hden](https://twitter.com/_hden)
TwitterAPI search/tweetsでURL検索時のドキュメントに掲載されていない仕様


TwitterAPI1.1の[search/tweets](https://dev.twitter.com/docs/api/1.1/get/search/tweets)(以下、検索API)でURLを検索する場合の仕様です。

## 前提知識

URLを含む文字列をツイートした場合は、全てのURLは `http://t.co/*` に変換されます。
そしてそのツイートはentitiesに

| Key | 意味 |例|
|:-----------|------------:|-------------:|
| url       |Twitterの短縮URL|`http://t.co/*`|
| dispaly_url |元のURLの短い表記|`amzn.to/*`|
| expanded_url|元のURL|`http://www.amazon.co.jp/*`|
	
という情報を持ちます。

## URLを検索
下記を例に検索してみます。

| Key | 意味 |例|
|:-----------|------------:|-------------:|
| url       |Twitterの短縮URL|`http://t.co/VWXYZ`|
| dispaly_url |元のURLの短い表記|`amzn.to/abced`|
| expanded_url|元のURL|`http://www.amazon.co.jp/abcde`|

|検索クエリ|一致|
|:-----------|:------------:|
|t.co|×|
|amzn.to|×|
|amazon.co.jp|◯|
|jp/abcde|◯|

expanded_url(t.coのリダイレクト先のURL)が検索対象となっています。

***

次に、投稿の段階で既に他サービス(bit.ly)で短縮してあるURLです。

| Key | 意味 |例 (bit.lyのURL)|
|:-----------|------------:|-------------:|
| url       |Twitterの短縮URL|`http://t.co/VWXYZ`|
| dispaly_url |元のURLの短い表記|`bit.ly/abcde`|
| expanded_url|元のURL|`http://bit.ly/abcde`|
| -|bit.lyのリダイレクト先のURL|`http://google.com/`|

|検索クエリ|一致|
|:-----------|:------------:|
|t.co|×|
|bit.ly|×|
|http://bit|×|
|bit.ly/abcde|×|
|google.com|◯|
|http://goo|◯|

expanded_urlでなくbit.lyのリダイレクト先のURLが検索対象となっています。

## まとめ
* TwitterAPI1.1の[search/tweets](https://dev.twitter.com/docs/api/1.1/get/search/tweets)では短縮URLは検索対象でなく、リダイレクト先のURLが検索対象になっている。
* 投稿時のURLがbit.lyなどの短縮URLであってもbit.lyのリダイレクト先のURLが検索対象になっている。

***※ `t.co`は、除外されているかなと予想はしていましたが、`bit.ly`まで展開されているのには驚きました。***

* 特定のブログ記事の反応など、このURLはTwitterでどれくらいつぶやかれているのだろうと検索するときは、単純にオリジナルの長いURLで検索すれば全ての一致を取得出来るとういことですね。

## 注釈
1. TwitterAPI1.0では検証してませんが、ここの仕様は同じかなと予想。
2. 更に(3つ以上)短縮URLを介しているものは試してません…
3. [Webでの検索](https://twitter.com/search)は仕様が少し違いました。リダイレクト先のURLが検索対象で一致するのは同じなのですが、`t.co`で検索したら一致するツイートが返ってきたりします。
4. ドキュメントに載ってませんよね？見つけたら教えて欲しいです。
パスワードありsudoでrsyncするシェルスクリプト

## 前提

リモートホストのsudoersで
* !requiretty指定不可
* NOPASSWD指定不可
という条件下で、rsyncの--rsync-pathオプションを使ってリモート側をsudoで実行したいという話です。

## 実現案

試行錯誤の末、以下のスクリプトで一応実現できました。
ただし、一瞬ですがパスワードを含んだファイルがリモートホストに存在しますので、
その瞬間にroot権を持つ別のユーザがそのファイルを読むとパスワードが漏れてしまうという問題があります。

```sh:rsync_sudo_with_password.sh
#!/bin/sh

host=${Your_Remote_Host_here}
src=${Your_Source_Directory_Here}
dest=${Your_Destination_Directory_Here}

read_password() {
  prompt=${1:-Password:}
  stty -echo
  read -p "$prompt" password
  stty echo
  echo "$password"
}

password=`read_password "[sudo] password for $host:"`

ssh ${host} "umask 0077 && cat <<EOF > .password.sh && chmod +x .password.sh
#!/bin/sh
echo $password
EOF"
rsync -avz --rsync-path="SUDO_ASKPASS=.password.sh sudo -A rsync" ${src} ${host}:${dest} &
ssh ${host} rm .password.sh
wait
```

## 試行錯誤の経緯

上記のスクリプトに至るまでの試行錯誤の経緯を説明します。
rsyncではなくsshでsudoする場合は、リモートホストに.password.shを作成する必要はなくて、以下のコマンドで可能です。

```
ssh ${host} "cat <<EOF | sudo -S -p '' whoami
$password
EOF"
```

しかし、rsyncの--rsync-pathオプションで同じことをしてもうまく動きません。

```
# No, this does not work!
rsync -avz --rsync-path="cat <<EOF | sudo -S -p '' rsync
$password
EOF
" ${src} ${host}:${dest}
```

苦肉の策として、冒頭のスクリプトでは以下の手順を用いています。

* パスワードを標準出力に出力するスクリプト.password.shをリモートに作成。
    * 他のユーザから見られないようにumask 0077を設定してから作成します。
    * echoではなくcatを使っているので、誰かがpsを実行してもパスワードを見られることはありません。
* rsyncの--rsync-pathでは、SUDO_ASKPASS環境変数を指定してsudo -Aを実行する
* rsyncはバックグラウンドで実行して、開始直後にsshで接続して.password.shを削除する。
* waitでrsyncの実行完了を待つ。


## 改良版

.password.shという固定のファイル名だと狙われやすいので、
[pwgen](http://pwgen.sourceforge.net/)を使ってランダムな名前のディレクトリを生成してその中に.password.shを作成するという方式にしてみたのが以下のバージョンです。

```sh:rsync_sudo_with_password.sh
#!/bin/sh

host=${Your_Remote_Host_here}
src=${Your_Source_Directory_Here}
dest=${Your_Destination_Directory_Here}

read_password() {
  prompt=${1:-Password:}
  stty -echo
  read -p "$prompt" password
  stty echo
  echo "$password"
}

password=`read_password "[sudo] password for $host:"`
random_dir=`pwgen -s 32 1`

ssh ${host} "umask 0077 && mkdir $random_dir && cat <<EOF > $random_dir/.password.sh && chmod +x $random_dir/.password.sh
#!/bin/sh
echo $password
EOF"
rsync -avz --rsync-path="SUDO_ASKPASS=$random_dir/.password.sh sudo -A rsync" ${src} ${host}:${dest} &
ssh ${host} rm -rf $random_dir
wait
```


OSXではpwgenはHomebrewでインストール可能です。

```
brew install pwgen
```

## ご意見募集

果たしてこの方式は、十分安全と言えるのかご意見をお聞きしたいところです。さらなる改良案や全く別の解決策もお待ちします。
sotryboardのシーン切り替わりでメモリを増やさない

スッゲー悩んでいたのですが、
まず
print('#DisplayObject:'..display.getCurrentStage().numChildren)
コレでDisplayObjectの数をシーンごとにチェック。

メモリが増大していく場合は、大抵コレが原因。
どのgroupにもインサートされずに
ステージ上？に配置されちゃったdisplayObjectが絶対どこかにいるので
そいつを見つけてinsertしてやるかremoveしてやるかすれば、
メモリはまず増えない。
もうソレだけやればいいみたい。

どうしようかと思ったけど、こんな簡単な事でメモリリークを防げるんだから、
coronaってやっぱり簡単でいいですね。
PHPで列挙型(enum)を作る

[列挙型 - Wikipedia](http://ja.wikipedia.org/wiki/%E5%88%97%E6%8C%99%E5%9E%8B)

まず列挙型の定義は〜となるんだけど、ここでは「あらかじめ定義した値のいずれかしか取らない特殊な型」という感じを想定してます。
要は[SplEnum](http://jp2.php.net/manual/ja/class.splenum.php)みたいなのですが、拡張モジュールの力を借りなくても、PHPだけで作れます。リフレクションを使うだけ。

```php
<?php
abstract class Enum
{
    private $scalar;

    public function __construct($value)
    {
        $ref = new ReflectionObject($this);
        $consts = $ref->getConstants();
        if (! in_array($value, $consts, true)) {
            throw new InvalidArgumentException;
        }

        $this->scalar = $value;
    }

    final public static function __callStatic($label, $args)
    {
        $class = get_called_class();
        $const = constant("$class::$label");
        return new $class($const);
    }

    //元の値を取り出すメソッド。
    //メソッド名は好みのものに変更どうぞ
    final public function valueOf()
    {
        return $this->scalar;
    }

    final public function __toString()
    {
        return (string)$this->scalar;
    }
}
```

```php:使い方
<?php
// トランプのスート型を定義する。4種類しか値を取らない。
// Enumをextendして、定数をセット
final class Suit extends Enum
{
    const SPADE = 'spade';
    const HEART = 'heart';
    const CLUB = 'club';
    const DIAMOND = 'diamond';
}

//インスタンス化
$suit = new Suit(Suit::SPADE);
echo $suit; //toString実装済みなので文字列キャスト可能

echo $suit->valueOf(); //生の値を取り出す。intやfloat等の場合に。

// 適当な値を突っ込もうとすると、InvalidArgumentExceptionが発生して停止
//$suit = new Suit('uso800');



//__callStaticを定義してあるのでnewを使わずこんな感じでも書ける(PHP5.3以降)
$suit = Suit::SPADE();
```

PHPには組み込みのEnum型はないので、無理にEnumを作った所で速度的な旨味はありません。ただ、型チェックだけで「この定義済みの値のいずれかである」ことが保証できます。

ユーザーの入力なんかを予め検証して、適当な型にキャストしておけば、以降は型チェックだけで安心してデータを扱えるようになります。べんり。


```php
<?php

function doSomething(Suit $suit) {
    //Suitというタイプヒントによって、
    //$suitは必ず4種類のうちのどれかだと保証されている

}
```

元の値を取り出すメソッド名に困ったので、JavaScript風にvalueOf()にしてますが、まあ別に何でもOKです。
起動したWebDriverにただページ遷移をさせたい

Selenium WebDriverで、リンクやボタンのクリックとかなしに
ただページ遷移する方法がわからなくてずっとハマってたんですが、
今日やっとNavigationなるクラスを発見したのでここにメモしておきます。
Javaです。

// IEdriver起動
WebDriver driver = new InternetExplorerDriver();

// ブラウザを起動してGoogleのトップページを開く 
driver.get("http://ww.google.com"); 

// Yahoo!のトップページへ遷移
driver.navigate().to("http://www.yahoo.co.jp/"); 

日本語ブログとかだとあんまり見かけないような気がする。
stackoverflowで見たところによるとnavigate().to()とget()は
同じようなものだ とのこと。
でもnavigate().to()のほうが純粋に「遷移」って感じな気がする。
メソッド名がそう思わせるだけでしょうか…？

あと、Navigationクラスには「進む」「戻る」「更新」もある。

driver.navigate().forward(); // 進む
driver.navigate().back(); // 戻る
driver.navigate().refresh(); // 更新
複数のCookieを頻繁に切り替える必要があるテスト


ってめんどくさいですよね。
でもwebアプリだとそういうシチュエーション（複数人の役割を一人でテストしたいとき）はわりとありますよね。

## 概要
Chrome の 複数ユーザー管理機能を使うと便利だということを今日発見したのでメモっておきます。
See: [Chrome で複数のユーザーを管理する - Chrome ヘルプ](https://support.google.com/chrome/bin/answer.py?hl=ja&answer=2364824)

## やりかた
* Chrome -> 設定 -> 新しいユーザーを追加
![chrome-setting](http://f.cl.ly/items/3z41471W0Q3y3b1T0O2z/chrome-setting.png)

* アイコンと名前を適当に入れてユーザーを作成
![create-user](http://f.cl.ly/items/2T2t0H1D0u2L2j212T1V/chrome-create-user.png)

* 好きなだけユーザーを作る
![user-list](http://f.cl.ly/items/3V013b2E1X1C2e003A1X/chrome-user-list.png)

* するとこんな感じで別ウインドウで別Cookieで操作できます。しかも見た目がわかりやすいですね
![window-icon](http://f.cl.ly/items/0G1S000T3o1G3W2F0z0K/chrome-window-icon.png)

## 所感
当たり前の機能なのかもしれないですけど、僕的に結構発見でした。
昔は Firefox の CookiePie っていうタブごとに Cookie を切り替えられるやつを使ってたのですが、
いつの間にか使えなくなってしまい困っていました。
Chrome の シークレットウインドウ でも同じ事ができるのですが、
シークレットウインドウ間では Cookie を共有するようで、
通常のウインドウ と シークレットウインドウ の2個しか使い分けられないため、
3個以上使い分けたい場合は便利かなと思います。
GoogleMapナビの起動Intent

GoogleMapナビをIntentで起動する方法メモ。
忘れないように備忘録。

```java:
Intent i = new Intent();
i.setAction(Intent.ACTION_VIEW);
i.setClassName("com.google.android.apps.maps", "com.google.android.maps.driveabout.app.NavigationActivity");

Uri uri = Uri.parse("google.navigation:///?ll=lat,lon&q=表示名");
i.setData(uri);
startActivity(i);
```

ll=lat,lon には目的地の緯度・経度が入ります。

```java:例
ll=36.000000,137.000000
```

q=表示名 にはナビで表示する目的地名が入ります。
title=表示名としても同様ですが、目的地ではなく、"指定の地点"と表示されます。

徒歩の経路を検索する場合には、
mode=w
をつけると徒歩モードで検索します。

```java:徒歩モード
Uri uri = Uri.parse("google.navigation:///?ll=lat,lon&title=表示名&mode=w");
```

logcatをみると、
entry=d
opt=4:0,5:0
というパラメータも渡しているようですが、何に使用しているのか不明でした。。。