OmniAICreator/Qiita-1.07M huggingface dataset:
GASのUI① UiAppの基礎

Google Apps Script Advent Calendar 2012の11日目です。
今日から3日間誰も入ってないので、このまま入らないようならGASのUIの話をしていきたいと思います。
というか3日間で書ききれないので多分もっと書きます。

今日は最も古くからあるUiAppの話からしていきたいと思います。

# UiAppの表示の仕方

GASではUIを持ったアプリケーションを開発できます。
作ったアプリケーションは

* Spreadsheet上に表示する
* Google Sitesに埋め込む
* 独立したWebアプリケーションとして表示する

という3つの場所で利用できます。
2つ目と3つ目のやり方はほぼ一緒なのですが、1つ目だけ少しやり方が違うので注意が必要です。
それでは簡単にやり方を説明していきます。

# Spreadsheet上に表示する

Spreadsheet上に表示する場合は`Spreadsheet#show(UiInstance)`というメソッドを利用します。
UiInstanceはUiAppというサービスから作成します。
以下に簡単な例を書きます。 なおこのスクリプトはSpreadsheet上からGAS Editorを開いて作成してください。

```javascript:Spreadsheet上に表示する.gs
function showUi(){
  
  var uiapp = UiApp.createApplication().setTitle("Hello World");
  
  var label = uiapp.createLabel("Hello World");
  uiapp.add(label);
  
  SpreadsheetApp.getActive().show(uiapp);  
}
```

あとはこのメソッドを起動するとSpreadsheet上にUIが表示されます。

# Google Sitesに埋め込む & 独立したWebアプリケーションとして表示する

Sitesに埋め込んだり、Webアプリケーションとして表示する場合はどちらもほぼやり方は一緒です。
大まかに書くと

1. UiInstanceを返却するdoGetメソッドを作成
2. バージョンを作成
3. アプリケーションとして公開
4. Sitesの場合はSitesに埋め込み

です。

## UiInstanceを返却するdoGetメソッドを作成

まず、`doGet(e)`というメソッドを利用して`UiInstance`を返却するメソッドを作成します。


```javascript:doGet.gs
function doGet(e) {
  
  var uiapp = UiApp.createApplication().setTitle("Hello World");
  
  var label = uiapp.createLabel("Hello World");
  uiapp.add(label);
  
  return uiapp;
}
```

上のSpreadsheet上に表示する場合のメソッドから名前と返却値を変えただけですね。

## バージョンを作成

次はバージョンを作成します。以前ライブラリの回で説明したように適当にバージョンを作成してください。

## アプリケーションとして公開

次はアプリケーションを公開します。

1. メニューから「公開」→「Webアプリケーションとして導入」を選択
2. `プロジェクトバージョン`は「バージョンを作成」で作成したバージョンを選択します。
3. `アプリケーションとして公開`は各種サービス(GmailAppとか)を誰として実行するかを選択します。GmailApp等を利用していて、自分にしてしまうと自分のメールの中身が見られてしますので注意してください。
4. `アプリケーションにアクセスできるユーザー:`は誰がアプリケーションにアクセスできるかを選択できます。
5. 上記を設定したら「導入」ボタンをクリックします。
6. `現在のウェブ アプリケーションの URL:`にアプリケーションのURLが表示されているのでそこにアクセスしてみてくださいアプリケーションが見れます。
7. Sitesに埋め込む場合は埋め込みたいSitesのページに行き編集モードにして、左上にある挿入メニューから「Appsスクリプトガジェット」を選択して下さい。

なお通常バージョンを作成したように、doGetで表示するUIやコードは「バージョン固定した時のUIやコード」になります。
つまりプログラムを変更し6.のURLで画面を表示してもバージョンを固定した時点のプログラムが表示されます。

ただそれでは開発がしづらいので6.のところで「最新のコード」というリンクがあるのでそれをクリックしてUIを表示すると、
最新のコードでUIを表示できます。
なおこのURLは「公開」→「Webアプリケーションとして導入」を再度表示しても取得できます。

# 小話

## UiAppとGWT

UiAppで各Ui部品を利用する場合createXxxというメソッドを利用します。
公式ドキュメントにも書いてありますが、UiAppは裏側でGWTというJavaをJavascriptに変換するライブラリを利用しています。
 ※関係無いですが著者は[GWT-Bootstrap](http://gwtbootstrap.github.com/)というライブラリを作ったりしています。

公式ドキュメントにはどのUI部品がどのような見た目かが書いてないのでわかりにくいですが、
GWT側のドキュメントや[サンプル](http://gwt.googleusercontent.com/samples/Showcase/Showcase.html)には書いてあるので見てみてください。

がGWTをやると軽く死ねるのでおすすめしません( ｰ`дｰ´)ｷﾘｯ
こういう見た目になるんだなぁーぐらいで見ておくと幸せです。

# まとめ

今日は初歩の初歩を書きました。
次回はもう少し踏み込んでよく使ってるUiAppの自作フレームワークを書きたいと思います。
Heroku PostgreSQL "Database Availability Issue" から復帰するついでに PostgreSQL 9.2 に更新

~~~
$ heroku addons:add heroku-postgresql:dev --version=9.2
Adding heroku-postgresql:dev on ${app_name}... done, v119 (free)
Attached as HEROKU_POSTGRESQL_IVORY_URL
$ heroku pgbackups:restore HEROKU_POSTGRESQL_IVORY_URL
$ heroku pg:promote HEROKU_POSTGRESQL_IVORY_URL
~~~

本来の qiita の使い方とは違う気がしますが、「えーと、これ前にもやった気がするんだけどどうやるんだっけ」的なメモはここで探す感じなので qiita に書いてます。すみません。
UIDocumentを使ってみた

何もネタがなかったのでUIDocumentを使ってみる事にしました。

UIDocumentというのはiOS5から使える様になったクラスでMacでいうところのNSDocumentに対応するようです。注目すべきはiCloudと簡単に連携できることですなのでが、今回は単にまず最低限の動く実装を試してみました。

UIDocumentのサブクラスで次の二つのメソッドの実装をすれば良いです。

```objective-c:SimpleObject.m
//ロード
- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError *__autoreleasing *)outError
{
    NSLog(@"typeName:%@",typeName);
    NSData *data = (NSData *)contents;
    if (data.length == 0) {
        NSLog(@"nothing");
        self.text = @"";
        return YES;
    }
    self.text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    if (!self.text) {
        NSLog(@"[Error]loadFromContents initWithData:%@",data);
        return NO;
    }
    return YES;
}
//セーブ
- (id)contentsForType:(NSString *)typeName error:(NSError **)outError
{
    return [(self.text)?:@"" dataUsingEncoding:NSUTF8StringEncoding];
}
```

サンプルをGitHubに置きました。もう少し機能を増やしたサンプルにしたいです。。

https://github.com/KatagiriSo/SimpleDocument
”GAS、すごいんじゃない！？”と思う７つのポイント

わたくしごとですが、GASを知ったのは、2012年10月11日でした。弊社では、そこから、かなりフォーカスして取り組んでいます。
「すごいんじゃない！？」（ビジネス的かも）と思っている７つのポイントをまとめます。
※弊社は、比較的利用ユーザーが少ない企業・組織をターゲットにしていますので、大企業での利用という観点からは、フィットしない項目があるかもしれませんが、ご容赦ください。

##1.スプレッドーシートをあたかもDBとして使うことで、入力の効率が高まる。
通常の業務システムは、１レコード（ロー）の入力を１画面で行います。１レコードに納めるデータを１画面で入力していただき、実行ボタンを押してもらうということになります。
一度に入力するレコード数が少なければ問題ないのですが、10レコードを超えてくると、かなりうざいです。
SFAやCRMのクラウドサービスを提案していた際、お客様に「EXCELで入力したい！」と言われたものです。
スプレッドシートは、どんどんレコードを入力でき、都度都度保存してくれます。また、GASの編集時トリガーと組み合わせることで、イライラの少ない業務システムが作れます。

##2.スプレッドーシートをあたかもDBとして使うことで、一般的な管理画面の開発が不要になる。
通常の業務システムでは、管理者がDBにアクセスするために、管理画面を作ることが一般的かと思います。
スプレッドシートを使う方法では、直接スプレッドシートでデータをメンテナンスできますので、管理画面の開発が不要になります。

##3.スプレッドーシートをあたかもDBとして使うことで、利用ユーザーの学習コストが低くなる。
EXCELをはじめとする表計算ソフトを使った経験のある方は、スプレッドシートの習得は容易です。
通常の業務システムではその業務システムのユーザーインターフェイスや振る舞いを学習することが必要ですが、スプレッドーシートを使う場合、学習コスト（学習に要する時間）は少なくなります。

##4.GASは可能性が広がっているJavascriptベースの言語
EXCELはVBA, Force.comはApex(Javaベース)という独自言語。それに対しGASは、扱える人が多いJavascript！
このことにより、潜在的にGASを扱える人は多く、開発を発注する際も、比較的容易にリーズナブルな金額で、開発してくれる企業や個人を見つけることができるようになるでしょう。
また、プログラミング初心者向けに「EXCEL VBAでプログラミングを学ぼう！」というコンセプトの本・ブログがありますが、個人的には、「Google Apps + GAS」だと思います。Javascriptは、今後ますます必須の言語になるはずなので。

##5.Google Appsとの組み合わせがすごすぎる。
機能的にももちろんなのですが、Google Apps 1ユーザー月額600円というのがすごすぎます。
SalesforceやForce.comは、利用ユーザーの権限設定やセキュリティ管理など、とてもきめ細やかに設定できるので、十分価格に見合う価値はあると思うのですが、GASを知ってから、利用ユーザーの少ない場合、自信をもっておすすめできなくなっちゃいました。はい。
http://www.salesforce.com/jp/platform/pricing-editions.jsp?d=70130000000sqmY&internal=true

##6.デプロイが異様に楽。
Herokuもかなりデプロイが楽！と思っていましたが、GASのデプロイは異様に楽です。デプロイしていると感じないくらい。これは、大橋さんのこちらを参照ください。
http://qiita.com/items/cb12c14a937f67632c68

##7.トリガー（スケジューラー）が充実している。
スクリプトをトリガーを使って起動することで、高度な自動化を実現できます。
GASのトリガーは、設定オプションが多く、しかも追加料金とかなし！


##いかがでしたか？
ほかにも、GASすげー！というポイントがあると思います。
ぜひ、あなたのGASすげー！ポイントを教えていただけるとうれしいです！

それと、GoogleスプレッドシートとGASで作っている、武蔵小山の便利マップです。
これを作ることで、Googleスプレッドシート＋GASのすえおそろしさを実感しました！
http://mg03.jp/hospitalmap/
病院のデータをDBではなく、スプレッドシートに格納しています。

##告知させてください。
Tokyo GAS 〜東京でのGoogle Apps Script勉強会・交流会〜を2012年1月18日(金)に開催します！
詳しくは、こちらをご覧いただき、お気軽にご参加ください！
http://atnd.org/event/TokyoGAS
Debug.Logを無効化

UnityのDebug.Logは、製品化したときもログを吐いてしまいます。
AndroidなどでLogcatすると割と誰でもログを見れてしまうので、できれば製品版では無効化しておきたいところ。
また、Debug.Logは実はかなり負荷が高いです。一度に何十というログを出したりなどしていると、実機になった途端に謎の処理落ち頻発とかになります。「Unityじゃなんともなかったのに！なんでガクガクなの？」とかなったら疑ってみると良いかと思います。

さて、実際にログを消そうとしても、一つ一つコメントアウトしたり必要になるたびに戻す…というのは大変です。自分も困って悩んでたんですが、良いやり方を聞いたので、紹介します。

2016/7/28更新
紹介していたやり方が古かったので、新しいやり方をまとめました。

2020/6/28更新
無効化されるわけではない点が間違っていたので修正しました。

## PlayerSettingsで設定する（Unity5.4から）　##
Unity5.4から、PlayerSettingsの下部にLoggingという項目が加わりました。
![ss_392.png](https://qiita-image-store.s3.amazonaws.com/0/12158/8fff28ec-fab3-a7e5-f017-583b322843d9.png)
全部止めたい場合は、これでNoneにすればよさげです。
ただし、これはスタックトレースを止めるだけで、ログメッセージ自体は出力されてしまうようです。

## PlayerSettingsで設定する（Unity5.3以前）　##
5.3以前でも、PCビルドでのみですが、ログを出力を無効化する設定があったようです。
![ss_391.png](https://qiita-image-store.s3.amazonaws.com/0/12158/e2c610a6-3f77-f494-6213-304f4bfc68e4.png)
なぜかPC限定で微妙に使いづらいですね。MacAppの場合ログが出ていると審査が通らないのでその対策という話も。

### スクリプトから設定する（Unity5.3から）　###

スクリプトからこう書くことでログを止められるようになっているようです。
```
Debug.unityLogger.logEnabled = false;
```
普段はオフにしていても、デバッグボタンからオンにするとか使い分けができそうですね。

公式ドキュメントはこちら
http://docs.unity3d.com/ScriptReference/Logger.html

起動時に無効化するなら、こちらもの方法も参考になるかと
https://gist.github.com/tsubaki/049e68297723572b6f19709bfd2d3d6a


## 昔のやり方 ##
~~この先は以前のやり方です。Unityのバージョンが古い場合には有効かも~~

~~やり方としては、自分で同名の「Debug」クラスを定義する。~~

~~UnityのDebugクラスは、UnityEngineというnamespaceにあるので、UnityEngine.Debugとして定義されている。なので、ネームスペースを使わずに同名クラスを定義した場合は、そちらが優先される･･･というC#の仕様を利用する。
クラスの中身はこんな感じ。~~

***

```
#if !UNITY_EDITOR
#define DEBUG_LOG_OVERWRAP
#endif

using UnityEngine;

#if DEBUG_LOG_OVERWRAP
public static class Debug
{
	static public void Break(){
		if( IsEnable() )	UnityEngine.Debug.Break();
	}

	static public void Log( object message ){
		if( IsEnable() ){
			UnityEngine.Debug.Log( message );
		}
	}
	static public void Log( object message, Object context ){
		if( IsEnable() ) {
			UnityEngine.Debug.Log( message, context );
		}
	}
	
	static bool IsEnable(){ return UnityEngine.Debug.isDebugBuild; }
}
#endif
```

~~Unityエディター上ではデフォルトのUnityEngine.Debugじゃないと、エディタとの連動とかで使い勝手が悪い（「コンソール出力をダブルクリックで該当ソースにジャンプ」が使えなくなります）。なので、#if !UNITY_EDITOR　を使って、エディター上では定義を無効にしています。
ここに書いてるメソッドは一部なので、必要に応じてDebug.Log以外のメソッドも同様に定義を追加してください。~~

~~もちろん、自力でエディター拡張して、色々なログを吐いたりエディターと連動したりするクラスを作ったほうが何かと融通が利くと思います。
ただ、既にコードのあちこちにDebug.Logを仕込んでしまった場合はこのやり方を使えば、製品版でのログ出力を止められます。
なお、Assemblyを分けている場合はおそらく通用しないので、その点は注意してください。~~
[Gehirn RS2] RVM+nginx+Passenger環境でRails3を動かしてみる

Gehrn RS2でnginx+Passengerを使う際のインストールメモ。

**2012/12/25 gemsetを使うようにしたため修正**

ディスク容量を減らすため、facerootは使ってません。
まずは、SSHでログインします。
1.rubyをrs2コマンドでインストール

```console
$ rs2 install ruby
※、インストール完了後、SSHで再ログインすると、RVMが設定されています。
ここで、gemsetを指定します。
$ rvm gemset create gehirn
$ rvm gemset use gehirn
```

2.gemrcの設定

```console
$ vi ~/.gemrc
※、新規ファイルに以下を追加
:verbose: true
:sources: 
- http://gems.rubyforge.org/
- http://gems.github.com
:benchmark: false
:backtrace: false
:update_sources: true
:bulk_threshold: 1000
install: --no-ri --no-rdoc
update: --no-ri --no-rdoc
```

3.passengerをインストール

```console
$ gem install passenger
※、passengerがインストールされます
```

4.nginxとmoduleをインストール

```console
$ passenger-install-nginx-module
※、ここで1つ目の選択肢では「1」を2つ目の選択肢のインストールパスでは
「/home/[ユーザ名]/nginx」を指定します。

5.confファイルの設定
$ vi /home/[ユーザ名]/nginx/conf/nginx.conf
※、ここで、以下の設定を変更します。

```

変更前

```nginx
    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }
```

変更後

```nginx

    server {
        listen       61229;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   /home/[ユーザ名]/nginx/html/[アプリディレクトリ]/public;
            #index  index.html index.htm;
            passenger_enabled on;
            passenger_base_uri /[アプリディレクトリ];
            rails_spawn_method smart;
            rails_env production;
        }
```

6.nginxの起動

```console
$ cd /home/[ユーザ名]/nginx/sbin
$ ./nginx
```

これで、nginxが起動します。
ここで、アプリディレクトリにrailsのアプリを展開すればOKです。
展開時にBundlerについては、gemsetで設定しているのでsystemにインストールします。

```console
アプリディレクトリで、以下を実施
$ vi .rvmrc
rvm gemset use ruby-1.9.3-p327@gehirn
※、rvmのgemsetを指定

$ bundle install --system
※、gemをインストール

$ bundle exec rake assets:precompile 
※、sssetsをコンパイル
```
7.index.htmlの削除

```console
$ rm /home/[ユーザ名]/nginx/html/index.html
```

8.Passengerの再起動

```console
$ touch /home/[ユーザ名]/nginx/html/[アプリディレクトリ]/tmp/restart.txt
```

問題がなければ、以下のアドレスにアクセスすれば、Railsアプリが実行されています。
http://ユーザ名.gehirn.ne.jp:61229/

サービスとして登録するのではなく、cronの＠restartなどに起動シェルを登録して
再起動に対応します。(このへんは別途記載)

> 3.50 GB 中 478.49 MB（13%）使用しています。

と少ないので個人的にはありと思っております。
配列の添字がでかいとき

2^32 - 1

```
$ perl -e 'print [0,1,2,3]->[4294967295]'
3
```

2^32

```
$ perl -e 'print [0,1,2,3]->[4294967296]'
0
```

64ビット環境なんだけど32ビット符号付き整数として処理されてる模様。
Ember.js JSONデータをロードして表示するサンプル

今日はTwitterに検索をかけて、返されたJSONデータを、表示に反映するサンプルを見ていきたいと思います。以下がソースコードの全文です。

```js
var App = Ember.Application.create();

var searchTweets = function(query) {
  return $.Deferred(function(defer) {
    return $.ajax({
      url: 'http://search.twitter.com/search.json',
      dataType: 'jsonp',
      data: {
        result_type: 'recent',
        rpp: 10,
        page: 1, 
        q: query
      }
    }).done(function(res) {
      return defer.resolve(res.results);
    });
  }).promise();
};

//// Controllers
App.tweets = Ember.ArrayController.create({
  content: [], 
  update: function(query) {
    var _this;
    _this = this;
    searchTweets(query).done(function(tweets) {
      _this.get('content').unshiftObjects(tweets);
    });
  }
});

//// Views
App.ApplicationView = Ember.View.extend({
  query: '#emberjs',
  search: function() {
    App.tweets.update(this.get('query'));
  }
});

App.TweetsView = Ember.View.extend({
  templateName: 'tweets-view',
  tweetsBinding: 'App.tweets.content'
});
```

まずControllerから見ていきましょう。

```js
App.tweets = Ember.ArrayController.create({
  content: [], 
  update: function(query) {
    var _this;
    _this = this;
    searchTweets(query).done(function(tweets) {
      _this.get('content').unshiftObjects(tweets);
    });
  }
});
```

検索結果のツイートを表示するために、Ember.ArrayControllerのインスタンスを作成しています。
ArrayControllerは、contentメンバに配列データを格納します。Ember.jsでは、アプリケーションで扱うデータの格納、ビジネスロジックは、Controllerに置くのが流儀です。(一般的なMVCフレームワークなら、この役割はModelが担うところですが、Ember.jsでは用語がかなり違和感のある使い方をされています。)

updateメソッドは、検索ボタンが押された時に呼ばれます。今回はunshiftObjects()メソッドを利用して、どんどん結果を追加していくようにしました。もし検索ごとに結果を入れ替えたいなら、unshiftObjects()を使う代わりに、set()を使えばOKです。
↓こんな感じです。

```js
    searchTweets(query).done(function(tweets) {
      _this.set('content', tweets);
    });

```

Ember.jsは、現状データの送信/受信の部分の処理を提供していません。今回は、jQueryの機能を使って検索結果の受信を実装しました。

次はViewを見ていきます。

```js
//// Views
App.ApplicationView = Ember.View.extend({
  query: '#emberjs',
  search: function() {
    App.tweets.update(this.get('query'));
  }
});

App.TweetsView = Ember.View.extend({
  templateName: 'tweets-view',
  tweetsBinding: 'App.tweets.content'
});
```

Viewは簡単です。ApplicationViewの検索ボタンが押された時のトリガはsearchメソッドです。queryはテキストフィールドにバインディングされていて、ユーザが入力した値で検索を掛けます。結果表示はTweetsViewが行います。

テンプレートの記述は以下のとおりです。

```html
  <script type="text/x-handlebars">

    {{view Ember.TextField valueBinding="query"}}
    <button {{action "search"}}>search tweets</button>

    {{view App.TweetsView}}
  </script>

  <script type="text/x-handlebars" data-template-name="tweets-view">
    <ul>
      {{#each view.tweets}}
        <li>
        <a href="http://twitter.com/{{from_user}}">{{from_user}}</a> {{text}}
        </li>
      {{/each}}
    </ul>
  </script>
```

以下のページで実際の動作を確認できます。

http://kmdsbng.github.com/emberjs_twitter_search_sample/
配列の inf 番目の要素は?


```
$ perl -e 'print [0,1,2,3,4]->[0+"inf"]'
4
```

```
$ perl -e 'print [0,1,2,3,4]->[0+"-inf"]'
0
```

```
$ perl -e 'print [0,1,2,3,4]->[0+"nan"]'
0
```

```
$ perl -e 'print [0,1,2,3,4]->[0+"hoge"]'
0
```

```
$ perl -e 'print [0,1,2,3,4]->[-0**1]'
0
```
pumaを使ってみた

注:このTipsはRails初心者が書いたものです。ツッコミ歓迎です。

#pumaとは
http://puma.io/ で公開されているconcurrentなWebサーバー。thinやunicornはワーカー毎にプロセスを立ち上げるが、pumaはワーカー毎にスレッドを立ち上げる。production環境ではサイトのパフォーマンスを上げるため、複数のワーカーを立ち上げるが、thinやunicornはワーカー毎にプロセスが異なるため、排他処理ができない。しかし、pumaはスレッドで動作するため、Mutexでsynchronizeブロックを記述すれば、排他処理を行える。

[RailsCast #365 Thread-Safety](http://railscasts.com/episodes/365-thread-safety)で取り上げられていた。ここではpumaの設定等のメモをまとめる。

##インストール

pumaも他のgemと同様、Gemfileに

```ruby:Gemfile
gem 'puma'
```

と書いて

```sh
bundle
```

でインストールできる。

##起動

```sh
rails s Puma
```

でWEBrickの代わりのpumaがサーバーになる。標準では16スレッド立ち上がる。

##設定ファイルによる起動

ドキュメントはまだない。[公式でも実装を読んでほしいらしい。](https://github.com/puma/puma/blob/master/lib/puma/configuration.rb)
(ただしdaemonの設定は、2.0.0よりサポートされる。)

###puma.rbの設定例

```ruby:puma.rb
root = "/home/myapp"                                                                                                                                                             
bind 'unix:///tmp/puma.sock'
pidfile "#{root}/tmp/pid"
state_path "#{root}/tmp/state"
activate_control_app
```
activate_control_appは、pumactlというpumaをコントロールするコマンドを使いたい場合は有効にする。pumactlを使うにはactivate_control_app以外にもstate_pathを出力しなければならない。pumaを外部のプロセスから停止するには、

```sh
pumactl --state $STATEFILE stop
```

というように、state_pathで出力しておいたファイルを指定する。

##サービス化

Linux上でサービス化するには、[jungle](https://github.com/puma/puma/tree/master/tools/jungle)
を見る。複数のアプリもサポートできるみたい。start-stop-daemonを使ってdaemon化する。

複数のアプリを設定した場合、それぞれのアプリごとの環境変数はどういうように設定すればいいのだろう。

##Nginxとの連携
https://github.com/puma/puma/blob/master/docs/nginx.md
を参考にしよう。
読み取り専用配列


```
Internals::SvREADONLY (@hoge, 1);
```
のようにして読み取り専用にした配列に

```
eval {
  push @hoge, $fuga;
};
```
と push するとエラーになる。そこまでは良いのだけれど、 $fuga の参照数が上がってしまうらしくずっと解放されない。

https://gist.github.com/4244683
zshでの移動をとにかく楽にする


今回は､簡単にできてかつ､効果的な`zsh`のカスタマイズを紹介していきたいと思います｡テーマは移動です｡


#zshrc


```shell:~/.zshrc
# 'cd' なしで移動する
setopt auto_cd
setopt auto_pushd

# 重複するディレクトリは記録しないようにする
setopt correct

# 'cd -' [Tab] で以前移動したディレクトリに移動する
setopt pushd_ignore_dups

# 移動した後は 'ls' する
function chpwd() { ls -F }

# '^' を押すと上のディレクトリに移動する
function cdup() {
echo
cd ..
zle reset-prompt
}
zle -N cdup
bindkey '\^' cdup
```



#autojump

`autojump`をインストールすると､`j <キーワード>`でキーワードに関連する移動頻度が高いディレクトリ一覧を表示してくれます｡また､`j D__3`などの番号でも移動できます｡

```shell:
# https://github.com/joelthelion/autojump

brew install autojump

j --stat
```
Padrinoでプロジェクトのテンプレートを作る


Padrinoは色んなO/Rマッパー、テンプレートエンジン、データベース、テスティングフレームワークを選べるので柔軟で便利なんだけど、プロジェクトを作成する度に「あれ？どう指定したらいいんだっけ？」となりがち。

しかも自分が普段使うテスティングフレームワークやテンプレートエンジンなんかは決まっているので別に毎回柔軟に設定できる必要もない。

「自分はいつもjquery使っててactiverecordをO/Rマッパーにしていてテンプレートエンジンはslimだ！」
なんてこともあるよね。
そんな時はこんな感じでtemplateを作成しておこう。

```ruby:my_padrino_template.rb
project {
  :test => :rspec,
  :renderer => :slim,
  :script => :jquery,
  :orm => :activerecord,
  :bundle => true
}
```


こういうファイルを保存しておいて、プロジェクトを作成するときに

`padrino g project --template /path/to/my_padrino_template.rb`

と指定して実行すれば決まった構成でプロジェクトを作れる。
これでなんか指定し忘れて「うお、テンプレートエンジンがデフォルトのhamlになっとる！」なんてこともない。


「普段hamlでもslimでも色んなテンプレートエンジン使い分けてるからなー」って場合はthorのメソッドを使って対話式にも出来る。

```ruby:my_padrino_template.rb
renderer = ask("Renderer(erb, slim, haml, liquid):")

choices = {
	:test => :rspec,
	:renderer => renderer,
	:script => :jquery,
	:orm => :activerecord,
	:bundle => true
}

project choices
```

こうしておくと実行時に選べるようになる。

```
$ padrino g project hello_prj --template ./my_template.rb                                     
       apply  /Path/to/my_template.rb
  Renderer(erb, slim, haml, liquid): slim #ここで聞いてくれる！
  => Executing: padrino-gen project hello_prj --bundle=true --orm=activerecord --renderer=slim --script=jquery --test=rspec -r=/Path/to
```

というように選択式にすることも出来る。

こんな感じで自分のtemplateを育てておくと便利。毎回作る認証部分までを含んだtemplateだって作成可能。

[padrino-recipes](https://github.com/padrino/padrino-recipes)の中のtemplatesにはpadrinoのチュートリアルで作成する[blogのアプリを丸々作成出来るtenplate](https://github.com/padrino/padrino-recipes/blob/master/templates/sampleblog_template.rb)もある。

[この辺のAPI](http://www.padrinorb.com/api/Padrino/Generators/Runner.html)を見ておくといいかも。
NIPS2012より識別モデル学習の進展を垣間見る

こんばんは．[@kisa12012](https://twitter.com/kisa12012)です．しがない機械学習系大学院生をやっております．
Machine Learning Advent Calendar 2012 9日目では，"NIPS2012より識別学習の進展を垣間見る"という無駄に野心的なタイトルで，先ほどまで開催されていたNIPS2012で発表された数本の論文概要を紹介します．
機械学習，特に識別学習の最先端が多少なりとも垣間見える，もしくは論文本体を読んでみようと思わせられる記事になっていれば幸いです．

**重要** : 概要紹介のみなので，数式は一切出てきません．（数式を記述する前に力尽きました……）

http://d.hatena.ne.jp/kisa12012/20121209
Mac OS 10.8 PHP デフォルトのタイムゾーンを設定

PHP スクリプト中で date 関数をおもむろに使うと、以下のようなメッセージが返ってくることがある：

> Strict Standards: date() [function.date]: It is not safe to rely on the systems timezone settings, please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. We now use 'Asia/Tokyo' for 'JST' in

PHP スクリプト中でタイムゾーンを

'date_default_timezone_set('Asia/Tokyo');'

と設定するのもいいけれど、php.ini にデフォルトの設定を入れておくのがよい。Mac OS 10.8 にインストールされているデフォルトの PHP には php.ini が存在しないので、[Mac初期化後の「開発」環境構築メモ（2012年9月版）](http://qiita.com/items/ee7024b41b0818d7542d) の以下を参考に php.ini を作成

> ##### PHP
> php.iniがないので、php.ini.defaultをコピーして作成する
> `sudo cp /etc/php.ini.default /etc/php.ini`

デフォルトのタイムゾーンを設定するには php.ini を以下のように更新して

```php:/etc/php.ini
# 1008-1010 行目
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
;date.timezone =
# 1010 行目を以下のように変更
date.timezone = "Asia/Tokyo"
```
ターミナルで `$sudo apachectl restart` として httpd を再起動

設定できるタイムゾーンの書式は
http://jp1.php.net/manual/ja/datetime.configuration.php#ini.date.timezone
CLIで手軽にカレーパンマンに喋らせたい

そんな時はこのgemを使うと便利です。
[pebbles-soreyuke | RubyGems.org](https://rubygems.org/gems/pebbles-soreyuke)

![](https://dl.dropbox.com/u/85825/blog/image/20121209/pebbles-soreyuke.png)

以前職場の先輩のために作っていて、やりかけだったのでこの機会にアップデートして公開しました。

先輩、今でもカレーパンマンって呼ばれたりしてるのかな？


追記(2012-12-12): 

先輩「未だに（たまに）呼ばれていますよ。」
コンソールに出力する文字に色をつける


制御文字を入れるだけで、色をつけることができます。用が終わったら、リセット用の制御文字でもとに戻しましょう。

```js
var black   = '\u001b[30m';
var red     = '\u001b[31m';
var green   = '\u001b[32m';
var yellow  = '\u001b[33m';
var blue    = '\u001b[34m';
var magenta = '\u001b[35m';
var cyan    = '\u001b[36m';
var white   = '\u001b[37m';

var reset   = '\u001b[0m';

console.log(red + 'This text is red. ' + green + 'Greeeeeeen!' + reset);
```

参考
[Console colors in node.js | Rogue JS](http://roguejs.com/2011-11-30/console-colors-in-node-js/)
カレンダーから作業時間を計算するスクリプトを作った！

これは、Google Apps Script Advent Calendar 2012の10日目の記事です。

フライングしてますが、前から欲しかったので一気に作ってみました。
今回はGoogle Calendarに登録してある予定（実績）から、かかった時間（＝作業時間）を
計算するGoogle Apps Scriptを作ってみました。

実際の業務でも「XXX作業、?時間」という報告をすることもあるでしょう。
（えっ？今の時代にそんな事しない？）

そういう報告するためのデータをGoogle Calendarで管理して、勝手にGASで計算して、文面を整えて、メールで上司に飛ばしたら非常に便利だと思います。
ここでは、カレンダーから時間を計測する部分のみを紹介します。

# 作成したコード

``` js:コード.gs
function myFunction() {
  var calendarName = "登録しているカレンダー名";
  var title = "＜取得したい作業名＞";
  
  // 今回は敢えて期間は長めに！
  var startTime = new Date("2012/08/01");
  var endTime = new Date("2013/01/01");
  
  // カレンダーの名前からカレンダーオブジェクトを取得
  // （複数の可能性があるので配列で返るよ！）
  var calendars = CalendarApp.getCalendarsByName(calendarName);
  for(var i = 0; i < calendars.length; i++) {
    // 開始時間と終了時間を指定することで、特定の期間のイベントを全て取得。
    var events = calendars[i].getEvents(startTime, endTime);
    Logger.log("全イベント数 = %s", events.length);
    
    var allTime = 0;
    var targetCount = 0;
    for(var count = 0; count < events.length; count++) {
      // カレンダーのタイトルでの絞り込みはできないので
      // 全てのイベントのタイトルで比較する。
      if(events[count].getTitle() == title) {
        targetCount++;
        var event_start = events[count].getStartTime();
        var event_end = events[count].getEndTime();
        
        // 時間の計算はmoment.jsを使えばもう少し楽になるよ！(Google Apps Script Advent Calendar 2012 5日目参照）
        Logger.log("イベント[%s] = %s", events[count].getTitle(), (event_end - event_start));
        allTime += ((event_end - event_start) / 1000);
      }
    }
    
    // ログに出力せず、Spreadsheetに出力すればもう少し見栄えが良いかも。
    // 今回は作業時間が割り出したかったのでLoggerにしています。
    Logger.log("イベント数 = %s, 全時間 = %s", targetCount, allTime / 3600);
  }
}
```

# レシピ
カレンダーの取得（`戻り値は配列`）
CalendarApp.getCalendarsByName(カレンダー名)
予定の取得（`戻り値は配列`）
Calendar.getEvents(開始時間, 終了時間)
イベントタイトルの取得
CalendarEvent.getTitle()
イベントの開始時間の取得
CalendarEvent.getStartTime()
イベントの終了時間の取得
CalendarEvent.getEndTime()

JavaScriptのDateオブジェクトで差分の計算

# 実行結果

...たくさんのログ...

イベント数 = 88.0, 全時間 = 191.0

# 結論
赤字か？！
既存のローカルブランチをリモートブランチを追跡させる


Git 1.8.0で確認。

現在のローカルブランチに`origin/master`を追跡させる場合。

```
$ git branch -u origin/master
```

`hoge`という名前のローカルブランチに`origin/hoge`を追跡させる場合。

```
$ git branch -u origin/hoge hoge
```
カラムが縦に列挙されるようにクエリ出力形式を変更する


特定のクエリのみ、出力形式を変更する場合はdelimiterを`;`から`\G`に変更することで、カラムが縦に列挙されるようになる。

```
mysql> select * from users\G
```

すべてのクエリの出力形式を変更する場合は、`mysql`コマンドに`-E`オプションを追加してデータベースに接続する。

```
$ mysql -E 
```
Visualforceで棒グラフと折れ線グラフを一緒に表示

Winter'13でグラフを表示するための<apex:chart>が正式にリリースされました。

これを使用して棒グラフと折れ線グラフを一緒に表示することができます。

```Apex:Apex
public class Chart_ChartTips {

    public List<Data> getData() {
        return Chart_ChartTips.getChartData();
    }
    
    @RemoteAction
    public static List<Data> getRemoteData() {
        return Chart_ChartTips.getChartData();
    }

    public static List<Data> getChartData() {
        List<Data> data = new List<Data>();
        data.add(new Data('Jan', 30, 90, 55));
        data.add(new Data('Feb', 44, 15, 65));
        data.add(new Data('Mar', 25, 32, 75));
        data.add(new Data('Apr', 74, 28, 85));
        data.add(new Data('May', 65, 51, 95));
        data.add(new Data('Jun', 33, 45, 99));
        data.add(new Data('Jul', 92, 82, 30));
        data.add(new Data('Aug', 87, 73, 45));
        data.add(new Data('Sep', 34, 65, 55));
        data.add(new Data('Oct', 78, 66, 56));
        data.add(new Data('Nov', 80, 67, 53));
        data.add(new Data('Dec', 17, 70, 70));
        return data;
    }
    
    public class Data {
        public String name { get; set; }
        public Integer data1 { get; set; }
        public Integer data2 { get; set; }
        public Integer data3 { get; set; }
        public Data(String name, Integer data1, Integer data2, Integer data3) {
            this.name = name;
            this.data1 = data1;
            this.data2 = data2;
            this.data3 = data3;
        }
    }
}
```

```Visualforce:Visualforce
<apex:page controller="ChartController">
    <apex:chart height="400" width="700" data="{!data}">
        <apex:legend position="right"/>
        <apex:axis type="Numeric" position="left" fields="data1"  title="Opportunities Closed" grid="true"/>
        <apex:axis type="Numeric" position="right" fields="data3"  title="Revenue (millions)"/>
        <apex:axis type="Category" position="bottom" fields="name"  title="Month of the Year">
            <apex:chartLabel rotate="315"/>
        </apex:axis>
        <apex:barSeries title="Monthly Sales" orientation="vertical" axis="right"  xField="name" yField="data3">
            <apex:chartTips height="20" width="120"/>
        </apex:barSeries>
        <apex:lineSeries title="Closed-Won" axis="left" xField="name" yField="data1"  fill="true" markerType="cross" markerSize="4" markerFill="#FF0000"/>
        <apex:lineSeries title="Closed-Lost" axis="left" xField="name" yField="data2"  markerType="circle" markerSize="4" markerFill="#8E35EF"/>
    </apex:chart>
</apex:page>
```
Visualforceで折れ線グラフ（複数）表示

Winter'13でグラフを表示するための<apex:chart>が正式にリリースされました。

これを使用して積み上げ棒グラフを表示することができます。

```Apex:Apex
public with sharing class Chart_SecondLineSeries {
    
    public List<Data> getData() {
        return Chart_SecondLineSeries.getChartData();
    }
    
    @RemoteAction
    public static List<Data> getRemoteData() {
        return Chart_SecondLineSeries.getChartData();
    }
    
    public static List<Data> getChartData() {
        List<Data> data = new List<Data>();
        data.add(new Data('Jan', 30, 90));
        data.add(new Data('Feb', 44, 15));
        data.add(new Data('Mar', 25, 32));
        data.add(new Data('Apr', 74, 28));
        data.add(new Data('May', 65, 51));
        data.add(new Data('Jun', 33, 45));
        data.add(new Data('Jul', 92, 82));
        data.add(new Data('Aug', 87, 73));
        data.add(new Data('Sep', 34, 65));
        data.add(new Data('Oct', 78, 66));
        data.add(new Data('Nov', 80, 67));
        data.add(new Data('Dec', 17, 70));
        return data;
    }
    
    public class Data {
        public String name { get; set; }
        public Integer data1 { get; set; }
        public Integer data2 { get; set; }
        public Data(String name, Integer data1, Integer data2) {
            this.name = name;
            this.data1 = data1;
            this.data2 = data2;
        }
    }
}
```

```Visualforce:Visualforce
<apex:page controller="Chart_SecondLineSeries">
    <apex:chart height="400" width="700" data="{!data}">
          <apex:axis type="Numeric" position="left" fields="data1,data2"  title="Opportunities Closed" grid="true"/>
          <apex:axis type="Category" position="bottom" fields="name"  title="Month of the Year">
          </apex:axis>
          <apex:lineSeries axis="left" fill="true" xField="name" yField="data1"  markerType="cross" markerSize="4" markerFill="#FF0000"/>
          <apex:lineSeries axis="left" xField="name" yField="data2"  markerType="circle" markerSize="4" markerFill="#8E35EF"/>
    </apex:chart>
</apex:page>
```
Visualforceで折れ線グラフ表示

Winter'13でグラフを表示するための<apex:chart>が正式にリリースされました。

これを使用して折れ線グラフを表示することができます。

```Apex:Apex
public with sharing class Chart_SimpleLineSeries {
    
    public List<Data> getData() {
        return Chart_SimpleLineSeries.getChartData();
    }
    
    @RemoteAction
    public static List<Data> getRemoteData() {
        return Chart_SimpleLineSeries.getChartData();
    }
    
    public static List<Data> getChartData() {
        List<Data> data = new List<Data>();
        data.add(new Data('Jan', 30));
        data.add(new Data('Feb', 44));
        data.add(new Data('Mar', 25));
        data.add(new Data('Apr', 74));
        data.add(new Data('May', 65));
        data.add(new Data('Jun', 33));
        data.add(new Data('Jul', 92));
        data.add(new Data('Aug', 87));
        data.add(new Data('Sep', 34));
        data.add(new Data('Oct', 78));
        data.add(new Data('Nov', 80));
        data.add(new Data('Dec', 17));
        return data;
    }
    
    public class Data {
        public String name { get; set; }
        public Integer data1 { get; set; }
        public Data(String name, Integer data1) {
            this.name = name;
            this.data1 = data1;
        }
    }
}
```

```Visualforce:Visualforce
<apex:page controller="Chart_SimpleLineSeries">
    <apex:chart height="400" width="700" data="{!data}">
          <apex:axis type="Numeric" position="left" fields="data1"  title="Opportunities Closed" grid="true"/>
          <apex:axis type="Category" position="bottom" fields="name"  title="Month of the Year">
        </apex:axis>
        <apex:lineSeries axis="left" fill="true" xField="name" yField="data1"  markerType="cross" markerSize="4" markerFill="#FF0000"/>
   </apex:chart>
</apex:page>
```
Visualforceで散布図を表示

Winter'13でグラフを表示するための<apex:chart>が正式にリリースされました。

これを使用して散布図を表示することができます。

```Apex:Apex
public with sharing class Chart_ScatterSeries {
    
    public List<Data> getData() {
        return Chart_ScatterSeries.getChartData();
    }
    
    @RemoteAction
    public static List<Data> getRemoteData() {
        return Chart_ScatterSeries.getChartData();
    }
    
    public static List<Data> getChartData() {
        List<Data> data = new List<Data>();
        data.add(new Data('Jan', 30, 90));
        data.add(new Data('Feb', 44, 15));
        data.add(new Data('Mar', 25, 32));
        data.add(new Data('Apr', 74, 28));
        data.add(new Data('May', 65, 51));
        data.add(new Data('Jun', 33, 45));
        data.add(new Data('Jul', 92, 82));
        data.add(new Data('Aug', 87, 73));
        data.add(new Data('Sep', 34, 65));
        data.add(new Data('Oct', 78, 66));
        data.add(new Data('Nov', 80, 67));
        data.add(new Data('Dec', 17, 70));
        return data;
    }
    
    public class Data {
        public String name { get; set; }
        public Integer data1 { get; set; }
        public Integer data2 { get; set; }
        public Data(String name, Integer data1, Integer data2) {
            this.name = name;
            this.data1 = data1;
            this.data2 = data2;
        }
    }
}
```

```Visualforce:Visualforce
<apex:page controller="Chart_ScatterSeries">
    <apex:chart height="530" width="700" animate="true" data="{!data}">
        <apex:scatterSeries xField="data1" yField="data2"  markerType="circle" markerSize="3"/>
        <apex:axis type="Numeric" position="bottom" fields="data1"  title="Torque" grid="true">
            <apex:chartLabel />
        </apex:axis>
        <apex:axis type="Numeric" position="left" fields="data2"  title="Lateral Motion" grid="true">
            <apex:chartLabel />
        </apex:axis>
    </apex:chart>
</apex:page>
```
Visualforceでレーダーグラフ表示

Winter'13でグラフを表示するための<apex:chart>が正式にリリースされました。

これを使用して積み上げ棒グラフを表示することができます。

```Apex:Apex
public with sharing class Chart_RadarSeries {
    
    public List<Data> getData() {
        return Chart_RadarSeries.getChartData();
    }
    
    @RemoteAction
    public static List<Data> getRemoteData() {
        return Chart_RadarSeries.getChartData();
    }
    
    public static List<Data> getChartData() {
        List<Data> data = new List<Data>();
        data.add(new Data('Jan', 30, 90, 55));
        data.add(new Data('Feb', 44, 15, 65));
        data.add(new Data('Mar', 25, 32, 75));
        data.add(new Data('Apr', 74, 28, 85));
        data.add(new Data('May', 65, 51, 95));
        data.add(new Data('Jun', 33, 45, 99));
        data.add(new Data('Jul', 92, 82, 30));
        data.add(new Data('Aug', 87, 73, 45));
        data.add(new Data('Sep', 34, 65, 55));
        data.add(new Data('Oct', 78, 66, 56));
        data.add(new Data('Nov', 80, 67, 53));
        data.add(new Data('Dec', 17, 70, 70));
        return data;
    }
    
    public class Data {
        public String name { get; set; }
        public Integer data1 { get; set; }
        public Integer data2 { get; set; }
        public Integer data3 { get; set; }
        public Data(String name, Integer data1, Integer data2, Integer data3) {
            this.name = name;
            this.data1 = data1;
            this.data2 = data2;
            this.data3 = data3;
        }
    }
}
```

```Visualforce:Visualforce
<apex:page controller="Chart_RadarSeries">
    <apex:chart height="530" width="700" legend="true" data="{!data}">
        <apex:legend position="left"/>
        <apex:axis type="Radial" position="radial">
            <apex:chartLabel />
        </apex:axis>
        <apex:radarSeries xField="name" yField="data1" tips="true" opacity="0.4"/>
        <apex:radarSeries xField="name" yField="data2" tips="true" opacity="0.4"/>
        <apex:radarSeries xField="name" yField="data3" tips="true"  markerType="cross" strokeWidth="2" strokeColor="#f33" opacity="0.4"/>
     </apex:chart>
</apex:page>
```
Visualforceでエリアグラフ表示

Winter'13でグラフを表示するための<apex:chart>が正式にリリースされました。

これを使用してエリアグラフを表示することができます。

```Apex:Apex
public with sharing class Chart_AreaSeries {
    
    public List<Data> getData() {
        return Chart_AreaSeries.getChartData();
    }
    
    @RemoteAction
    public static List<Data> getRemoteData() {
        return Chart_AreaSeries.getChartData();
    }
    
    public static List<Data> getChartData() {
        List<Data> data = new List<Data>();
        data.add(new Data('Jan', 30, 90, 55));
        data.add(new Data('Feb', 44, 15, 65));
        data.add(new Data('Mar', 25, 32, 75));
        data.add(new Data('Apr', 74, 28, 85));
        data.add(new Data('May', 65, 51, 95));
        data.add(new Data('Jun', 33, 45, 99));
        data.add(new Data('Jul', 92, 82, 30));
        data.add(new Data('Aug', 87, 73, 45));
        data.add(new Data('Sep', 34, 65, 55));
        data.add(new Data('Oct', 78, 66, 56));
        data.add(new Data('Nov', 80, 67, 53));
        data.add(new Data('Dec', 17, 70, 70));
        return data;
    }
    
    public class Data {
        public String name { get; set; }
        public Integer data1 { get; set; }
        public Integer data2 { get; set; }
        public Integer data3 { get; set; }
        public Data(String name, Integer data1, Integer data2, Integer data3) {
            this.name = name;
            this.data1 = data1;
            this.data2 = data2;
            this.data3 = data3;
        }
    }
}
```

```Visualforce:Visualforce
<apex:page controller="Chart_AreaSeries">
    <apex:chart height="400" width="700" animate="true" legend="true" data="{!data}">
        <apex:legend position="left"/>
        <apex:axis type="Numeric" position="left" fields="data1,data2,data3"  title="Closed Won" grid="true">
            <apex:chartLabel />
        </apex:axis>
        <apex:axis type="Category" position="bottom" fields="name"  title="Month of the Year">
            <apex:chartLabel rotate="315"/>
        </apex:axis>
        <apex:areaSeries axis="left" xField="name" yField="data1,data2,data3" tips="true"/>
    </apex:chart>
</apex:page>
```
Visualforceでゲージグラフ表示

Winter'13でグラフを表示するための<apex:chart>が正式にリリースされました。

これを使用してゲージグラフを表示することができます。

```Apex:Apex
public with sharing class Chart_GaugeSeries {
    
    public List<Data> getData() {
        return Chart_GaugeSeries.getChartData();
    }
    
    @RemoteAction
    public static List<Data> getRemoteData() {
        return Chart_GaugeSeries.getChartData();
    }
    
    public static List<Data> getChartData() {
        List<Data> data = new List<Data>();
        data.add(new Data('Jan', 30));
        data.add(new Data('Feb', 44));
        data.add(new Data('Mar', 25));
        data.add(new Data('Apr', 74));
        data.add(new Data('May', 65));
        data.add(new Data('Jun', 33));
        data.add(new Data('Jul', 92));
        data.add(new Data('Aug', 87));
        data.add(new Data('Sep', 34));
        data.add(new Data('Oct', 78));
        data.add(new Data('Nov', 80));
        data.add(new Data('Dec', 170));
        return data;
    }
    
    public class Data {
        public String name { get; set; }
        public Integer data1 { get; set; }
        public Data(String name, Integer data1) {
            this.name = name;
            this.data1 = data1;
        }
    }
}
```

```Visualforce:Visualforce
<apex:page controller="Chart_GaugeSeries">
    <apex:chart height="250" width="450" animate="true" data="{!data}">
        <apex:axis type="Gauge" position="gauge" title="Transaction Load"  minimum="0" maximum="100" steps="10"/>
        <apex:gaugeSeries dataField="data1" donut="50" colorSet="#78c953,#ddd"/>
    </apex:chart>
</apex:page>
```
Visualforceで積み上げ棒グラフ表示

Winter'13でグラフを表示するための<apex:chart>が正式にリリースされました。

これを使用して積み上げ棒グラフを表示することができます。

```Apex:Apex
public with sharing class Chart_BarSeries2 {
    
    public List<Data> getData() {
        return Chart_BarSeries2.getChartData();
    }
    
    @RemoteAction
    public static List<Data> getRemoteData() {
        return Chart_BarSeries2.getChartData();
    }
    
    public static List<Data> getChartData() {
        List<Data> data = new List<Data>();
        data.add(new Data('Jan', 30, 90, 55));
        data.add(new Data('Feb', 44, 15, 65));
        data.add(new Data('Mar', 25, 32, 75));
        data.add(new Data('Apr', 74, 28, 85));
        data.add(new Data('May', 65, 51, 95));
        data.add(new Data('Jun', 33, 45, 99));
        data.add(new Data('Jul', 92, 82, 30));
        data.add(new Data('Aug', 87, 73, 45));
        data.add(new Data('Sep', 34, 65, 55));
        data.add(new Data('Oct', 78, 66, 56));
        data.add(new Data('Nov', 80, 67, 53));
        data.add(new Data('Dec', 17, 70, 70));
        return data;
    }
    
    public class Data {
        public String name { get; set; }
        public Integer data1 { get; set; }
        public Integer data2 { get; set; }
        public Integer data3 { get; set; }
        public Data(String name, Integer data1, Integer data2, Integer data3) {
            this.name = name;
            this.data1 = data1;
            this.data2 = data2;
            this.data3 = data3;
        }
    }
}
```

```Visualforce:Visualforce
<apex:page controller="Chart_BarSeries2">
    <apex:chart data="{!data}" height="400" width="500">
        <apex:legend position="left"/>
        <apex:axis type="Numeric" position="left" title="Closed Won" grid="true"  fields="data1,data2,data3" dashSize="2">
            <apex:chartLabel />
        </apex:axis>
        <apex:axis type="Category" position="bottom" fields="name" title="Stacked Bars">
            <apex:chartLabel rotate="315"/>
        </apex:axis>
        <apex:barSeries orientation="vertical" axis="left" stacked="true"  xField="name" yField="data1,data2,data3" title="MacDonald,Promas,Worle"/>
    </apex:chart>
</apex:page>
```
Visualforceで棒グラフの表示

Winter'13でグラフを表示するための<apex:chart>が正式にリリースされました。

これを使用して棒グラフを表示することができます。

```Apex:Apex
public with sharing class Chart_BarSeries {
    
    public List<Data> getData() {
        return Chart_BarSeries.getChartData();
    }
    
    @RemoteAction
    public static List<Data> getRemoteData() {
        return Chart_BarSeries.getChartData();
    }
    
    public static List<Data> getChartData() {
        List<Data> data = new List<Data>();
        data.add(new Data('Jan', 30));
        data.add(new Data('Feb', 44));
        data.add(new Data('Mar', 25));
        data.add(new Data('Apr', 74));
        data.add(new Data('May', 65));
        data.add(new Data('Jun', 33));
        data.add(new Data('Jul', 92));
        data.add(new Data('Aug', 87));
        data.add(new Data('Sep', 34));
        data.add(new Data('Oct', 78));
        data.add(new Data('Nov', 80));
        data.add(new Data('Dec', 17));
        return data;
    }
    
    public class Data {
        public String name { get; set; }
        public Integer data1 { get; set; }
        public Data(String name, Integer data1) {
            this.name = name;
            this.data1 = data1;
        }
    }
}
```

```Visualforce:Visualforce
<apex:page controller="Chart_BarSeries">
    <apex:chart data="{!data}" height="400" width="500">
        <apex:legend position="left"/>
        <apex:axis type="Numeric" position="left" title="Closed Won" grid="true"  fields="data1" dashSize="2">
            <apex:chartLabel />
        </apex:axis>
        <apex:axis type="Category" position="bottom" fields="name" title="Stacked Bars">
            <apex:chartLabel rotate="315"/>
        </apex:axis>
        <apex:barSeries orientation="vertical" axis="left" stacked="true"  xField="name" yField="data1" title="MacDonald,Promas,Worle"/>
    </apex:chart>
</apex:page>
```
知られざるsystem.utilsの世界


Yiiの内部にひっそりと佇むutilsディレクトリにお気づきだろうか、マニュアルでもろくに触れられない地味な機能がここに詰まっている

##CVarDumper
その名の通りのver_dump。ただしちょっと便利になっている

```php:source
<?php
    CVarDumper::dump($class, 1);
```	

```php:dist
TestCommand#1
(
    [defaultAction] => 'index'
    [CConsoleCommand:_name] => 'test'
    [CConsoleCommand:_runner] => CConsoleCommandRunner(...)
    [CComponent:_e] => null
    [CComponent:_m] => null
)
```

コールは正直冗長だけど、第2引数でdepthが指定できる。大きなクラスをvar_dump()しようとすると出力が超大すぎることがあるので結構ありがたい。

```
<?php
     $dump = CVarDumper::dumpAsString($class);
```

ダンプした結果を変数で受け取りたいというのはまれによくあるケースで「あれob_startとかでできたっけ…」みたいに思ったりもするがちゃんと用意してくれてる。

##CPropertyValue

値を変換するスタティックメソッドを提供してくれるヘルパーだそうです。

```php:source
<?php
  CPropertyValue::ensureInteger('10sec'); // 10
  CPropertyValue::ensureString(false); // 'false'
  CPropertyValue::ensureBoolean(true); // true
  CPropertyValue::ensureBoolean('hogehoge'); // false
  CPropertyValue::ensureBoolean('true'); // true
  CPropertyValue::ensureArray('(1,2,3)'); // array(1,2,3)
```

上記のような事をしてくれます。ensureHogeということで値の型を保証するということですがtrue/falseを文字列にしてくれたりパーレンで囲まれた文字列をArrayとして評価したりといろいろと気をつかってくれています。
べつにキャストでいいかな


##CFileHelper.php

ファイルに関するヘルパーです

```php:source
<?php
  CFileHelper::getExtension('hoge/fuga.jpg'); // 'jpg'
  CFileHelper::getMimeType('hoge.xml'); // 'application/xml'
```

なんてちょっとしたことからファイル名で検索できる`findFiles()`とか再帰コピーしてくれる`copyDirectoryRecursive()`とかちょっと便利なものがあります。

##CTimestamp

時間に関するいろいろ

```php:source
<?php
    CTimestamp::getDayOfWeek(2012,12,9);  //0(曜日)
    CTimestamp::isLeapYear(2012); // true(うるう年判定)
    CTimestamp::get4DigitYear(85); //1985
    CTimestamp::get4DigitYear(12); //2012
```

曜日判定やらうるう年判定やら2桁年号の変換やらの小物からGMTとの時差とか`date()`の再実装とか色々入ってます。

##CDatetameParser

`strtotime()`とは趣の違った時間表記のパーサー

```php:source
<?php
    CDateTimeParser::parse('2012年12月2日','yyyy年M月d日'); // 1354374000
```

上記のように文字列とフォーマットを渡すとそのようにパースしてタイムスタンプを返してくれます。


##CMarkdownParser

実はデフォルトでMarkdownが利用できる

```php:source
<?php
    $parser = new CMarkdownParser;
    $contents = $parser->safeTransform('#hoge'); // '<h1>hoge</h1>'
```

利用しているパーサーライブラリは[php Markdown Extra](http://michelf.ca/projects/php-markdown/extra/)
細かく設定もできるようです

##CFormatter

フォーマットの管理を担うことができます
これだけはインスタンスとして最初からYiiのコアに組み込まれていますので`Yii::app()`から呼びます

```php:source
<?php
    Yii::app()->format->boolean(1); //Yes
    Yii::app()->format->formatEmail('hoge@hoge.co'); //'<a href="mailto:hoge@hoge.co">hoge/hoge.co</a>'
    Yii::app()->format->dateFormat = 'Y年m月d日 H時i分s秒';
    Yii::app()->format->formatDate(time());  //"2012年12月09日 04時17分44秒"

```

アプリケーション内で利用する共通の出力形式をFormatにもつことで統一化が図れます。特にYiiのViewで使うWidgetは勝手に色々と吐き出してくれるのでここは自然といじることになると思います。


というわけでutilsの下に眠る機能の一部を紹介しました。正直半分も使ったことありません。が、覚えてると地味ーに便利だったりすることもあったりなかったりするので覚えても覚えなくてもいいかもしれなくもない。そんなutilsです。
AsyncTaskにリスナーを追加してActivityで処理する


原型のAsyncTask

```java:AsyncTaskSample

public class AsyncTaskSample extends AsyncTask<Void, Integer, String> {
	//Activiyへのコールバック用interface
	public interface AsyncTaskCallback {
		void preExecute();
		void postExecute(String result);
		void progressUpdate(int progress);
		void cancel();
	}

	private AsyncTaskCallback callback = null;;

	public AsyncTaskSample(AsyncTaskCallback _callback) {
		this.callback = _callback;
	}

	@Override
	protected void onPreExecute() {
		super.onPreExecute();
		callback.preExecute();
	}

	@Override
	protected void onCancelled() {
		super.onCancelled();
		callback.cancel();
	}

	@Override
	protected void onPostExecute(String result) {
		super.onPostExecute(result);
		callback.postExecute(result);
	}

	@Override
	protected void onProgressUpdate(Integer... values) {
		super.onProgressUpdate(values);
		callback.progressUpdate(values[0]);
	}

	@Override
	protected String doInBackground(Void... params) {
		return null;
	}
}

```
(空行)
実装するActivity

```java:Activity
public class SampleActivity {
	public void onCreate(Bundle savedInstanceState) {
		AsyncTaskSample sampleTask = new AsyncTaskSample(new AsyncTaskCallback() {
			public void preExecute() {
				//だいたいの場合ダイアログの表示などを行う
			}
			public void postExecute(String result) {
				//AsyncTaskの結果を受け取ってなんかする
			}
			public void progressUpdate(int progress) {
				//だいたいプログレスダイアログを進める
			}
			public void cancel() {
				//キャンセルされた時になんかする
			}
		});
	 	sampleTask.execute();
	}
}
```

または

```java:Activity
public class SampleActivity implements AsyncTaskCallback {
	public void onCreate(Bundle savedInstanceState) {
		AsyncTaskSample sampleTask = new AsyncTaskSample(this);
		sampleTask.execute();
	}
	public void preExecute() {
		//だいたいの場合ダイアログの表示などを行う
	}
	public void postExecute(String result) {
		//AsyncTaskの結果を受け取ってなんかする
	}
	public void progressUpdate(int progress) {
		//だいたいプログレスダイアログを進める
	}
	public void cancel() {
		//キャンセルされた時になんかする
	}
}
```
MacのVimで全角記号（■とか）がずれないようにする

MacのTerminal.appのvimで文章を書いていると、■や□の扱いが半角の幅になっているので表示が崩れたりする。

Mountain LionならTerminal.appの設定で「Unicode 東アジア A（曖昧）の文字幅を W（広）にする」というのが言語環境のセクションにあるので、そのチェックをONにしておけば全角の幅で表示されるようになる。

Mountain Lion以前の場合、SIMBLプラグインの[TerminalEastAsianAmbiguousClearer](http://kita.dyndns.org/wiki/?TerminalEastAsianAmbiguousClearer)を使えば大丈夫になるみたい。
いつもお気に入りのhookを使う＆hookを使ってバージョンをちゃんと管理する


[ここ](http://stackoverflow.com/questions/2293498/git-commit-hooks-global-settings)に書いてあるように、
フックスクリプト置き場は自由に設定できるみたい。そこで、

```bash
git config --global init.templatedir '~/.git_template'
```

として、自分用のhookを書いていく。
注意点としては、ひとつしかテンプレートディレクトリを指定できないっぽいので、
会社とかで共通のhookの使用が前提となっている場合は他の方法を考える。
.git以下にはhook-loaderみたいなものをコピーして、実態は別の場所から参照、みたいな機能を用意できればいいのかな。
自分は特に差し迫って必要じゃないので作りませんが。

[ここ](http://qiita.com/items/dfe1ec9d82c0ed5da7c6)とか[ここ](http://git-scm.com/book/ja/Git-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-Git-%E3%83%95%E3%83%83%E3%82%AF)とか読めばどんなhooksがあるかわかる。

## ここからが本題

さて、この間もついやってしまったが、ライブラリやアプリケーションのバージョンとgitのタグとを同時に管理しているのに、タグ付けしてpushしたあとに
バージョンを上げるのを忘れてしまう。
例を挙げると、githubでgit push --tagsしたあとにsetup.pyやversion.rbの中を更新しわすれるパターン。

pre-push-hookとかpre-merge-hookはない（欲しい）。
私は幸いにもgit-flowを使っており、releaseブランチやhotfixブランチの中にバージョン記述がある。
それをpre-commit-hookを使い、コミット前にチェックする。

## 流れ

```bash
git flow release start 0.2
# 作業
git commit # この時にhook発動
# 作業
g flow release finish 0.2
```

慣れないbashで頑張って書きました。
https://raw.github.com/aflc/.git_template/master/hooks/pre-commit

## 設定

.gitconfigにこんな感じで書く。

```
# init.templatedirを設定すると、git initやcloneする度にhooksをコピーしてくれます
[init]
    templatedir = ~/.git_template
[version-check-hook]
    # mode = python
    mode = all
    python-path = "setup.py"
    python-pattern = "[^a-zA-Z]*version=['\\\"]\\(.*\\)['\\\"].*"
    ruby-path = "*/lib/*/version.rb"
    ruby-pattern = "[^a-zA-Z]*VERSION = ['\\\"]\\(.*\\)['\\\"].*"
```

modeになにか文字列を入れて、
${mode}-pathにチェックするファイルのパターン、${mode}-patternに正規表現を入れる。
ダブルクオートや()はエスケープしてください。
ダブルクオートとバックスラッシュはそもそも.gitconfigでエスケープが必要なので気をつけてください。
また、行頭からマッチしにいくので行全体のパターンを書いてください。

## 例

```bash
git init repo
cd repo
git flow init
...
git touch setup.py
...
git flow release 0.2
```

ここまで作業が終わったとします。この時、setup.pyに以下の様に書いてあったとします。

```python
from setuptools import setup
setup(name='repo',
      version='0.1',
...
```

setup.py中のバージョン表記は0.2なのに、バージョン0.1でリリースしようとしているのがわかります。
この時、さっき作ったpre-commit hookが発動します。

```bash
git commit
[version-check-hook] Incompatible version found.
Your branch: 0.2
Matched version: 0.1
----
setup.py:3:      version='0.1',
```

後は直してコミットすればOK。

## 最後に

スクリプトがとても汚くておそらくバグってるので誰か美しく作ってください。
今となってはPythonで書いても良かった気がする。