OmniAICreator/Qiita-1.07M huggingface dataset:
[Swift]enumについて想うこと


## 参考サイト

[Soopyのデータタイプ宣言](http://soopy.sourceforge.jp/tutorial/soopycontent13.html#000044)
http://dev.eyewhale.com/archives/1194
[CodeZine](http://codezine.jp/article/detail/7886)

## はじめに

Swiftのenum構文が、なんとも（個人的に）気持ちの悪いものになっているので、どうしたら満足できるか考えてみた。

## 現状

まずは、なぜ気持ちが悪く感じるのかを考えてみた。

Xcode6-Beta7におけるenumの書き方をみてみよう。

```swift:現状
protocol ConvertToString {
    func toString() -> String
}

enum Weeks : ConvertToString {
    case Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
    
    func toString() -> String {
        switch self {
            case .Sunday:    return "日"
            case .Monday:    return "月"
            case .Tuesday:   return "火"
            case .Wednesday: return "水"
            case .Thursday:  return "木"
            case .Friday:    return "金"
            case .Saturday:  return "土"
        }
    }
}
```

みてのとおり、Sunday,Mondayなど、Weeks型に属するものを列挙している。

また、列挙型に属するメソッドは、 **caseうんたらとは別の場所に** 書かれている。
そして、メソッドのなかで **switch文で分岐して処理** されている。

メソッドが「caseうんたらとは別の場所に」書かれ、「switch文で分岐して処理」されるのが、どうやら気持ち悪く感じる原因のようだ。

>あくまで個人的意見です。

## 考察

ざっとWEBを見渡してみた感じでは、enum型のメソッドは、ほとんどswitch文で分岐して処理しているようだ。

それっておかしくないですか？

順に考えていこう。
まず、列挙型の列挙された各値（SundayやMondayなど）は、オブジェクト指向的に考えると、クラスなのだろうか？　それとも、オブジェクトなのだろうか？
つまり、型なのだろうか値なのだろうか？

ちょっとコードを見てみよう。

```swift:
enum Sample {
    case OneInteger(Int)
}

let s1 = Sample.OneInteger(1)
let s2 = Sample.OneInteger(2)
```

このコードをみると、s1とs2は同じSample.OneIntegerでありながら引数が違う。s1とs2が違うオブジェクトであることは明白だろう。
ということは、Sample.OneIntegerはオブジェクトとは言えない。
では、型として考えることは可能だろうか。

これは可能だろう。
上記の例で言えば、Sample.OneInteger(1)は
「1を引数にして、Sample.OneInteger型のオブジェクトを返している」
と考えることが可能だ。
s2も同様。

列挙型の列挙された各値（SundayやMondayなど）を型と考えるならば、enumの中にあるメソッドは型とは別の離れた場所に書かれていることになる。

列挙型でない場合だと以下のように書かれているような感じ。

```swift:
class Foo {
    let val : Int

    init(_ val : Int){
        self.val = val
    }
}

class Bar {
    let val : Double
    
    init(_ val : Double){
        self.val = val
    }
}

let obj1 = Foo(8)
let obj2 = Bar(3.14)

func f(obj : Any){
    // switchでうまく書けなかったのでifで書いてある。
    // 雰囲気は伝わる（と思いたい…）
    if let foo = obj as? Foo {
        println("Foo");
    }
    if let bar = obj as? Bar {
        println("Bar")
    }
}

f(obj1)
f(obj2)
```

↑これは気持ち悪い。
メソッドfは、if文やswitch文で分岐処理しないで、型FooやBarのなかにそれぞれの型ごとの処理を書きたい。

そう考えていくと、enumの中のメソッドが、switchで分岐処理してるのもなんか変だと思うことになる。
enumの中でも、switchで分岐しないで型ごとにメソッドを書くほうが、よりオブジェクト指向っぽいのではないだろうか。

あくまで個人的感想だが、自分がどうして気持ち悪いと感じるのかはわかった。



## こうあって欲しいという希望

では、どうあって欲しいのか。

メソッドは型の宣言と同時に書きたい。
つまりは、こんな感じ↓


```swift:希望
protocol ConvertToString {
    func toString() -> String
}

enum NewWeeks : ConvertToString {
    case Sunday {
        func toString() -> { return "日" }
    }

    case Monday {
        func toString() -> { return "月" }
    }

    case Tuesday {
        func toString() -> { return "火" }
    }

    case Wednesday {
        func toString() -> { return "水" }
    }

    case Thursday {
        func toString() -> { return "木" }
    }

    case Friday {
        func toString() -> { return "金" }
    }

    case Saturday {
        func toString() -> { return "土" }
    }

}
```

ようするに、[Soopyのデータタイプ](http://soopy.sourceforge.jp/tutorial/soopycontent13.html#000044)みたいな書き方が個人的理想なのだろう…。
RSpec 3で大量のエラーメッセージが出てうるさい件について

Railsで開発してて、rspecでテストを実行したら、大量のエラーメッセージが出て、何がなんだかわからない状態に。

Railsプロジェクトのルートに、 ```.rspec``` ってファイルがあって、そこに設定とか色々書いているんだけど、RSpec 3からデフォルトで ```--warnings```オプションが有効になっているそうで。

そいつを削除してやれば、大量のエラーメッセージが消えて、あなたが求めているであろうエラーメッセージだけが表示されるようになります。

お試しあれ。
MMDAgent を Android で動かす

#MMDAgentについて
　MMDAgent( http://www.mmdagent.jp/ )は、名古屋工業大学国際音声技術研究所の"MMDAgent Projectチーム"が開発したオープンソースの音声対話端末です。
　音声認識システム"Julius"、音声合成システム"OpenJTalk"、3DCGムービーフォーマットMikuMikuDance"を利用しているそうです。

#ソースコード等ダウンロード
　MMDAgent公式サイト( http://www.mmdagent.jp/ )からソースコードをダウンロード。
　本記事では"MMDAgent version1.4(Dec 25, 2013)"をAndroidへインストールする手順を解説します。

###MMDAgent本体をダウンロード
　**公式サイトで配布されているコードそのままだとビルドがうまくいきません**
　GitHubでAndroid用にカスタマイズされているコードがあったので、それを利用しました。
　感謝
　(https://github.com/kaitoh/MMDAgent)

###サンプルスクリプトをインストール
　本体は3Dモデルや音声スクリプトなどが同梱されていないので、本体とは別でサンプルデータを公式サイトからダウンロードしてください。
　MMDAgent "Sample Script"→Binary Packageからサンプルをダウンロード

#Android開発環境をインストール
　Android開発環境としてEclipseおよびAndroidSDK、AndroidNDKをインストールします。また、今回は実機デバック用にNexus7端末を利用しました。
　アプリとは別で利用データを端末へ送る必要があります→AndroidFileTransferが便利
・Eclipse with AndroidSDK ( http://developer.android.com/sdk/index.html )
・AndroidNDK ( https://developer.android.com/tools/sdk/ndk/index.html )
・AndroidFileTransfer ( https://www.android.com/filetransfer/ )

参考サイト
・AndroidNDKを使った開発環境の構築( http://note.chiebukuro.yahoo.co.jp/detail/n136598 )
・実機デバッグについて ( http://androidguide.nomaki.jp/html/dbg/dbg2.html )
・AndroidFileTransferの認識がうまくいかない場合 ( http://nihaoshijie.hatenadiary.jp/entry/2014/04/23/211649 )


#モデル・音声データ等をAndroid端末へ配置
　MMDAgentをインストール前に各データをAndroid端末へ転送しておきます。
　MMDAgent本体のディレクトリ内にある Release ディレクトリがデータディレクトリになります。
　ただし、モデル等は入っていないので、あらかじめダウンロードしていたサンプルデータを以下の様に名前変更したうえで、Releaseディレクトリに上書きします。

　MMDAgent_Example.mdf → MMDAgent.mdf
　MMDAgent_Example.fst → MMDAgent.fst
　MMDAgent_Example.ojt → MMDAgent.ojt
　MMDAgent_Example.dic → MMDAgent.dic

　以下のようなディレクトリ構成になると思います。

![6e570a64-9034-50f8-0834-4476d63efb3f.png](https://qiita-image-store.s3.amazonaws.com/0/53351/2cc861c7-69d0-af24-d701-0acf4f62b420.png)

　このディレクトリをAndroidFileTransferを利用して、端末の任意の場所へ配置します。
　例:/storage/emulated/0/Release/

#MMDAgentをAndroid端末へインストール
##インポート
　MMDAgent本体のコード等をEclipseへインポートします!


##編集
　さきほど転送したデータの位置に合わせてソースを一部編集します。
　ディレクトリ jni → Library_MMDAgent → Android.mk を編集
　Android.mkの

・DMMDAGENT_OVERWRITEEXEFILE
・DMMDAGENT_OVERWRITECONFIGFILE
・DMMDAGENT_OVERWRITESYSDATADIR

が3Dモデル、音声スクリプトなどへのパスを指定する部分になっているので、先ほど転送したデータの位置に合わせて書き換えます。
例：
                    -DMMDAGENT_OVERWRITEEXEFILE="\"/storage/emulated/0/Release/MMDAgent.exe\"" \
                    -DMMDAGENT_OVERWRITECONFIGFILE="\"/storage/emulated/0/Release/MMDAgent.mdf\"" \
                    -DMMDAGENT_OVERWRITESYSDATADIR="\"/storage/emulated/0/Release/AppData\"" \

　これで準備完了です。EclipseのRun/DebugでAndroid端末へインストールしてください。
　（自分の環境の場合Run/Debugの前にビルドすると失敗します。NDKの問題か？、Run/Debugを押して自動ビルドそのまま実行にするとうまくいく）

#テスト
アプリを実行して、「こんにちは」というと、返事します。
表示が縦画面だとうまく表示されません。
IntelliJ IDEA で vimのキーバインドを使う

IntelliJ IDEAでvimのキーバインド使い始めました。

## メニューのPreferencesを選択
![スクリーンショット 2014-09-05 23.10.30.png](https://qiita-image-store.s3.amazonaws.com/0/1624/df02e10b-cc30-16a9-59e2-87540ca13564.png)

## Pluginsを選択
![スクリーンショット 2014-09-05 23.10.40.png](https://qiita-image-store.s3.amazonaws.com/0/1624/dbd447a3-21ce-9309-05bf-fc503e7868c2.png)

## IdeaVimを選択
![スクリーンショット 2014-09-05 23.11.01.png](https://qiita-image-store.s3.amazonaws.com/0/1624/d725264b-235a-258d-4fc0-accdc3ccedbf.png)

## IntelliJを再起動
![スクリーンショット 2014-09-05 23.11.15.png](https://qiita-image-store.s3.amazonaws.com/0/1624/f223e905-b81c-a0e6-59b9-0f436e66082e.png)

再起動するとvimのコマンドモードが使えるようになりました。便利ー(☝ ՞ਊ ՞)
SQLを書く時にお願いしたいこと

# SQLを書く時にお願いしたいこと

* その1、いつもと同じインデントを気にすること！
* その2、ちゃんとキーワード大文字にすること！いいね？
* その3、キーワード以外は小文字で書くこと！
* 分かったらそのSQLヒアドキュメントで書いて！！
* 別にワガママなんて言ってないんだから
* 君に見やすいSQLを書いて欲しいの！かわいいの！！
* 改行、イヤならラップして改行取り除けばよかろ？文字列連結なんて論外よ！！
 * [【初音ミク】ワールドイズマイン【PV】 ~ 【Hatsune Miku】 World is Mine 【PV】 ](https://www.youtube.com/watch?v=W2EsQu41aio)
* 絶対！絶対！！君は守ってくれる。守ってくれるわー

```
SELECT
    some,
    other
  FROM foo t1
  LEFT JOIN bar t2
         ON t1.id = t2.foo_id
 WHERE hoge = ?
   AND fuga = ?
 GROUP BY fugo 
 ORDER BY piyo
 LIMIT m
```
PECL High resolution timing 高性能な時計

[High resolution timing](http://php.net/manual/ja/book.hrtime.php)は、高性能な時計を提供します。

```php
<?php
	$c = new HRTime\StopWatch;
	$c->start();
	$c->stop();
	
	var_dump($c->getLastElapsedTime(HRTime\Unit::NANOSECOND));
```

start()からstop()の間に何もしていませんが、手元ではだいたい1000程度のfloat値が帰ってきます。
start()とstop()の間に1000ナノ秒程度の時間がかかっているようです。

http://www.php.net/manual/ja/intro.hrtime.php
> It uses the best possible APIs on different platforms which brings resolution up to nanoseconds.

最も性能の良いAPIを利用して時間を取得しているとのことです。

```php
<?php
	$c = new HRTime\StopWatch;
	$c->start();
	time_nanosleep(0, 1);
	$c->stop();

	var_dump($c->getLastElapsedTime(HRTime\Unit::NANOSECOND));
```

time_nanosleep()で1ナノ秒スリープしているので、理論上は1ナノ秒だけプラスされるはずなのですが、実際は10000いくらかの値が返ってきます。
http://jp2.php.net/manual/ja/function.time-nanosleep.php
time_nanosleep(0, 0)でも同じような値になるので、関数呼び出しのオーバーヘッドが10000ナノ秒くらいあるようです。
time_nanosleep(0, 100)までは値が変わらないのですがtime_nanosleep(0, 1000)あたりで急に500000くらいに値が増えてしまいます。
なぜだ。

実はWindowsのタイマは[ナノ秒の精度を持っていない](http://cpplover.blogspot.jp/2012/05/100.html)ので、そもそもtime_nanosleep(0, 1)のような設定をしても意味がないのであった。
いったい何に使えばいいんだHRTime。
MySQLをSELECTするときにINNER JOINするSQL

# キーを指定してJOIN

テーブルをSELECTするときにJOINするSQLが書きたくなりました。

```sql:SELECTするSQL
SELECT
  u.`id` AS user_id,
  u.`name`,
  g.`id` AS gid,
  g.`name`
FROM
  users u
INNER JOIN groups g ON
  u.`id` = g.`user_id`
WHERE
  u.`id` = 2;
```

usersテーブルのidと、groupsテーブルのuser_idをリレーションしているテーブルイメージです。

# お試し用テーブル
お試し用にテーブルを作りました。

```sql:userテーブル
create table users ( id int auto_increment, name text, primary key (id))  default character set utf8;
```

```sql:groupsテーブル
create table groups ( id int auto_increment, user_id int, name text, primary key (id)) default character set utf8;
```

構成がおかしいのですがお試しなので(^o^;)

## データをINSERT

```sql:SQL
INSERT INTO users (name) VALUES ('ジバニャン');
INSERT INTO users (name) VALUES ('ロボニャン'); 
INSERT INTO groups (user_id, name) VALUES ( 1, 'ネコ');
INSERT INTO groups (user_id, name) VALUES ( 1, '妖怪'); 
INSERT INTO groups (user_id, name) VALUES ( 2, '動物');
INSERT INTO groups (user_id, name) VALUES ( 2, 'ロボ'); 
```

# 実行結果
SQLを実行しました。

```sql:SQL
SELECT
  u.`id` AS user_id,
  u.`name`,
  g.`id` AS gid,
  g.`name`
FROM
  users u
INNER JOIN groups g ON
  u.`id` = g.`user_id`
WHERE
  u.`id` = 2;
```

```実行結果
+---------+-----------------+----------+--------+
| user_id | name            | gid | name   |
+---------+-----------------+----------+--------+
|       2 | ロボニャン      |        3 | 動物   |
|       2 | ロボニャン      |        4 | ロボ   |
+---------+-----------------+----------+--------+
2 rows in set (0.00 sec)
```
この結果がとりたかったのでした。
Ruby | 「call」メソッド の Syntax Sugar 「.()」 について

# Ruby | 「call」メソッド の Syntax Sugar 「.()」 について
## 概要
RubyKaigi で 登壇予定の Satoshi Egi 氏 の
egison-ruby を読んでいて「ん？？」という文法がありました。

件のコードがこちら。

~~~ruby
        with(List.(*_, _x, *_)) do
~~~

https://github.com/egison/egison-ruby/blob/master/lib/egison/matcher.rb#L71

`List.()` なんて書き方ははじめてみました。

「call」メソッド の Syntax Sugar により「.()」 と記述できることを活用しています。

## サンプルコード

~~~ruby
require 'tbpgr_utils'

class Hoge
  def self.call(msg)
    msg
  end
end

class Hige
  def call(msg)
    msg
  end
end

class Parent
  def self.call(msg)
    msg
  end
end

# 継承も使えます
class Child < Parent
end

module MyModule
  def call(msg)
    msg
  end
end

# Mix-inも使えます
class Includer
  include MyModule
end

bulk_puts_eval binding, <<-EOS
Hoge.("hoge")
Hoge.call("hoge")
Hige.new.("hige")
Hige.new.call("hige")
Child.("child")
Child.call("child")
Includer.new.("includer")
Includer.new.call("includer")
EOS

__END__
下記はTbpgrUtils gemの機能
bulk_puts_eval

https://rubygems.org/gems/tbpgr_utils
https://github.com/tbpgr/tbpgr_utils
~~~

## 出力

~~~bash
$ ruby ruby_implicit_send_call.rb
Hoge.("hoge")                 # => "hoge"
Hoge.call("hoge")             # => "hoge"
Hige.new.("hige")             # => "hige"
Hige.new.call("hige")         # => "hige"
Child.("child")               # => "child"
Child.call("child")           # => "child"
Includer.new.("includer")     # => "includer"
Includer.new.call("includer") # => "includer"
~~~

## 参照

* egison-ruby GitHub  
https://github.com/egison/egison-ruby
TypeScriptでmongoose と戦う日記 #1 モデルの独自定義

# まえおき
TypeScriptの世界に最近飛び込みました。まともにNode触った事無いので色々勉強中ですが、目下の所猛獣mongooseとの戦いが辛いので備忘録として書きます。
TypeScriptを勉強しながらなので、mongooseというかTypeScriptがムズイのかもしれません。

# とりあえずユーザーモデル作る
d.ts読み込み等は省略してあります。

```ts
import mongoose = require('mongoose');

//スキーマ作る
var userSchema:mongoose.Schema = new mongoose.Schema({name:String, age:Number});
//モデル作る
var userModel:mongoose.Model<mongoose.Document> = mongoose.model('User', userSchema);

//モデルのインスタンス作る
var user:mongoose.Document = new userModel({name:'orzngo', age:17});

```
注意する点は、mongoose.Model<T>をnewした結果はTであるという事です。これがよくわかんなくてかなり悩みました。
ただし、このままだとDocument型がそのまま返ってくる形になる為、ぼくがuserSchemaで定義したnameとageが取れません。

# Documentを拡張する
mongoose.Documentを継承したインターフェース、UserDocumentを定義しました。

```ts

interface UserDocument extends Document{
    name:String;
    age:Number;
}

```

これを参照出来るようにした上で、インポート等でコードを少し見やすくした物が以下になります。

```ts

import mongoose = require('mongoose');
import Schema = mongoose.Schema;
import Document = mongoose.Document;
import Model = mongoose.Model;

//スキーマ定義する
var userSchema:Schema = new Schema({name:String, age:Number});
 
//モデル作る
var userModel:Model<UserDocument> =  <Model<UserDocument>>mongoose.model('User', userSchema);

//モデルからドキュメントを作る
var user:UserDocument = new userModel({name:'ORZNGO', age:17});

console.log(user.name);//ORZNGO

```

やっとこさコンパイルが通りました。interfaceが読めてれば、きちんと補完もしてくれます。
![スクリーンショット 2014-09-05 22.11.13.png](https://qiita-image-store.s3.amazonaws.com/0/40020/d35adea8-b005-e3fd-099e-3ddd3d1587b3.png)


# ひとまずできた
とりあえず独自モデルを定義する所までようやくこぎ着けました。１週間くらいかかったかもしれません。
初めてQiitaに記事を書いたのですが、これからも勉強の為にいろいろ書いていこうと思います。

# 追記１
mongooseをやっつけたと思ったら、sequelizeでも同じような事をしています。
http://qiita.com/orzngo/items/186d700de481cc23c055
rbenvで複数のバージョンのRubyを管理する


## はじめに

rbenvで複数のバージョンのRubyを管理する方法を記述します。
なお、Rubyのインストールには、ruby-buildを使用します。

## 環境

* CentOS 6.5
* git 1.7.1

## gitのインストール

```shell
$ sudo yum install git
```

## rbenvのインストール

```shell
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
$ type rbenv
rbenv is a function
rbenv ()
{
...(省略)...
}
```

## ruby-buildのインストール

推奨されているとおりにrbenvのプラグインとしてインストールします。

pluginsディレクトリが存在しないため、gitからcloneする際に
ディレクトリも作成します。

```shell
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ rbenv install --version
ruby-build 20140702-16-g85369d2

```

## rubyのインストール

* 必要なパッケージのインストール

```shell
$ sudo yum install gcc openssl-devel
```

__2.0.0-p481__ では、 __openssl-devel__ が必要となります。

* インストール可能なRubyのバージョンを確認します。

```shell
$ rbenv install --list
Available versions:
  1.8.6-p383
  1.8.6-p420
  1.8.7-p249
...(省略)...
```

* 1.8.6-p420をインストール

```shell
$ rbenv install 1.8.6-p420
$ rbenv versions
  1.8.6-p420
```

* 1.9.3-p547をインストール

```shell
$ rbenv install 1.9.3-p547
$ rbenv --versions
  1.8.6-p420
  1.9.3-p547
```

* 2.0.0-p481をインストール

```shell
$ rbenv install 2.0.0-p481
$ rbenv versions
  1.8.6-p420
  1.9.3-p547
  2.0.0-p481
```
* 2.1.2をインストール

```shell
$ rbenv install 2.1.2
$ rbenv versions
  1.8.6-p420
  1.9.3-p547
  2.0.0-p481
  2.1.2
```

## バージョンの切替

* デフォルトのバージョンを2.1.2とする

```shell
$ rbenv global 2.1.2
$ rbenv version
2.1.2 (set by ~/.rbenv/version)
$ rbenv versions
  1.8.6-p420
  1.9.3-p547
  2.0.0-p481
* 2.1.2 (set by ~/.rbenv/version)
$ ruby --version
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]
```

* 2.0.0-p481を利用する

```shell
$ mkdir -p ~/src/ruby/2.0.0
$ cd src/ruby/2.0.0
$ rbenv local 2.0.0-p481
$ rbenv version
2.0.0-p481 (set by ~/src/ruby/2.0.0/.ruby-version)
$ ruby --version
```

* 1.9.3-p547を利用する

```shell
$ mkdir -p ~/src/ruby/1.9.3
$ cd ~/src/ruby/1.9.3
$ rbenv local 1.9.3-p547
$ rbenv version
1.9.3-p547 (set by ~/src/ruby/1.9.3/.ruby-version)
$ ruby --version
ruby 1.9.3p547 (2014-05-14 revision 45962) [x86_64-linux]

```

## 参考

*[rbenv](https://github.com/sstephenson/rbenv)
*[ruby-build](https://github.com/sstephenson/ruby-build#readme)
*[rbenv を利用した Ruby 環境の構築](http://dev.classmethod.jp/server-side/language/build-ruby-environment-by-rbenv/)
*[Ruby 2.1.0 以降のセマンティックバージョニングについて](https://www.ruby-lang.org/ja/news/2013/12/21/ruby-version-policy-changes-with-2-1-0/)
CakePHP2 Paginatorコンポーネント用いてvirtualFieldで定義したjoin先テーブルのカラムでソートをする方法。

少しはまったので、忘れない為のメモとして投稿。
paginatorコンポーネントを使用した一覧ページにて、virtualFieldで定義したjoin先のテーブルの
カラムでソートをする際の記述方法。

###Controller
Model1にModel2をjoinしてModel1.idでGROUP BYし、Model1に紐づくjoin先のテーブルのidをカウントする記述。
`$this->paginate('Model1')`を行う前に前にバーチャルフィールドを定義する。

```php:Model1sController.php
// join先のテーブルのカラムをcountするvirtualField
$this->Model1->virtualFields['model2VFColumnName'] = 'count(distinct Model2.model1_id)';

// paginate
$this->paginate = array('Model1' => array(
    'fields' => array(
        'id',
        'title',
        'model2VFColumnName',
    ),
    'joins' => array(
        'table' => 'model2s',
        'alias' => 'Model2',
        'type' => 'left',
        'conditions' =>
        'Model1.id = Model2.model1_id'
    ),
    'conditions' => array(
        is_delete = 0,
    ),
    'limit'=>100,
    'group' => array('Model1.id'),
    'order' => array('Model1.id' => 'desc'),
);

$model1Data = $this->paginate('Model1');
```

###View
View側ではコントローラー側で定義したvirtualField名を記述する。

```php:Model1sController.php
$this->paginator->sort('model2VFColumnName', '項目名');
```

以上で、virtualFiledで定義したjoin先のカラムで並び替えができる。
下記に調査の際に読んだPaginatorComponent.php内の仕組みをメモ。



###PaginatorComponent.php
paginateメソッド内で呼び出されているvalidateSortメソッド397行目辺り
並び替えに必要なorderをセットする処理

```php:lib/Cake/Controller/Component/PaginatorComponent.php
if ($correctAlias && $object->lib/Cake/Controller/Component/PaginatorComponent.php) {
    $order[$object->alias . '.' . $field] = $value;
} elseif ($correctAlias && $object->hasField($key, true)) {
    $order[$field] = $value;
} elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field, true)) {
    $order[$alias . '.' . $field] = $value;
}
```

上記コードの最初の条件文で`hasField($field)`で呼び出し元モデルのテーブルに、
並び替え対象のカラムが存在するかどうかチェックしている。今回のケースはjoin先のテーブルでのソートなので、この条件分には入らない。

次の条件文では`hasField($field, true)`となっており、第2引数にtrueがセットされているのでvitrualFieldも含めてカラムが存在するかを確認している。

paginateをコントローラーで呼び出す前にvirtualFieldを定義する事でこの条件分に入りViewで定義する`$this->paginator->sort('model2VFColumnName')`で生成されるリンクをクリックした際に渡るカラム名`model2VFColumnName`が並び替えの対象となる。
自社フレームワークで開発していますという案件を地雷と思ういくつかの理由

# 自社フレームワークで開発していますという案件を地雷と思ういくつかの理由

* これまでに4社ほど経験した

## 前書き

* すでにOSSとして公開済み、OSSとして公開されたF/Wの作者がいる、招聘したというケースは対象外です

## 作っているヒトたち

* OSSなF/Wのソコードリーディングなんてしたことがない
 * 偏見かも知れないがマジメにOSSのF/Wを採択する人間の方がちゃんと読んでいる
* OSSなF/Wをちゃんと使ったことがない様に見える
 * 大体がF/Wというよりは中途半端なアプリケーションや残念ライブラリとなっている
* F/WとアプリケーションのグルーツールやF/Wのプラグインすら作ったことがない
 * この辺の知見があるヒトは上記に当たるわけないし、まずはここから

## 解決策

* まずは無料のOSSなF/Wをいくつかピックアップする
* とりあえず触って、コードを読む
* 自分たちだけで修正/拡張が出来そうなものを優先して選ぶ

## OSSなF/Wを使うメリット

### F/Wの価値は使う人間、コミッタの数、修正ペース、そしてコミュニティの活発さにある

* [CPANソムリエになる方法](http://blog.64p.org/entry/20080520/1211292598)
 * この記事はそのまま選ぶべきF/Wの指針となると思っている
* 補足
 * 新規にヒトを雇い入れる際に使ったことがあれば、学習コストが比較的安く済む
 * コミッタやバグ報告する人間には雇うには高価なくらいに優秀な人間が多い
 * さらにそういった人間がデバッグまでした上でリリースノートまで書いてくれる
 * コワいヒトたちがマサカリ投げまくった後だったりするので比較的キレイだったりする

### ところが自社F/Wだと

* 入ってからでなければ教育が出来ない
* 何か問題が発生した際に自分たちで(限られた時間内に)全て解決しなければならない
* 開発に携わった人間がいつまでもいるとは限らない
* ドキュメントが社内だけに向けたもので貧相だったりする
* 使う人間よりは出来る人間が書いているという誤解の元でクソースがままある
* 作者が行方不明で使い方もすでに分からないというケースがままある
* なぜ、OSSとして公開出来ないのか？ということを改めて考えてみるべき
 * 業務のクリティカルな情報はF/Wに依存すべきではない
 * 公開して恥ずかしくないものを作っていれば自ずと公開しましょうと言うはず

### F/Wとは簡単な制約であるべき

* ex. 六本木から渋谷に行って下さい
 * 無数の経路が存在する
 * 誰かが落とし物をした際にどうやって見つけるか？
* 簡単な制約
 * 恵比寿から渋谷までは山手線を使って下さい
* 誰かが落とし物をした
 * 山手線に問い合わせをすれば見つかる可能性が少しは上がる
* 何のたとえ？
 * プログラムのエンドポイントを探すことに似ていると思っている
 * 問い合わせ場所が分かる(ロギング)が明白であるということは強み

### 結論

* とりあえず、最初はOSSなF/Wから始めよう
* パフォーマンスの問題を解決できない場合は軽いF/Wを探そう
* どうしても見つからなければ、F/Wの機能削減を検討しよう
* ここまですれば自家製する前にF/Wのソースを読むということは完了している
* 作るなら期限を決めてOSSとして公開しよう

### 最後に

* エンジニア名乗るならF/Wの一つや二つ作ったことがあって当然
* だけど、仕事でするなって昔偉いヒトに言われた
githubでClone後にMasterの更新を反映する方法

Githubは更新のConflictが起こらないように気を付ける必要があり、githubでCloneしたレポジトリをMasterにちゃんと追従する方法を記載します。Oraganaizationを使用してますが、基本的に操作は一緒です。

クライアント
-------------

Origin/Masterでは通常通り「add」「commit」「push」をします。

```
[user@localhost app]$ git add README.md
[user@localhost app]$ git commit -m "modify api tree => table"
[master d4774c3] modify api tree => table
 1 files changed, 27 insertions(+), 42 deletions(-)
```

```
[user@localhost app]$ git push -u origin master
Enter passphrase for key '/home/user/.ssh/github_organaize':
Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 605 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)
To git@github-organaize:Organaization/repo.git
   8824155..d4774c3  master -> master
Branch master set up to track remote branch master from origin.
```

サーバ
------------
pushした内容をサーバにCloneします。この環境では./ssh/configを使用してますので、適宜変更してください。

```
git clone git@github-organaize:Organaization/repo.git
```

このサーバ側はoriginではなく「upstream」として登録します。

```
[server@localhost app]$ git remote add upstream git@github-organaize:Organaization/repo.git
```

あとはfetchとmergeをして完了です。Masterの変更点が反映されていることを確認してください。
fetch後に「git branch -a」で確認するとupstream/masterが追記されていました。

```
[server@localhost app]$ git fetch upstream
remote: Counting objects: 9, done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 9 (delta 5), reused 6 (delta 2)
Unpacking objects: 100% (9/9), done.
From github-organaize:Organaization/repo
   10f1940..d4774c3  master     -> upstream/master
   
[server@localhost app]$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/upstream/master
```

git branch -aで問題なく追加されているようであれば、そのままmergeしてください。
   
```
[server@localhost app]$ git merge upstream/master
Updating 10f1940..d4774c3
Fast-forward
 README.md |   71 +++++++++++++++++++++---------------------------------------
 1 files changed, 25 insertions(+), 46 deletions(-)
```

以上、簡単ですが方法だけメモしておきます。
変数の作成方法

基礎から書く。

# 基本

```js
var name;
```

# 複数個作成する

```js
var name;
var age;
```

こうも書ける

```js
var name, age;
```

# アタイも一緒に
```js
var name = 'Akane';
```

## 複数個ではこう書くことも
```js
var name = 'Akane',
    nickname = 'Akaino';
```
よく喧嘩が起こる。
vim-plugin NERDTree で開発効率をアップする！

# vim-plugin NERDTreeで開発効率をアップする！

## NERDTreeとは

vimのプラグインで、vimを開きながらディレクトリをツリー表示することができ、ファイルにvimを開きながらアクセスができます。

## 導入方法

1.　まずはvimのプラグイン管理ツール「NEOBUNDLE」を導入します。

導入の本家サイトリンクはこちら（[NEOBUNDLE][1]）

```bash
$ curl https://raw.githubusercontent.com/Shougo/neobundle.vim/master/bin/install.sh | sh
```

このコマンドを叩くだけでNEOBUNDLEがインストールされます。
※MacとLinuxのみになります。

2.　~/.vimrcに以下のコードを書きます。

```bash:~/.vimrc
set nocompatible
filetype off

if has('vim_starting')
    set runtimepath+=~/.vim/bundle/neobundle.vim
    call neobundle#rc(expand('~/.vim/bundle/'))
endif

"insert here your Neobundle plugins"
NeoBundle 'scrooloose/nerdtree'

filetype plugin indent on
```

ちなみにNERDTreeのBundleは

```bash
NeoBundle 'scrooloose/nerdtree'
```

になります。

3.　Bundleのインストール

.vimrcを保存して再度vimを開き、vimの中で下記のコマンドを実行します。

```bash
:NeoBundleInstall
```

これにより、先ほど指定したBundleがインストールされ、無事にNERDTreeが入りました。

4.　NERDTreeの設定

特に設定等は必要ありまん。
しかし、NERDTreeを起動するには、vimを開いて

```bash
:NERDTreeToggle
```

と打たなければいけないので、自分は.vimrcにショートカット（キーマップ）を書いてます。

```bash:~/.vimrc
nnoremap <silent><C-e> :NERDTreeToggle<CR>
```

これにより、vim上でCtrl+eでNERDTreeを開くことができます。

## NERDTreeの使い方

### ファイル操作系

| コマンド| 説明 |
|:-----------|:------------|
|o(enter)|ファイルを開く|
|go|ファイルを開き、カーソルはツリーに保持する|
|t|タブで開く|
|T|タブで開き、移動はしない|
|i|水平分割して開く|
|gi|水平分割して開き、移動はしない|
|s|垂直分割して開く|
|gs|垂直分割して開き、移動はしない|

### ディレクトリ操作系

| コマンド| 説明 |
|:-----------|:------------|
|o(enter)|フォルダを開く|
|O|再帰的にディレクトリをすべて開く|
|x|親ディレクトリを閉じる|
|X|再帰的にすべての子ディレクトリを閉じる|
|e|新しいツリーを生成する|

### ツリー操作系

| コマンド| 説明 |
|:-----------|:------------|
|P|ルートディレクトリへ移動|
|p|親ディレクトリへ移動|
|K|一番上へ移動|
|J|一番下へ移動|
|Ctrl+k|一つ上へ移動|
|Ctrl+j|一つ下へ移動|

### ファイルシステム系

| コマンド| 説明 |
|:-----------|:------------|
|C|ツリーのルートを選択したディレクトリに変更|
|u|ツリーのルートを上の階層にする|
|U|変更前のツリーの状態を保持して、ツリーのルートを上の階層にする|
|r|選択したディレクトリをリフレッシュする|
|R|ツリーのルートをリフレッシュする|
|m|メニューを表示する|
|cd|選択したディレクトリにcwdを変更する|
|CD|cwdをツリールートに変更する|

※mでファイルやディレクトリの追加・削除・コピー・移動ができる

### その他

| コマンド| 説明 |
|:-----------|:------------|
|I|隠しファイルの表示、非表示|
|B|ブックマークの表示・非表示|
|F|ファイルの表示・非表示|

これで簡単なファイル操作とかをわざわざbashに戻さなくても編集できますし、なにしろvimだけでいろいろできるのが超便利！

以上がNERDTreeの説明でした。
快適はvim生活を！

[1]:https://github.com/Shougo/neobundle.vim
1つのファイルで bash と php のコード実行する

なんの役に立つのかわからないし（きっとなんの役にも立たない）、そもそもこの動作が保証されているかどうかも知りませんが。

次のようなファイルを用意します。

```sh:a.sh.php
echo "I am bash $BASH_VERSION"
exec php
<?php
echo "I am php " . PHP_VERSION . PHP_EOL;
```

次のように実行します。

```console
cat a.sh.php | bash
```

ファイルの前半部分は bash で、`exec php` 以降は php で実行されます。

```text:output
I am bash 4.1.2(1)-release
I am php 5.5.16
```

strace した感じ、bash にパイプでスクリプトを流し込むと１文字ずつ read して改行が来たところで実行するようです。なので `exec php` のところまで標準入力を読んだあとに php に切り替わって、それ以降の標準入力は php で実行されます。
【PhotoshopCC】GIFアニメーションの作り方

PhotoshopCCを使ったGIFアニメーションの作り方です。

【読了時間5分】

# STEP1
PhothoshoCCを開いて、［ウィンドウ］→［タイムライン］を表示します。
![step1](https://qiita-image-store.s3.amazonaws.com/0/50668/c8c94bec-603e-fff4-e968-0073ba827f6b.png)

タイムラインの［フレームアニメーションを作成］をクリック
![step1](https://qiita-image-store.s3.amazonaws.com/0/50668/a76dbd41-b85c-a916-cbb4-37b2159c5486.png)

1コマ目が作成されます
![step1](https://qiita-image-store.s3.amazonaws.com/0/50668/f13d50b7-50f0-da43-c50a-b096affb8140.png)


# STEP2

1コマ目に表示したい状態を作成したら、2コマ目用にレイヤーを複製します。
![step2](https://qiita-image-store.s3.amazonaws.com/0/50668/2672deff-c518-b434-c7e8-b8c0cbf17c0e.png)

フレームも複製し（※黄色「現在のフレームを複製」をクリック）、２コマ目に表示したい状態を作成します。
![step2](https://qiita-image-store.s3.amazonaws.com/0/50668/adaf0f8d-ce43-8fb0-3de1-69cb8f02bc50.png)


その後は同様に複製を繰り返し、アニメーションになるようオブジェクトを動かしていきます。
※今回はグループでコマ割りをしているので、選択しているコマと同じ名前が付いたグループしか表示していません。
![step2](https://qiita-image-store.s3.amazonaws.com/0/50668/e2253240-fde0-dcb1-55fa-c58e5bb27284.png)


# STEP3

最後に、動きを見ながらコマの秒数や動作方法を設定。
![step3](https://qiita-image-store.s3.amazonaws.com/0/50668/7b84ae3b-fda5-d061-af42-637bb11375e7.png)

[ファイル]→[Web用に保存]でGIF形式で保存。
![step3](https://qiita-image-store.s3.amazonaws.com/0/50668/363ab60a-9e81-ccde-91a7-1890a48c066b.png)

	
GIFアニメーションの完成です！
![Gif_post.gif](https://qiita-image-store.s3.amazonaws.com/0/50668/b985cfef-1274-e18c-b8ab-df371a177891.gif)
GoogleAnalytics イベントトラッキングの設定 (ユニバーサルアナリティクス向け)

* 外部サイトへのリンクや、pdfのダウンロードボタンのクリック数を計測したいとき、ソースコードにイベントトラッキングというタグを埋め込む必要があります。その手順についてまとめました。

## 手順
### :large_orange_diamond: Step1
* 計測したいタグをソースコードから探しましょう。ここでは例として、「http://example.com/」 という外部サイトへリンクする以下のaタグを使用します。

```html
<a href="http://example.com/" target="_blank">サンプルページへ飛びます</a>
```

### :large_orange_diamond: Step2
* 以下のonclickタグをaタグ内に記述します。

```js
onclick="ga('send', 'event', 'カテゴリ', 'アクション', 'ラベル', 値);"
```

* 「send」「event」はそのまま文字通り指定すればOKです。
* 「カテゴリ」「アクション」は必須で、「ラベル」「値」は任意で指定します。各項目の説明は以下の表にまとめました。

| 項目 | 内容 | 入力例 |
|:----------:|:--------:|:-----------:|
| カテゴリ(必須) | 計測したい対象物 | link, pdf |
| アクション(必須) | 計測したいユーザの操作 | click, download |
| ラベル(任意) | 固有の名前(リンク先の名前, pdf資料名など) | www.example.com, サンプルpdf |
| 値(任意) | 指標にする数値 | 100 |

* ラベルには、「www.example.com」や「サンプルページ」、などリンク先の内容を入れると良いと思います。
* 値には、計測データの指標値を指定したい場合に記述します。例えば、1クリック＝100円とカウントしたいときは、100を指定すればOKです。

### :large_orange_diamond: Step3
* 以下はタグ設置後の例です。サーバに反映させたら完了です！

```html
<a href="http://example.com/" onclick="ga('send', 'event', 'link', 'click', 'サンプルページ');">サンプルページへ飛びます</a>
```

## おまけ：タグ設置後の確認
* GoogleAnalyticsを開き、左メニューの ①行動 > ②イベント > ③サマリーから確認できます。
* ページ下にある「上位のイベント」では、Step2で指定した項目ごとにデータを確認できます。
* **【注意】タグ設置後、テストでクリックしてもすぐにはデータは取れないかもしれません･･･私は1時間後ぐらいにデータがとれました！**

![140905-0007.jpg](https://qiita-image-store.s3.amazonaws.com/0/49675/b6012ead-2b39-20ac-a83c-e6f011ad4b27.jpeg "140905-0007.jpg")
Riak 2.0.0 へアップグレードする際の注意点


自分の為に纏めた。
公式なものは[Upgrading to 2.0](http://docs.basho.com/riak/2.0.0/upgrade-v20/)に公式ドキュメントが在る。


## クライアント

Riak2.0と通信する為には2.0に対応したBashoの公式なクライアントを使うのが良いとのこと。

* [Java](https://github.com/basho/riak-java-client)
* [Ruby](https://github.com/basho/riak-ruby-client)
* [Python](https://github.com/basho/riak-python-client)
* [Erlang](https://github.com/basho/riak-erlang-client)

これらの最新版を使えば```data types```や```新しいRiak Search```のような機能が使えるよって。

## Bucket Types

1.4系以前のRiakではデータの位置は```bucket```と```key```で決まってて、```bucket properties```でそれらに関する設定が行われてた。
Riak2.0から追加された```bucket type```はデータの位置を示す追加のネームスペースであり、同時によりシステマティックな設定方法を提供する...という訳でいいんだろうか。

要するに2.0より前のものでは

```
/buckets/<bucket>/keys/<key>
```

という指定だったのが、

```
/types/<type>/buckets/<bucket>/keys/<key>
```

というような指定になる。
同時に、```type```に対してプロパティを設定すると、そこに属するbucket全てに反映されるので効率的に管理できるよって。

ちなみに、古いクライアントを使ったりして2.0より前の```/buckets/<bucket>/keys/<key>```という形式で指定した場合、それはbucket typeに```default```を指定したことになるらしい。
つまり

```
/buckets/<bucket>/keys/<key>
```
は

```
/types/default/buckets/<bucket>/keys/<key>
```
と同じ事ってこと。

あとRiak2.0にアップグレードしてbucket typeを使い始めたら、それ<b>以前のバージョンにダウングレードはできない</b>との事。

## allow_multiのデフォルトがtrueに

2.0より前のRiakではallow_multiの初期値はfalseだったけど、2.0からtrueになったよって。
全ての```bucket type```でデフォルトの```allow_multi```の設定値は```true```になる。

では```allow_multi```が```false```のbucketを使いたい場合はどうすれば良いのか。
方法は２つ。

* bucket typeの```allow_multi```を```false```に設定する。
* bucket typeを使わない。 

```allow_multi```を ```true```にした場合、Siblingsでのコンフリクトなんかの問題がでるけど、それらについては[Conflict Resolution](http://docs.basho.com/riak/latest/dev/using/conflict-resolution/)にドキュメントがあるよって。


## セキュリティ

Riak2.0のセキュリティを有効にする前に、テスト環境で十分にテストしろよって言ってる。
特にセキュリティを有効にすると(```riak-admin security enable```)、```Link Warking```や、古い(Yokozuna採用前の)```Riak Search```などの機能は使えなくなるから注意が必要とのこと。
[Authentication and Authorization](http://docs.basho.com/riak/latest/ops/running/authz/)


## ダウングレード

Riak 2.0を使い始めてもまだ、以下のいずれも行っていない段階では2.0より古いバージョンに戻す事ができる。

* Riak Searchのためのインデックスの使用。
* １つ以上のbucket typeの作成または有効化。これはつまり、Riak2.0の新しい機能である以下の２つのいずれかを利用した場合、必然的に2.0より前にダウングレードする事ができなくなる事を意味する。
    * Strong consistency
    * Riak Data Types

それ以外の新機能、例えば```Riak Security```や新しい設定ファイルなどを使っている段階では、まだ2.0より前のバージョンへのダウングレードは可能。

## 設定

Riak2.0からは新しい設定システムが採用されてる。
```riak.conf```は今まで```app.config```と```vm.args```に書いていた内容を新しいシンタックスで記述するファイル。
ちなみに設定に関する詳細は[Configuration Files](http://docs.basho.com/riak/2.0.0/ops/advanced/configs/configuration-files/)にある。

なお、Riak 2.0をつかう場合に、設定には２つの選択肢が在る。

* 手動で新しいRiak 2.0に設定を移す（この場合は```riak.conf```を使う事になる)。
* 古い形式の設定ファイルをそのまま使う。Riak 2.0ではまだ古い形式の設定ファイルが使える(この場合は```advanced.conf```を使う事になる)。

## Searchのアップグレード

2.0より古いバージョンのRiakを使っている場合はSearchのインデックスを新しいSearchのインデックスへ移行しないといけない。詳しい方法は[Upgrading Search from 1.x to 2.x
](http://docs.basho.com/riak/latest/ops/advanced/upgrading-search-2/)にドキュメントがある。
アプリが実機に入らないときの対処法

アプリが完成していざ実機に入れようとするとき、うまくいかないときの対処法

##パスコードを設定している

Could not launch "アプリ名"
process launch failed: Locked
(または Unlock the device "自分の名前" and then launch "アプリ名" again.)
![スクリーンショット 2014-09-05 13.10.12.png](https://qiita-image-store.s3.amazonaws.com/0/48286/60fe0612-7941-bd9d-b543-5c24fdebec43.png)

###解決方法
パスコードが設定されているので、解除してからもう１回実行します。

##機能制限がかかってる
Installation of apps is prohibited by a policy on the device.

![スクリーンショット 2014-09-05 14.16.12.png](https://qiita-image-store.s3.amazonaws.com/0/48286/be4713b1-f0b1-6106-6967-5fea6ccb36c6.png)

###解決方法
機能制限の制限を解除してからもう１度実行します。

##実機のバージョンが古い
![スクリーンショット 2014-09-05 14.23.27.png](https://qiita-image-store.s3.amazonaws.com/0/48286/bf0bc48b-eaae-9028-1c81-17bcb8fe476b.png)

beta版とかがでたときに、xcodeのバージョンだけあげて作ってるアプリはiOS8.0向けなのに実機はiOS7.1になっているとか。

OrganizerのDevicesではちゃんと緑のマークもついて実機に入れられるはずなのに、下のようにiOS Deviceのままで自分の実機が選択できないとき。
![スクリーンショット 2014-09-05 14.39.37.png](https://qiita-image-store.s3.amazonaws.com/0/48286/b692a20a-e102-a6f7-3a04-cec2b23a67d8.png)

![スクリーンショット 2014-09-05 14.39.53.png](https://qiita-image-store.s3.amazonaws.com/0/48286/2c0300d8-9c97-fc70-d0ac-d2921dde37a7.png)


###解決方法

![スクリーンショット 2014-09-05 14.32.10.png](https://qiita-image-store.s3.amazonaws.com/0/48286/b7354c67-18ca-1719-db5a-1370732c8a90.png)

上のようにBuild SettingsのDeploymentにiOS Deployment Targetのバージョンを自分の実機のバージョンに変えます。
Knockout.js ObservableArray を部分的に更新

数時間ハマったのでメモ。
observableArray で複雑なオブジェクトを含む配列を渡した時、
オブジェクトのプロパティを部分的に更新する。

```:html
<!-- ko foreach: myItems -->
    <li>アイテム <span data-bind="text: $data.value"></span></li>
<!-- /ko -->
```

```:javascript
var items = [
        {value: 'a'},
        {value: 'b'},
        {value: 'c'}
    ];

var bindObj = {
        myItems: ko.observableArray(items)
    };

ko.applyBindings(bindObj);

var ob = bindObj.myItems;
var idx = 1;

// 新しいオブジェクトだと更新される
// ob.splice(idx, 1, {value: 'b updated'});

var b = items[idx];

b.value = 'b updated';

// 同じオブジェクトだと更新されない
// ob.splice(idx, 1, b);

// しかたないからディープコピー
ob.splice(idx, 1, $.extend(true, {}, b));
```

同じオブジェクトのプロパティを書き換えて `splice` しても、値が更新されなかった。
しかたないので、ディープコピーしてから更新。
コピーには今回 `jQuery.extend` を使用。
DelayedJob に ActiveRecord インスタンスを渡す時の注意


# 結論
ハマったら .as_json で渡しましょう。
*** ActiveJob は GlobalID に対応しているので以下の心配は不要です**

# 理由
```ruby:user.rb
class User < ActiveRecord::Base
  before_save :notify

  def before_save
    Notifier.delay.push(self)
  end
end
```

これは期待通りに動かない (ことがある)。
delay は巧妙な構文で仕組みを隠蔽しているが、実際に内部で起きていることは 'Notifier' と 'push' と 'self' を全部ひとまとめにした yaml 文字列を作って Delayed::Job のインスタンスを生成しているだけだ。
分かりやすく書けばこんな感じ。

```ruby
Delayed::Job.new(PerformableMethod.new(Notifier, :push, [self]))
```

PerformableMethod は渡された3つのパラメタを纏めて1つのyaml文字列を生成する。これが delayed_jobs テーブルに保存される。
一方、別プロセスで動作している delayed_job デーモンは、このyaml文字列から元のオブジェクトを復元する。
これらの一連の変換は
https://github.com/collectiveidea/delayed_job/blob/master/lib/delayed/psych_ext.rb
に記述されている。

さて、save 前の ActiveRecord インスタンスはどのように delayed_job デーモンに渡るのか。実際に delayed_jobs テーブルの実行前のレコードを見てみると、各カラムの値が記録されているのがわかる。
しかし油断してはいけない。先ほどの psych_ext.rb の、 yaml からインスタンスを復元する部分のコードを確認してみよう。

```ruby:psych_ext.rb
        case object.tag
        when /^!ruby\/ActiveRecord:(.+)$/
          klass = resolve_class(Regexp.last_match[1])
          payload = Hash[*object.children.map { |c| accept c }]
          id = payload['attributes'][klass.primary_key]
          begin
            klass.unscoped.find(id)
          rescue ActiveRecord::RecordNotFound => error
            raise Delayed::DeserializationError, "ActiveRecord::RecordNotFound, class: #{klass}, primary key: #{id} (#{error.message})"
          end
```

この通り、 ```klass.unscoped.find(id)``` となっていて、 **idしか見ていない** ことがわかる。
user が new インスタンスで id が振られてなければ、 RecordNotFound になってしまう。
あるいは id を既に持っていても、この job が実行される時点でもしまだレコードが保存されてなければ、 notify メソッドは保存前のレコードの内容で実行されることになる。
あるいは、 delayed_job の実行が十分に遅れて、その間に DB の内容が変わっていたら、最新のデータで notify が呼ばれることになる。

レシーバが ActiveRecord インスタンスの場合も同様の問題が起きる。

```ruby
def before_save
  self.delay.notify
end
```

せっかく全カラムの情報渡してるんだから、その通りに復元してくれればいいのにと思いました。

# 余談
DelayedJob 公式には、 Delayed::Job レコードの id を取得する方法が用意されてないので実行結果の追跡が困難なのだが、実は

```ruby
job = Notifier.delay.push(self)
```
とすると Delayed::Job インスタンスが取得できるので ```job.id``` で id が簡単に取れる。
最新のIEへアップデートしてもらうように説得する。

ケースバイケースですけど。

---

最近、「壊れるまで使って、壊れたら買い替える」というのが、一般的な考え方なのだなと気付いた。
なので、古いIEで見た際にレイアウトがガタガタに崩れるサイトがあった際に、
 


「あぁ、だいぶ古くなったのでIE壊れちゃいましたねー。保証期間も過ぎているので同じものはもう手に入りませんが、今なら、最新のIEがタダで貰えるので、それに変えましょう」


と言うとわりと通るということが分かった。
重要なのは、「壊れた」「今なら」「タダで」この三つの単語。
cocos2d-xのtouchイベント内でtoastを表示したいとき。


# 概要

メニューをタップ等したときに、例えば通信状態がよくない場合にエラーメッセージを出したいことがあると思いますが、JNI経由でToastを呼び出すと思わぬエラーが発生することがあります。
そういったときの対処方法のひとつを記載します。

## 環境

cocos2d-x(2.2.4)

## 原因

cocos2d-xのtouchイベントはGLThread内で処理されますが、Toastクラスは初期化時に内部でHandlerクラスの引数なしの初期化が行われており、この際に例外が送出されます。
例外が発生する該当箇所を見てみると、

```java:Handler.java
public Handler(Callback callback, boolean async) {
        if (FIND_POTENTIAL_LEAKS) {
            final Class<? extends Handler> klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }

        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }
```

GLThread内でLooper.prepareがコールされていないようです。

## 対処方法
ここでは、Toastクラスの初期化がUIスレッド(mainスレッド）内で行われれば問題が発生しなさそうだということで、次のように記述してみました。

```java
 //jni経由でコールされるメソッド
 Handler handler = new Handler(Looper.getMainLooper());
 handler.post(new Runnable(){
   public void run(){
     Toast toast = new Toast(…
     …
     toast.show();
   }
 });
```

かなり省略した感じですけどニュアンスは伝わると思います。
結局のところToastに限らず、touchイベント内でHandlerクラスを生成するケースがあれば全て同じ処理をする必要があります。
Ubuntu 14.04 に Oracle Java をインスールする

旧Sun Java （現 Oracle Java）を Ubuntuにインストールする方法の備忘録。標準のリポジトリでは提供されていないため、PPA(Personal Package Archive)からインストールする。

 * https://launchpad.net/ubuntu/+ppas

### インストール方法

インストールはこれだけ。

```shell-session
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java7-installer
```

Java7 の他に、Java6, Java8 も提供されている。詳細は、

 * https://launchpad.net/~webupd8team/+archive/ubuntu/java

を参照のこと。

### バージョン
投稿時点でのバージョンは以下の通り。

```shell-session
$ java -version
java version "1.7.0_67"
Java(TM) SE Runtime Environment (build 1.7.0_67-b01)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)
```

他のJavaが入っていたりする場合は、update-java-alternatives コマンドで切り替える必要があるかもしれない。

### JAVA_HOME
JAVA_HOMEを設定するには、以下のパッケージをインストール後、再度ログインすれば設定されている。

```shell-session
$ sudo apt-get install oracle-java7-set-default

...再ログイン...

$ echo $JAVA_HOME
/usr/lib/jvm/java-7-oracle
```

以上
Git push エラー (error: RPC failed; result=55, HTTP code = 0)の対処


https で remote 設定している 外部 Git ホスティングサービス への push にて上記エラーになりました。
コミットに画像ファイルをいくつか入れていたのでコミットサイズが比較的大きいコミットが含まれている場合
に頻繁にエラーになります。
(下記は、Windows 上 の SourceTree 上で実行したpush時のエラーメッセージです)

# エラー
```
error: RPC failed; result=55, HTTP code = 0
```

# 詳細

```
git -c diff.mnemonicprefix=false -c core.quotepath=false push -v --tags origin master:master
POST git-receive-pack (chunked)

fatal: The remote end hung up unexpectedly
fatal: The remote end hung up unexpectedly

error: RPC failed; result=55, HTTP code = 0
```

ググると、httpを使うと良いとか、sshを使えばよいかもとかいろいろ情報がありました。

ひとまず、下記でOKでした。

# 対策

```
git config http.postBuffer 52428000
```

ちなみに、 git config http.postBuffer 524288000 では同じ現象で回避できませんでした。うむ。

```
git config --global http.postBuffer 52428000
```
なお、global オプションにてリポジトリ全体に適用しておくと良いかもしれません。
kernelが更新されてvboxfsが使えなくなることの対策

```bash:
vagrant up
```

> ==> default: Mounting shared folders...

で先に進まない・・・
ログインして確認すると、`vbox*`のモジュールを読み込まれていない。

```diff:/etc/yum.conf
+ exclude=kernel*
```

を先に設定してから`yum update`するとよい。
ofImage::drawが遅い問題


ofImageで画像を表示しようとした時に激遅い状態があるのでメモ。

おそらくoF内部で色々なプラットフォームに対応したり、レンダラを抽象化してたりする所のオーバーヘッドがつみかさなって重くなっている感じであったので、そのあたりを全部すっとばしてGLの関数群をそのまま呼ぶようにした奴

今となっては懐しいdisplaylist使用…。。。

```cpp
class SimplifiedImageDrawer
{
public:
	
	SimplifiedImageDrawer()
		: display_list(0)
		, tex(NULL)
	{}
	
	virtual ~SimplifiedImageDrawer()
	{
		deleteDisplayList();
	}
	
	void setTexture(ofTexture& tex)
	{
		this->tex = &tex;
		tex_size.set(tex.getWidth(), tex.getHeight());
		
		deleteDisplayList();
		
		display_list = glGenLists(1);
		glNewList(display_list, GL_COMPILE);
		{
			glBegin(GL_TRIANGLE_STRIP);
			{
				glTexCoord2f(0, 0);
				glVertex2f(0, 0);
				
				glTexCoord2f(tex_size.x, 0);
				glVertex2f(1, 0);
				
				glTexCoord2f(0, tex_size.y);
				glVertex2f(0, 1);
				
				glTexCoord2f(tex_size.x, tex_size.y);
				glVertex2f(1, 1);
			}
			glEnd();
		}
		glEndList();
	}
	
	inline void draw(float x, float y, float w, float h)
	{
		assert(display_list != 0);

		glPushMatrix();
		glTranslatef(x, y, 0);
		glScalef(w, h, 1);
		glCallList(display_list);
		glPopMatrix();
	}
	
	inline void bind()
	{
		tex->bind();
	}
	
	inline void unbind()
	{
		tex->unbind();
	}
	
protected:
	
	ofTexture *tex;
	ofVec2f tex_size;
	GLint display_list;
	
	void deleteDisplayList()
	{
		if (display_list)
			glDeleteLists(display_list, 1);
		display_list = 0;
	}
};
```

## 使う

要点のみ

```cpp
SimplifiedImageDrawer SID;
ofImage my_image;

void ofApp::setup()
{
	my_image.loadImage("test.png");
	SID.setTexture(my_image.getTextureReference()); // テクスチャをセット
}

void ofApp::draw()
{
	SID.bind(); // テクスチャをバインド
	SID.draw(0, 0, 100, 100); // 描画
	SID.draw(100, 0, 100, 100); // 描画
	SID.draw(0, 100, 100, 100); // 描画
	SID.unbind(); // テクスチャをアンバインド
}
```

上記の例では数回しか呼んでないのでうまみゼロですがこっちでやってみた感じ2万個ぐらいまでは余裕の60フレキープで動いてました。

bind/unbindをループの外に出してdrawメソッドの中でいちいち呼ばないようにしたら結構早くなった。コンテクストのスイッチにも結構時間がかかるもんなんですね…

[そういえばofxFontStashにも同じようなモードがありますね](https://github.com/armadillu/ofxFontStash/blob/master/src/ofxFontStash.h#L87-L91)
SQLite のカラムのタイプ


```
    public const u8 SQLITE_INTEGER = 1;
    public const u8 SQLITE_FLOAT = 2;
    public const u8 SQLITE_BLOB = 4;
    public const u8 SQLITE_NULL = 5;
    public const u8 SQLITE_TEXT = 3;
    public const u8 SQLITE3_TEXT = 3;
```
gitのブランチを切り替えたらpod install

チームでiOSアプリを開発している人たちはブランチ変更するたびに手動でpod installしていて、苛つくことがよくあるかと思います。そんな時にはgitのpost-checkoutフックを利用してブランチを切り替えるごとにpod installを実行するようにすると良いかと思います。


以下の設定を.git/hooks/以下のpost-checkoutファイルに書いてchmod +x post-checkoutしておけばブランチ切り替えごとにPodfileの更新があれば自動的にpod installするようになります。

```sh:/path/to/ios-project/.git/hooks/post-checkout
#!/bin/sh

# parse this format
# x3de1b0 HEAD@{0}: checkout: moving from xxxx to yyyyy
BEFORE_BRANCH=`git reflog | head -1 | cut -f 6 -d ' '`
AFTER_BRANCH=`git reflog | head -1 | cut -f 8 -d ' '`
DIFF=`git diff ${BEFORE_BRANCH} ${AFTER_BRANCH} --name-only | grep Podfile`

if [ -n "${DIFF}" ]; then
  bundle exec pod install
fi
```

便利
Rubyメモ

# Rubyメモ

Macとrbenvの場合。

## Rubyのアプリを最新のバージョンで動かす賢いやり方

```bash
brew update
brew install rbenv
echo 'if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi' >> ~/.bashrc
brew install ruby-build
brew install rbenv-gemset  # bundleでpathを指定してればいらない？
brew install rbenv-gem-rehash
brew install rbenv-binstubs
rbenv install 2.1.2
rbenv global 2.1.2
gem update
gem install bundler
bundle install --path=vendor --binstubs=vendor/bin
```

## Rubyやライブラリを根こそぎ最新にアップデート

```bash
brew doctor
brew update
brew upgrade rbenv
brew upgrade ruby-build
rbenv install --list
rbenv install 2.0.0-p481
rbenv install 2.1.2
rbenv versions
rbenv global 2.1.2
gem list
gem update
bundle show
cp Gemfile.lock Gemfile.lock.backup
bundle update
```

## Ruby環境の確認

```bash
gem env
bundle config
```

## 今の環境でどのbinやgemが使われてるか調べる

```bash
rbenv which pry
bundle show pry
```

## 参考

- https://github.com/sstephenson/rbenv/wiki/Plugins#approved-plugins
データベースにindexを張る方法

データの読み込み速度を改善する上で、indexを張ることは非常に大切です。
ただし、張り方や張る箇所によっては、目に見えた改善が見られなかったり、むしろ速度が遅くなってしまうケースもあります。

そこで、indexへの理解を深めるべくindexの基礎的な内容を記します。

##1.indexってなんぞや
特定のカラムからデータを取得する際に、テーブルの中の特定のカラムのデータを複製し検索が行いやすいようにしたものです。
例えば、あるユーザーをバイネームで検索したい！となった際に、Usersテーブルのnameカラムにインデックスを張ってないと、プログラムは、Userテーブルのnameカラムを上から順にみて、そのユーザーのデータを取得します。もし、これが1万人もしくはそれ以上の大量のデータを含むカラムだったらどうでしょう。すごく時間がかかりますね。
Usersテーブルのnameカラムにindexを張ることで、アルファベット順にnameを並べ替え検索しやすいようにしてくれます。

##2.indexのメリット・デメリット
1.でindexってすげー便利！じゃあ、全部のカラムに貼っちゃおう！と思ってしまいがちですが、もちろんメリットとデメリットがあります。

・メリット：データの読み込み・取得が早くなる。
・デメリット：書き込みの速度が倍かかる。

indexを貼り、カラムを検索しやすいように整理しデータの読み込み・取得が早くなる反面、そのカラムのデータを複製する処理が走るので、書き込みの速度に倍かかってしまいます。かつ、たいしたデータ量のやアクセスのないカラムに張っても、大した速度改善は見込めません。

なので、基本的にindexは、 
###ある程度多くのデータを格納するテーブルの、格納される値がそれぞれ異なるようなカラムの中で、検索がよく行われるカラム
に対して張ると効果的です。

##3.indexを張ってみる
``rails generate migration add_index_テーブル名_カラム名``をし、migrationファイルを作成します。

作成されたmigrationファイルの中身はこんな感じです。

```ruby:
class AddIndexToテーブル名 < ActiveRecord::Migration
  def change
    add_index :テーブル名, カラム名
  end
end
```
indexに複数のカラムを設定する場合は

```
add_index テーブル名, [:カラム名1, :カラム名2, ・・・]
```

と書けばオーケーです。

###オプション
:name - インデックスの名前
:unique	 - trueを指定するとユニークなインデックス
:length	 - インデックスに含まれるカラムの長さ

最後に``rake db:migrate``をお忘れなく。
今日のMarkdown

平日にMarkdownの投稿内容を更新します。
※ストックすると平日は通知が来ます。

社内啓蒙用の投稿でしたが、公開してみました。

---

# 2014/09/08のMarkdown『リンクテキスト』
リンクをhttp://google.com とURLを直接記述するのではなく、
「[Google](http://google.com)」のようにリンクテキストで記述する場合のやり方はこちらです。

## :page_with_curl: 例
> [Google](http://google.com)


## :black_nib: 書き方

```

[Google](http://google.com)

```

このように`[]`には表示させたいテキストを、`{}`には挿入したいリンクを括弧の中に書きます。
こんな感じで`[]{}`２つを並べるとテキストリンクが作成できます。

## 参考
[Markdownとは · 日本語Markdownユーザー会](http://markdown.jp/what-is-markdown/ "Markdownとは · 日本語Markdownユーザー会")

---

# 2014/09/05のMarkdown「*テキストの強調*」

今日は**強調文**です。テキストにボールドや斜体がかかります。

## :page_with_curl: 例

_強調文です_
*強調文です*
__強調文です__
**強調文です**
~~ついでに打ち消し線です~~

## :black_nib: 書き方

```

_強調文です_
*強調文です*
__強調文です__
**強調文です**
~~ついでに打ち消し線です~~

```

`*(アスタリスク)`や`_(アンダースコア)`囲むだけです。簡単！

ブログなどでは修正したことを示すために、**打ち消し線**はよく使われていますね。
~~こんな感じです~~


# 2014/09/04のMarkdown「Lists-リスト」
今日はリストについて説明します。

まずリストには下記の3種類があります。

-  `<ul>`：Unordered List ・・・  順序なしリスト
-  `<ol>`：Ordered List ・・・    順序付きリスト
-  `<dl>`：Definition List ・・・ 定義リスト

ちなみに`<li>`はList Itemの略。Listの略じゃないんですね〜(知らなかった)
今回は使うと便利な「順序なしリスト」と「順序付きリスト」の使い方を紹介します。

## :page_with_curl: 例
#### ▼順序なしリスト
##### 【動物の種類】
- りす
- うさぎ
- パンダ

---

#### ▼順序付きリスト
##### 【卵かけごはんの作りかた】
1. 卵を割る
2. 卵をかける
3. 卵をご飯にかける

---


## :black_nib: 書き方

#### ▼順序なしリスト

```

- りす
- うさぎ
- パンダ

```

#### ▼順序付きリスト

```

1. 卵を割る
2. 卵をかける
3. 卵をご飯にかける

```

![19fc4b1ea93700233ad7374acc232f7a.gif](https://qiita-image-store.s3.amazonaws.com/999/49056/f0a31976-13b7-b78b-445e-71c1ec219256.gif)

このように「1. テキスト」と書いて改行すると自動で、次の行の「2. 」を作成してくれるので、
いちいち先頭にある「1.、2. ...」と書かなくていいのも、Qiitaエディターのいい所です(順序なしリストでも同様です)


## 参考
[電書ちゃんのでんでんマークダウン - でんでんマークダウン](http://conv.denshochan.com/markdown "電書ちゃんのでんでんマークダウン - でんでんマークダウン")



# 2014/09/03のMarkdown「水平線」

文章を区切る水平線`<hr>`の書き方は非常に簡単です。

## example

---

## 書き方

```
---

```

`-`を3本書くだけです。感覚的にも水平線っぽいので覚えやすいです。
他にも色々のような書き方があるので、お試しあれ。

```

***

* * *

*****

- - -

---------------------------------------

___


```

## 参考
[文章作成やメモ書きにも便利、Markdown記法｜Web Design KOJIKA17](http://kojika17.com/2013/01/starting-markdown.html "文章作成やメモ書きにも便利、Markdown記法｜Web Design KOJIKA17")



# 2014/09/02のMarkdown「絵文字:sunglasses:」

なんと！Markdownでは絵文字が使えます:sparkles:
もちろんコメントにも使えますので、是非使ってみてください。


### :page_facing_up:Example
oh... :hushed:

### :pencil2:記述方法

```ruby:Markdown

oh... :hushed:

```

このように`:アイコン名:`で囲むとアイコンが出てきます。

ただ実際はアイコン名を覚えるのが大変なので、辞書登録するか、
下記のサイトをブックマークバーに登録します。

![スクリーンショット 2014-09-03 12.51.54.png](https://qiita-image-store.s3.amazonaws.com/999/49056/831dcbb0-6c24-9263-bd25-b47e1c62c10e.png)

※:thumbsup:がファビコン

### :link:[Emoji cheat sheet for Campfire and GitHub](http://www.emoji-cheat-sheet.com/ "Emoji cheat sheet for Campfire and GitHub")
### 使い方
アイコンをクリックすると、クリップボードにコピーされます。
海外では絵文字がEmojiなんですね〜:grinning:



# 2014/09/01のMarkdown「引用文」
###例
>このテキストは引用文です。

引用文は文頭に`>`を付けるだけで記述できます。

###書き方

```

>このテキストは引用文です。

```
【php】URLを取得してカレント表示させる

例えば下記のURLがあったとして、
http://sample/★★★/
★★★にいるときに、★★★ページのグロナビなどをカレント表示させたいときに使いました。

```ruby:php

<?php
 function is_current( $uri = "" ) {
    $uri = trim( $uri, "/" );
    $request_uri = $_SERVER['REQUEST_URI'];
 
    if( $uri && strpos($request_uri."/", "".$uri."", 0) !== FALSE ) {
        return true;
    }
    $request_uri = trim(str_replace( "/index.php", "", $request_uri ), '/'); // top
    if( !$uri && !$request_uri ) {
        return true;
    }
    return false;
}
function echo_current( $uri = "" ) { 
    if(is_current( $uri )) {
        echo '_on';
    };
}
?>

```


```ruby:php

<ul>
  <li><a href="/"><img src="http://sample/images/gnav_top<?php echo_current("");?>.png" alt="トップページ"></a></li>
  <li><a href="/★★★/"><img src="http://sample/images/gnav_top<?php echo_current("★★★");?>.png" alt="★★★ページ"></a></li>
</ul>

```

★★★ページ（http://sample/★★★/ ）にいる際に、
画像URLの<?php echo_current("★★★");?>の部分が「_on」に変わります。


引用：[地味に便利：自動的にリンクにclass=”current”を付加するPHP書きました。 | Toro_Unit](http://www.torounit.com/blog/2012/11/15/1399/ "地味に便利：自動的にリンクにclass=”current”を付加するPHP書きました。 | Toro_Unit")
私とPuppet インストール編

Puppetのインストール手法についてまとめておく。

# 本シリーズの目次

* [Infrastructure as Code 概念の理解](http://qiita.com/takeuchikzm/items/fb9d1701ea19be337131)
* [Puppet環境の準備](http://qiita.com/takeuchikzm/items/eb37a918b39b069f22b3)
* [Puppetの基本の理解その1 Resource,Ordering,Class,Define,Node](http://qiita.com/takeuchikzm/items/cfa012571fdedcf0792b)
* [Puppetの基本の理解その2 Module,File,Templates,Variable](http://qiita.com/takeuchikzm/items/6b65af9e0cf8d317c9b3)
* [Puppetベストプラクティスの理解その1 ディレクトリ構成とその役割](http://qiita.com/takeuchikzm/items/5e303e03a48ab2f0db1a)
* [Puppetベストプラクティスの理解その2 多種多様なサーバの構成管理](http://qiita.com/takeuchikzm/items/8dd82540a8cceb7b850f)
* [Puppetベストプラクティスの理解その3 Hieraで世界が変わる?] (http://qiita.com/takeuchikzm/items/e04e6cbe84a185eb1f26)

# 前提条件
* 構成管理対象としてはCentOS 6.5を想定する。
* VirtualBoxおよびVagrantがインストールされていること。

# テスト用仮想マシンの準備 

## Puppet提供のVMを使う場合

VirtualBox用のイメージが[無料ダウンロード](http://puppetlabs.com/download-learning-vm)できる模様。(ただし登録が必要)

## Vagrantを利用する場合

```bash::vagrantによるVMの準備
$ sudo mkdir PuppetVagrant 
$ sudo cd PuppetVagrant 
$ sudo vagrant box add CentOs6.5 https://github.com/2creatives/vagrant-centos/releases/download/v6.5.3/centos65-x86_64-20140116.box
$ sudo vagrant init CentOs6.5
$ sudo vagrant up 
$ sudo vagrant ssh 
[vagrant@vagrant-centos65 ‾]$ 
(うまくいけばVMにログインできる。ログイン時のusername/passwordはともにvagrant。) 
```

PuttyやTeraterm等の任意のSSHクライアントでログインしたい場合は、`vagrant init`
直後に出来上がるVagrantfileの中の

```:PuppetVagrantVagrantfile 
config.vm.network :private_network, ip: "192.168.33.10" 
```

でローカルマシンからアクセスできる任意のアドレスを設定することができる。

## puppetのインストール

以下はすべてvagrantで作成したVMの中の操作とする。

```bash::puppetのインストール
$ sudo rpm -ivh http://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm 
$ sudo yum install -y puppet 
```

これでPuppetのインストールは完了。なお、2014/09/05時点でこの手順を実行すると、

* puppet-3.7.0-1

がインストールされた。