OmniAICreator/Qiita-1.07M huggingface dataset:
git 上のいろんなことをなかったことにする

# 前置き

自分用覚書なので適当です。

## 注意

この記事は、git でやらかしたあれこれを『人知れず「なかったことにする」』ための方法が主になっているので、リモートに `push` したあとには絶対しないように。`push` したあとに `reset` して、あらたに別の `commit` をしてからの `push -f` などは、間違ってもしてはいけません。

## 注意2 (2020-08-06追記)

なにぶん古い記事なので、一部コマンドが最新の形態とは異なる部分があります。（後方互換性があるから大丈夫ですが。）
気が向いたら修正していこうかと思っています。

# なかったことにする

## add をなかったことにする

### すでに git の管理下にあるファイルの場合

```shell-session
$ git reset HEAD <file>
```

### git の管理下にまだなかったファイルを add した場合

```shell-session
$ git rm --cached <file>
```

管理下になかったファイルの場合、よくよく考えてみれば当然だが、戻るべきコミットが存在しないから reset では戻れない。しかたがないので rm で直接管理外とする。

## commit をなかったことにする

### commit したことをなかったことにする（編集内容はそのまま）

```shell-session
$ git reset --soft HEAD^
```

`--soft` は HEAD の位置だけが移動する

### commit をまるごとなかったことにする（編集内容もなかったことにする）

```shell-session
$ git reset --hard HEAD^
```

### commit をやり直す

#### 足りないファイルを追加するとか

不足していたファイルを add した後

```shell-session
$ git commit --amend
```

#### コメントを書きなおす（直前のコミットに対して）

コミットした直後にコメントが間違っていたことに気づいた場合

```shell-session
$ git commit --amend 
```

すかさず --amend 付けてコミットすればよい。

#### コメントを書き直す（履歴をさかのぼって）

いくつかコミットをしたあとに、過去のコミットのコメントが間違っていたことに気づいた場合

```shell-session
$ git log --oneline
aaaaaaa (HEAD -> main) 正しいコメント
bbbbbbb 間違ったコメント
ccccccc 正しいコメント
```

rebaseで間違っているコミットの一つ前に戻り

```shell-session
$ git rebase -i ccccccc

pick aaaaaaa 正しいコメント
pick bbbbbbb 間違ったコメント
```

pickをeditに書き換えてエディタを終了

```shell-session
pick aaaaaaa 正しいコメント
edit bbbbbbb 間違ったコメント
```
amendでコメントを修正して

```shell-session
$ git rebase -i ccccccc
Stopped at bbbbbbb...  間違ったコメント
You can amend the commit now, with

  git commit --amend

Once you are satisfied with your changes, run

  git rebase --continue
```

```shell-session
$ git commit --amend
```

continueでrebaseを完了させる

```shell-session
$ git commit --continue
```


### 付けてはいけないのにうっかり --amend をつけてコミットしてしまった

```shell-session
$ git reset HEAD@{1}
```

コマンド実行履歴などを使っていると、うっかり amend を付けてはいけない時に付けてしまうことがたまにある。そのような場合、単に `git reset --hard HEAD^` では前のコミットは戻ってこない。すでに amend でコミットそのものが編集されてしまっているので。
そこで reflog を使用して元に戻す。
ちなみにreflogを使うと、単純なコマンド使用では回復できない状態でも、よほど致命的なことがない限りログをさかのぼることができて、いざというときに有用。

## merge をなかったことにする

```shell-session
$ git reset --hard ORIG_HEAD
```

## ファイルの編集をなかったことにする

```shell-session
$ git checkout HEAD -- <file>
```

編集したファイルを、元あった場所から取り直してくるということ。
なお、うっかりファイルを削除した場合でもこれで取り直せる。

## rmしたことをなかったことにする

```shell-session
git restore --staged <file>
git restore <file>
```

（多分）一発で戻すことはできなくて、一旦stageから降ろしてきた後に最終的になかったことにします。

## git の管理下にあることをなかったことにする

```shell-session
$ git update-index --assume-unchanged <file>
```

例えば配布はするけど管理は各リポジトリごとに別々で行いたい（一例として、環境に依存する設定ファイルとか）場合に重宝する。

なお、元に戻したいときは

```shell-session
$ git update-index --no-assume-unchanged <file>
```

とする。

（http://qiita.com/usamik26/items/56d0d3ba7a1300625f92 を参考にさせていただきました。）

# 後書き

なかったことにするのに `revert` については触れないのか？と思った方もいるでしょう。しかし、`revert` はある意味では `commit` をなかったことにしていますが、`commit` をなかったことにしたことをなかったことにはしません。`commit` を取り消したことがちゃんとログに残ります。ですので、この記事の趣旨とは外れるため、あえて触れませんでした。
コマンドとREPLで結果が異なるコード

こんなコードを書いた。

```js:index.js
console.log(!!require);
console.log(!!global.require);
```

なんかコマンドから実行すると、想定している動作をしないな？と思い調べてみると。

```bash:Terminal
$ node index.js
true
false
$ node
> .load index.js
console.log(!!require);
true
undefined
console.log(!!global.require);
true
undefined
```

どういうこっちゃ……

```js:inspect.js
var fs = require('fs'),
    util = require('util');

fs.writeFileSync(!!global.require ? './repl.txt' : './command.txt', util.inspect(global, {
  depth: null
}));
```

```bash:Terminal
$ node inspect.js
$ node
> .load inspect.js
...
> .exit
$ diff -u repl.txt command.txt
```

ヽ(`Д´)ﾉなんか微妙に違うじゃん！
yeoman環境構築関連のメモ

# yeoman関連のメモ

* yeomanの前にnodejsが必要なのでまずはnodejsからインストール

* 参考
 * [yeomanインストール](http://hack.aipo.com/archives/887/)
 * [nodejsインストール](http://qiita.com/you21979@github/items/4efd9fc4363573191b5c)

## 環境
* VirturalBoxで仮想環境を作成
* 仮想環境のOSはCentOS6.5
* Vagrantで管理

## nodejsのインストール

* 念のためvagrantのsandboxのモードはonにしておく
* pythonとopen-sslは先にインストールしておく必要あり
* epelとRemiもインストールしておく
* Remi、epel は yum のリポジトリ

### 準備

* リポジトリ追加

```
sudo rpm -ivh http://ftp.riken.jp/Linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
```

### インストール

* 途中の確認メッセージはNoを選択

```
sudo yum install nodejs npm --enablerepo=epel
```

## yeomanのインストール

* grunt と bower も同時にインストールする

```
sudo npm install -g yo grunt-cli bower
```

* 次にジェネレータのインストール
* backboneはよくわからないので入れるだけ

```
sudo npm install -g generator-backbone
sudo npm install -g yo generator-webapp
sudo npm install -g generator-bespoke
```

## 動作確認

* 任意のディレクトリを作成


```
mkdir $HOME/yeoman_test_02
```

* 作成

```
cd $HOME/yeoman_test_02
yo webapp
```

* 下記エラー

```
Warning: PhantomJS not found. Use --force to continue.
```

* phantomjsが必要っぽいのでインストール

```
cd /usr/local/src
sudo wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-1.9.7-linux-x86_64.tar.bz2
sudo tar jxfv phantomjs-1.9.7-linux-x86_64.tar.bz2
```

* パスを通す

```
sudo cp /usr/local/src/phantomjs-1.9.7-linux-x86_64/bin/phantomjs /usr/bin/
```

* 改めて作成

```
cd $HOME/yeoman_test_02
yo webapp
```

* 今度はエラーはなし

* サーバ起動

```
grunt server
```

* 起動できた


* ホストOSのブラウザから参照したい
* 一旦サーバストップ(ctrl + C)
* $HOME/yeoman_test_02/Gruntfile.jsを編集

```js
                // hostname: 'localhost'
                hostname: '192.168.33.56'
```

* ホストOSのブラウザから下記にアクセス

```
http://192.168.33.56:9000/
```

* Allo, Allo！！　（ブラウザに表示された）

　　
　



* bespoke もやっとく
* オプションは全部Yesにしておく

```
mkdir $HOME/yeoman_test_03_bespoke
cd $HOME/yeoman_test_03_bespoke
yo bespoke
```

* ホストOSのブラウザから参照したい
* $HOME/yeoman_test_03_bespoke/Gruntfile.jsを編集

```js
          // hostname: '*', // Remove this line if you only want the server available locally
          hostname: '192.168.33.56',
```


* サーバ起動

```
grunt server
```

* ホストOSのブラウザから下記にアクセス

```
http://192.168.33.56:8000/
```

Newbie!（表示された）
Vagrant - Vagrant Cloudの新規登録手順

# 1. はじめに

本記事では、作成したBoxファイルをVagrant Cloudに登録するまでの手順について記述します。

# 2. 前提条件

Boxファイルを登録する際に、Vagrant Cloudへのユーザー登録が必要になります。
もし、ユーザー登録をしていない場合、先にユーザー登録をしてください。

URL: https://vagrantcloud.com/account/new

# 3. 登録手順

### (1) Vagrant Cloudにログインします。

URL: https://vagrantcloud.com/session

### (2) ナビゲーションメニューから「Create Box」をクリックします。

### (3) 「Create a new box」の画面が表示されるので、入力フォームに記載します。

<入力内容>

|項目|内容|
|:--|:--|
|Name|(ユーザーID)/(Box名)|
|Short description|(Boxファイルに関する概要を記載)|
|Private|(一部のユーザーにのみ公開したい場合はチェックを入れる)|
|Description|(Boxファイルに関する説明を記載)|

### (4) 「Create box」をクリックします。

### (5) 「Create a new version for (Box名)」の画面が表示されるので、入力フォームに記載します。

<入力内容>

|項目|内容|
|:--|:--|
|Version|1.0.0|
|Description|Initial commit|

### (6) 「Create version」をクリックします。

### (7) 「Create new provider」をクリックします。

### (8) 「New provider」の画面が表示されるので、テキストボックスに対象のプロバイダー名を入力して「URL」をクリックします。
→ VirtualBoxの場合、「virtualbox」と入力します。

### (9) 「URL」の下に表示されているテキストボックスにBoxファイルの格納先を入力します。

＊）Boxファイルの格納先はDropboxやAmazon S3のようなクラウドストレージ上にしないといけません。

### (10)「Create provider」をクリックします。

### (11)「Release now」をクリックします。
revelでmgo実装テスト　その2

　前回はsessionを制御するsession.goを実装しました。今回は実装したsessionを使用して簡単なアプリケーションを作っていきます。まずは使用するmodelを準備します。

```Go:person.go
package models

import (
	"labix.org/v2/mgo/bson"
)

var (
	err error
)

type Person struct {
	PersonID     bson.ObjectId `bson:"_id,omitempty" json:"-"`
	FirstName    string        `bson:"firstName" json:"firstName"`
	LastName     string        `bson:"lastName" json:"lastName"`
	Nickname     string        `bson:"nickname" json:"nickname"`
	Email        string        `bson:"email" json:"email"`
	SecurityCode int           `bson:"securityCode" json:"securityCode"`
}

func (p *Person) MakeEmail() {
	if p.FirstName == "" {
		panic(err)
	} else {
		p.Email = p.FirstName + "." + p.LastName + "." + p.Nickname + "@email.com"
	}
}
```
 いつかはテストしたいのでbsonとjsonのタグをつけています。またmethodとしてMakeEmail()を実装し生成された構造体のデータをもとにemailを生成しています。
　次に具体的な作業をしているapp.goの中身をみていきます。

```Go:app.go

package controllers

import (
	"fmt"
	"github.com/robfig/revel"
	"labix.org/v2/mgo/bson"
	"testApp/app/models"
)

var (
	results []interface{}
	errCode string
)

type App struct {
	*revel.Controller
}

// ------ Index ------
func (c App) Index() revel.Result {
	greeting := "Welcome"

	return c.Render(greeting)
}
```
　ここまでは雛形から自動生成されるものですね。少し改造したのは"Welcome"を追加したぐらいです。
次にPerson構造体を生成しDBにInsertするmethodです。

```Go:app.go
// ------ CreatePerson -----------
func (c App) CreatePerson(firstName string, lastName string, nickname string, securityCode int) revel.Result {
	c.Validation.Required(firstName).Message("You must input your firstname")
	c.Validation.Required(lastName).Message("You must input your lastname")
	c.Validation.Required(nickname).Message("You must input your nickname")

	if c.Validation.HasErrors() {
		c.Validation.Keep()
		c.FlashParams()

		return c.Redirect(App.Index)
	}

	person := &models.Person{FirstName: firstName, 
								LastName: lastName, 
								Nickname: nickname, 
								SecurityCode: securityCode}
	person.MakeEmail()
	InsertEntity("testApp", "person", "localhost", person)
	
	return c.Render()
}
```
　まずはpersonを生成します。その後personのmethodであるMakeEmail()を呼び出します。これで準備ができたので次ぎにDBにEntityを追加します。登録する際に情報がかけていると問題なのでValidationを使い。Error処理しています。今回は示していませんが、xxx.htmlはこれらの情報がとれるように変更してください。
　次に登録されているかを確認するためにSearchを使ってみます。

```Go:app.go
// ----- Search All person -----
func (c App) SearchAllPerson(nickname string) revel.Result {
	results, errCode = Search(bson.M{"nickname": nickname}, 0, 10, "testApp", "person", "localhost")

	var containerNumber = len(results)

	if containerNumber != 0 {
		result := results[0]

		return c.Render(result)

	} else {

		return c.Redirect(App.Index)
	}
}
```
　このような感じでresultsのスライス内に検索結果を入れます。
VagrantのOSをロールバックさせられるsaharaの使い方メモ


[1]: http://www.amazon.co.jp/gp/product/B00BSPH158?ie=UTF8&camp=1207&creative=8411&creativeASIN=B00BSPH158&linkCode=shr&tag=stackstock-22&qid=1398762855&sr=8-1&keywords=%E5%85%A5%E9%96%80+chef+solo

VagrantでOSを管理している場合に、「あれ？これおかしいな」ってなった時のためにロールバックができるようにするSaharaってプラグインがあるらしいのでメモ。

これとChefのようなサーバの状態管理ツールと組み合わせることで、

- 今の状態を保存しておく
- Chefで変更したい状態を記述する
- Chefを実行して状態を変更する
- ダメだった場合保存した状態に戻す

みたいなことが出来るようになる

### Saharaのインストール

````shell
$ vagrant plugin install sahara
````

## 使い方
SaharaとChefを使った場合の基本的な作業の流れはこんな感じ

- sandboxモードをon
- Chef solo を実行して状態を変更
- 問題があった場合はロールバック
- 問題がなければコミットしてサンドボックスモードを解除

### サンドボックスモードを有効
「この状態を保存したい」って時にサンドボックスモードを有効にする

````shell
$ vagrant sandbox on
````

ロールバックコマンドを実行したらサンドボックスモードを有効にした時の状態に戻る

````shell
$ vagrant sandbox rollback
````

### OSの状態を確定
良い感じになったらコミットコマンドでOSの状態を確定する

````shell
$ vagrant sandbox commit
````


### サンドボックスモードを解除
````shell
$ vagrant sandbox off
````

基本的にnaoyaさんの本を見て「これは覚えておかないと！」と思ったのをメモっただけなのでこれを読んで「これはっ！」って思った人は悪い事言わないから本買うといいよ

[入門Chef solo][1]
revelでmgo実装テスト　その1

　今回は、revelでmgoを使ってDBを利用するための下準備です。まずはDBを制御するためのcontrollerを実装していきます。参考にしたのは以下のサイトです。こちらをもとに少し使いやすくしています。
<参考サイト>
http://denis.papathanasiou.org/2012/10/14/go-golang-and-mongodb-using-mgo/

　sessionをコントロールするので、session.goというcontrollerを作成します。
主な機能は
①session構築(cloneSession)
②Entity挿入(InsertEntity)
③Entityの削除(RemoveEntity)
④Collectionのquery(queryCollection)
⑤検索(Search)

```Go:session.go
package controllers

import (
	"labix.org/v2/mgo"
)

var (
	session *mgo.Session
	err     error
)

// new session create
func cloneSession(dialURL string) *mgo.Session {
	if session == nil {
		session, err = mgo.Dial(dialURL)
		if err != nil {
			panic(err) //no, not really
		}
	}
	return session.Clone()
}

// insertEntity
func InsertEntity(dbName string,
	collection string,
	dialURL string,
	model interface{}) {

	session := cloneSession(dialURL)
	defer session.Close()

	err := session.DB(dbName).C(collection).Insert(model)
	if err != nil {
		panic(err)
	}
}

// removeEntity
func RemoveEntity(dbName string,
	collection string,
	dialURL string,
	model interface{}) {

	session := cloneSession(dialURL)
	defer session.Close()

	err := session.DB(dbName).C(collection).Remove(model)
	//err := session.DB(dbName).C(collection).RemoveAll(model)

	if err != nil {
		panic(err)
	}
}

// Query collection
func queryCollection(dbName string,
	collection string,
	dialURL string,
	query func(c *mgo.Collection) error) error {

	session := cloneSession(dialURL)
	defer session.Close()

	c := session.DB(dbName).C(collection)

	return query(c)
}

// Search
func Search(q interface{},
	skip int,
	limit int,
	dbName string,
	collection string,
	dialURL string) (results []interface{}, errorCode string) {

	errorCode = ""
	query := func(c *mgo.Collection) error {
		fn := c.Find(q).Skip(skip).Limit(limit).All(&results)
		if limit < 0 {
			fn = c.Find(q).Skip(skip).All(&results)
		}
		return fn
	}

	search := func() error {
		return queryCollection(dbName, collection, dialURL, query)
	}

	err := search()
	if err != nil {
		errorCode = "error"
	}

	return
}
```
 []interface{}で受け取るもしくは、返り値として設定している部分は適宜使用する構造体のスライスに置き換えればカスタマイズできそうですね。
 Searchはかなり厄介ですね。私もコード理解するのに苦労しました。queryはObjective-CのBlocksのような使い方ですね。queryをその場の引数で関数実装して、それをqueryCollection関数の引数で渡しています。
　次回はapp.goの中で具体的な処理を実装します。
【ownCloud】AmazonS3連携

# ownCloudとは
* PHPベースのオープンソースプロダクト
* Dropboxのようなオンラインストレージを自前の環境に構築可能
* ブラウザの他、専用のWindows、Linux、Mac、Android、iPhone用クライアントから接続可能
* アドオン機構があるため、独自アプリを実装することが可能
* 日本語フォーラム[Japan ownCloud User Group (JOUG)](http://owncloud.jp/forum/)あり

# 今回やること 
* [前回の記事](http://qiita.com/ukitiyan/items/f4113aeb4b56d76d3bc2)で紹介した環境からAmazonS3に接続する方法を紹介します。
* 構成は以下のイメージで、EC2からインターネットを介して接続しているところが惜しいです。S3へのゲートウェイとしてownCloudを利用するイメージです。
* StrageGateway経由での接続方法等は別途掲載します。
![Arch](https://qiita-image-store.s3.amazonaws.com/0/39596/e3155aa1-9861-2c47-6c40-88adc15d52fc.png "スクリーンショット 2014-04-28 22.42.44.png")

# AmazonS3連携
## １. AWSで事前にやること
1. AmazonS3にてBucketを登録します。
2. アクセス証明書にて、"アクセスキーID"と"シークレットアクセスキー"を取得します。

※セキュリティ保護のため、 2014年4月21日以降はシークレットアクセスキーを取得できなっています。
[こちらを参照](https://portal.aws.amazon.com/gp/aws/securityCredentials?)

## ２. ownCloudの構築
1. 以下の記事を参照
 * [【ownCloud】AWSに専用オンラインストレージ構築](http://qiita.com/ukitiyan/items/f4113aeb4b56d76d3bc2)

## ３. External Storage supportアプリ有効化
1. 管理者アカウントでログインし、「アプリ」パネルを表示します。
![sc0009.png](https://qiita-image-store.s3.amazonaws.com/0/39596/45e16ff2-4132-e69e-ef2c-ad2727bde74b.png "sc0009.png")
2. 「アプリ」パネルで、「External Storage support」を有効にします。
![sc0009.png](http://www.begood-tech.com/wp-content/uploads/2014/01/20140115_01.jpg)

## 4. External Storage supportアプリの設定
* External Storage supportアプリでは、「個人設定」パネル・「管理者」パネルから設定が行えます。
 * 「個人設定」パネル
     * ユーザが自分自身でAmazonS3に接続します。
![user_pane](http://www.begood-tech.com/wp-content/uploads/2014/01/20140115_021-615x108.jpg)
 * 「管理者」パネル
     * 管理者がAmazonS3に接続し、ユーザやグループに対してアクセス権限を付与します。
![admin_pane](http://www.begood-tech.com/wp-content/uploads/2014/01/20140115_03-615x123.jpg)

* 以降は、「個人設定」パネルでの説明となります。

1. 「個人設定」パネルを表示します。
2. 外部ストレージセクションで以下を設定します。
 * フォルダ名：ownCloudで表示されるフォルダ名（デフォルト：AmazonS3）
 * 外部ストレージ：プルダウンメニューから「Amazon S3」を選択
 * 設定（アクセスキー、シークレットキー、BucketName）
![admin_pane2](http://www.begood-tech.com/wp-content/uploads/2014/01/20140115_06-615x111.jpg)

3. 設定完了後、緑色のフラグが表示されます。

## ５．ownCloudでの確認
1. 「ファイル」パネルを表示すると「Amazon S3」というフォルダが表示されます。
![sc0012.png](https://qiita-image-store.s3.amazonaws.com/0/39596/0c1dae20-cfc3-03ee-376f-6cc31e6c403f.png "sc0012.png")


# 最後に
* AmazonS3以外にもAmazon S3互換のストレージであれば同様に接続可能です。
* 順次ownCloudとAWSに関する記事を投稿していきます。
* 独自アプリのコードも公開予定です。
rails.vimの基本動作を確認してみた

自分用のメモにrails.vimの基本動作を確認してみた。

# rails.vimのインストール
ここから https://github.com/tpope/vim-rails


# モデルTodoから、Controller,Viewに切り替えるには

```vim
:Econtroller
:Eview ビュー名(newやeditなど)
:Emodel
:Ehelper
```

# モデル名を明示して、MVCを切り替えるには
例:モデルroleを表示する.
```vim
:Econtroller roles
:Eview roles/ビュー名(newやedit,showなど)
:Emodel role
```

名称はtabを押すと色々と補完してくれる。

# gfの動作
ソースを見た方が早いのかもしれない･･･。

- クラス名でgf => そのクラスの定義ファイルに移動する.

```rb
# カーソルがApplicationController上でgfを入力する
class RolesController < ApplicationController
```

- controllerのメソッド名でgf => viewがある場合はそのビューファイルへ

```rb
class RolesController <...
  # カーソルがこの行にある状態でgfを入力する.
  def index
    # メソッド中にあるRole.methodなどでもgfしたら、role.rbに移動
    # するかと思いきや、ファイルが見つからないと怒られてしまった。
    # パスの設定不足?
    ...
  end
end
```

- モデル中のattr_accessible,has_many, メソッド中のモデル名でgf(attr_accessibleはrails4では非推奨) => モデルクラスがある場合は、その定義ファイルへ

```rb
class Role < ActiveRecord::Base
  # Userが存在する場合、userにカーソルをあててgfを入力する.
  # name(string)では飛ばない
  attr_accessible :name, :user

  def sample
    # ここでgfを入力すると、user.rbへ
    user
  end
end
```

- viewの'form'などでgf => 対応するviewファイルへジャンプ

- 以下でgfしても反応無し？
 - helper
 - js
 - scheme.rb
 - routes.rb

# :Aコマンド (関連ファイルに切り替え)
（カーソル位置に依らない？）

凡例: :Aを実行したファイル => 移動先ファイル

- モデル => モデルテスト
  例：role.rb => role_test.rb

- ビューファイル => コントローラテスト
  例：roles/_form.html.erb => roles_controller_test.rb

- ヘルパー => ヘルパーテスト
  例：roles_helper.rb => roles_helper_test.rb

- application.js => application_heler.rb
- xxx.js => application.js
- scss => 反応無し
- migration => 定義済みのmigrationファイルを循環する
- scheme.rb => seeds.rb
- seeds.rb => scheme.rb
- application.rb => routes.rb
- routes.rb => application.rb

# :Rコマンド
（カーソル位置に依る）

- RolesController => RolesHelper
- RolesController::index => views/roles/index.html.erb
- views/roles/index.html.erb => RolesController::index
- Roles => schema.rb
- schema.rb => カーソルのあるモデルクラス
- RolesHelper => RolesHelerTest
- environment.rb => routes.rb
- routes.rb => application.rb
- application.rb => routes.rb

# ジャンプ元のファイルに戻るには

[Rails.vim 移動元のファイルに戻るには](http://qiita.com/hmu29/items/bc40932a82858fcddeb9)
Compassのsourcemap出力

# sassのインストール
* Sassはsourcemap出力は正式対応されているので、下記コマンドでインストール。

```
gem install sass
```

# Compassのインストール
* Compassは現時点ではsourcemapの出力に正式対応していない(2014年4月29日時点)のでalpha版をインストールする

```
gem install compass --pre
```

config.rbに以下を追加することでsourcemapが出力される

```rb:config.rb
sourcemap = true
```
※ 以前はcompass watchではsourcemapが出力されなかったが、現在は出力される

# Gruntのインストール（オプション）
* ~~compass -watchでsourcemapが出力されなかったが、Gruntでは対応している?!~~
* gruntではsourcemapオプションで指定することができる
```
npm install grunt-cli -g
npm install grunt-contrib-compass
```

```js:Gruntfile.js
grunt.initConfig({
    compass: {
      watch: true,
      sourcemap: true
    }
});
```
Sailsでデフォルトの設定値を変更する

Sailsバージョン：0.9.16

`sails/lib/configuration/defaults.js`内で定義されているデフォルトの設定値を変更する。
これを使うと`モデルやコントローラーのパス`、`その他もろもろのデフォルト設定値`をsails.lift()の前に変更することが可能。

やり方は簡単で、sails.lift()の第一引数に変更したい設定値を渡すだけ。

```js:app.js
// Start sails and pass it command line arguments
var path = require('path');
var config = require('optimist').argv;

// モデルディレクトリのパスをapi/modelsからapi/models2に変更
var modelPath = path.join(__dirname, 'api/models2');
config['paths'] = {models: modelPath};

require('sails').lift(config, function() {
	// 起動完了後に実行されるcallback
});
```
トレイトによるアクセサの自動実装

**2016年6月30日 更新**

- リフレクションを使わない方法を思いついたので，オーバーヘッドの少ない方法に変更しました．
- 型チェックはPHP7.0+のスカラータイプヒントにしました．

# 実装

マジックメソッド`__call()`を利用してGetterメソッドとして実装するのは大文字小文字の区別などの面で厄介事が多いので，素直にマジックメソッド`__get()`を利用して**外部から読み取り可能なプロパティ**として実装することにしました．

## 全プロパティを対象にする

```php:トレイト定義
<?php

trait AllReadable
{
    public function __get(string $name)
    {
        if (array_key_exists($name, get_object_vars($this))) {
            return $this->$name;
        }
        if (property_exists($this, $name)) {
            throw new \OutOfRangeException("Cannot access static property: $name");
        }
        throw new \OutOfRangeException("Undefined property: $name");
    }

    public function __isset(string $name) : bool
    {
        return isset($this->$name);
    }
}
```

```php:使用例
class Test
{
    use AllReadable;

    private $a = 'A';
    protected $b = 'B';
    public static $c = 'C';
}

$t = new Test;
echo $t->a; // A
echo $t->b; // B
echo $t->c; // Cannot access static property: c
```

## ***`$__readable`***で指定したプロパティのみを対象にする

少し気持ち悪いかもしれませんが，マジックメソッド`__get()`が存在しているのであれば，まぁPHPらしくプロパティ***`$__readable`***なんか作っちゃってもいいかなぁと．ちなみにこのプロパティ自体は静的プロパティであってもインスタンスプロパティであっても動作しますが，前者として書いておいた方が望ましいでしょう．

```php:トレイト定義
<?php

trait PartiallyReadable
{
    public function __get(string $name)
    {
        if (array_key_exists($name, get_object_vars($this))) {
            if (in_array($name, (array)(static::$__readable ?? []), true)) {
                return $this->$name;
            }
            throw new \OutOfRangeException("Inaccessible property: $name");
        }
        if (property_exists($this, $name)) {
            throw new \OutOfRangeException("Cannot access static property: $name");
        }
        throw new \OutOfRangeException("Undefined property: $name");
    }

    public function __isset(string $name) : bool
    {
        return in_array($name, (array)(static::$__readable ?? []), true)
             & isset($this->$name);
    }
}
```

```php:使用例
class Test
{
    use PartiallyReadable;
    protected static $__readable = ['a', 'c', 'd'];

    private $a = 'A';
    protected $b = 'B';
    public static $c = 'C';
}

$t = new Test;
echo $t->a; // A
echo $t->b; // Inaccessible property: b
echo $t->c; // Cannot access static property: c
echo $t->d; // Undefined property: d
```
64bit Ubuntu に Android の開発環境をインストールするときにやること

https://developer.android.com/sdk/installing/index.html より。

64bit 版の Ubuntu に Android の開発環境を構築するにあたっては、ほんの少しだけ事前にやることがあるので注意書きと備忘録として。

主には、エミュレータの動作にあたって必要なライブラリが 32bit 版に依存しているので、以下の手順で必要なライブラリを入れておかないと、エミュレータがうまく立ち上がらなかったり、SDK Manager の UI が立ち上がらなかったりします。

## i386 アーキテクチャ向けにコンパイルされたライブラリを入れる

Ubuntu 13.10 以上の場合、以下の手順で必要なライブラリを`apt-get install`します。

```shell-session

sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install libncurses5:i386 libstdc++6:i386 zlib1g:i386
```

それより前のバージョンの場合、以下の手順で必要なライブラリを`apt-get install`します。

```shell-session

apt-get install ia32-libs
```

## Java 6 を入れる

Sun の JDK を入れます。

```shell-session

apt-get install sun-java6-jdk
```

以上で、正常に Android の開発環境が動作するようになります。
Listからnull要素を抜く

```java
List<String> list = new ArrayList<>();
list.add("aaa");
list.add(null);
list.add("bbb");
list.add(null);

list.removeAll(Collections.singleton(null));

//→”aaa”,"bbb"だけになる
```
Collections.singletonは特定の要素を含むimmutableなSetを返すstaticファクトリメソッド
ニコニコ動画のタグ検索結果をXML形式で取得する。(ログイン不要)

#概要
ニコニコ動画のタグ検索結果をXML形式で取得する。
既存の検索APIがあるそうだが、ログイン必須で使いにくい。
[（→参考記事：ニコニコ動画のsearch API仕様整理）](http://qiita.com/sampleb3/items/f75173167e22fbbe4d90)
ログインなしで使う為のPythonコードを書いた。

※既存の検索APIでは51ページ以上は取得できないが、この方法なら取得できると思われる。

#コード

```py:nc2xml.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# nc2xml.py
# Copyright (c) 2014 nezuq
# This software is released under the MIT License.
# http://opensource.org/licenses/mit-license.php

import sys
import time
import datetime
import urllib
import urllib2
from lxml import etree

argvs = sys.argv
argc = len(argvs)

#検索キーワード
KEYWORD = u'ｷﾏｼﾀﾜｰ'
if 1 < argc:
    KEYWORD = argvs[1].decode('utf-8')

#ソート基準
#SORT_TYPE = 'n' #最新コメント投稿日時
#SORT_TYPE = 'v' #再生数
#SORT_TYPE = 'm' #マイリスト
#SORT_TYPE = 'r' #コメント数
SORT_TYPE = 'f' #投稿日時
#SORT_TYPE = 'l' #再生時間
if 2 < argc:
    SORT_TYPE = argvs[2]

#対象ページ番号(ID取得開始ページ)
MIN_PAGENUMBER = 1
if 3 < argc:
    MIN_PAGENUMBER = int(argvs[3])

#対象ページ番号(ID取得終了ページ)
MAX_PAGENUMBER = 3
if 4 < argc:
    MAX_PAGENUMBER = int(argvs[4])

#検索方法
SEARCH_TYPE = 'tag' #タグ検索

def main():
    keyword = urllib2.quote(KEYWORD.encode("utf-8"))
    ids = []
    nrow_bef = -1
    npage = MIN_PAGENUMBER - 1
    while ((nrow_bef != len(ids)) and (npage < MAX_PAGENUMBER)):
        npage += 1
        uri = 'http://www.nicovideo.jp/%s/%s?sort=%s&rss=2.0&page=%d' % (SEARCH_TYPE, keyword, SORT_TYPE, npage)
        print u'動画ID問合せ中  ： ' + uri
        time.sleep(1)
        res = urllib2.urlopen(uri)
        rss = etree.fromstring(res.read())
        nrow_bef = len(ids)
        ids += map((lambda x: x.text.rsplit('/', 1)[1]), rss.findall('./channel/item/link'))
    query = 'http://i.nicovideo.jp/v3/video.array?v=' + ','.join(ids)
    print u'動画データ取得中 ： ' + query
    d = datetime.datetime.today()
    # ※問い合わせに20秒以上かかる場合はタイムアウトし、0件となる。
    # ※負荷がかかるクエリを発行するのはIPブロックやAPI封鎖の可能性もあるのでNG。
    time.sleep(1)
    urllib.urlretrieve(query, u'%s_%s.xml' % (KEYWORD, d.strftime('%y%m%d%H%M%S')))
    print 'end!'

if __name__ == '__main__':
    main()
```

```bash:nc2xml.pyを実行する。
python nc2xml.py "百合" m 1 3
```

#出力イメージ
http://i.nicovideo.jp/v3/video.array?v=sm9720246,sm19673281

#感想
百合文化発展のためにデータ分析しなきゃ……（使命感）

#参考ページ
[ -> ニコニコ動画のsearch API仕様整理](http://qiita.com/sampleb3/items/f75173167e22fbbe4d90)
[ -> i.nicovideo.jp APIとgetthumbinfo APIの比較](http://qiita.com/sampleb3/items/c56dc9deaf0dc4980107)
[ -> ニコニコ動画の検索APIについて調べたのでメモ](http://shouginekochann.blog9.fc2.com/blog-entry-151.html)
[ -> ニコニコ動画のタグ検索結果をRSSで取得する](http://appakumaturi.hatenablog.com/entry/2013/02/02/094356)
LinuxMintでGenymotionが起動しない場合の対処法

LinuxMintで爆速エミュレータと評判のGenymotionを使った開発環境を構築したのですが、少しハマったのでメモ。

#genymotionとは？
参考
その1：[GenymotionでAndroidの超爆速エミュレータ環境を構築する](http://dev.classmethod.jp/smartphone/android/genymotion-install/)
その2：[Genymotionで開発作業効率化d(๑╹ω╹๑ )-Qiita](http://qiita.com/mofmofneko/items/c7786bb087c759764e2b)

Android用の爆速エミュレータです。
2番目の方ではベンチマークが公開されてますが、実機の3倍近いとかとんでもないですね……。

ちなみにEclipseではADTのエミュレータと違い、実機として認識されます（仮想マシンなので当たり前ですが）。
ADTのエミュレータと違って過去にインストールしたアプリも残りますし、GooglePlayからのダウンロードなんかもできます。

#Linuxへのインストール方法
参考：[UbuntuでGenymotionをインストールして起動してみる](http://www.kkaneko.com/rinkou/js/vmandroid.html)
インストール方法は上記の記事を参考にしました。
OSはLinuxMint15で、同じUbuntu系という事もありフォルダの場所とかが少し違うぐらいで大体記事の通りでいけます。

あと、YoutubeでMintでのインストール方法を解説してくれてる方がいます。
解説は英語ですが、GUIでの操作ですのであまり不自由はしないかと。
https://www.youtube.com/watch?v=60Nf-Cl07q4

##「Unable to load VirtualBox Engine」とエラーが出る
Genymotionの起動まではできるのですが、Playを押してもしばらく待った後に「Unable to load VirtualBox Engine」と出て起動されません。
続くメッセージを見る限り、VirtualBoxのNetwork設定がおかしいというのはわかるのですが、何がおかしいのかわからない……。
一応、管理者権限でGenymotionを起動すれば動くのですがそれでは根本的解決になってません。


一番最初に紹介した記事では、

>※ Genymotion で「Unable to load VirtualBox Engine」と表示されたときの対処例
>もう一度「Play」ボタンをクリックしてみる
>それでもダメなときは、vboxdrv モジュール読み込み操作を手動で行なってみる
> sudo /etc/init.d/vboxdrv status
> sudo /etc/init.d/vboxdrv setup
> sudo /etc/init.d/vboxdrv status

と書かれていますが、それをやってもダメ。

###対処法
調べてて見つけたのが以下の記事でした。

[Genymotion起動時にエラーが出た時の対処法](http://blog.hello-world.jp.net/?p=1161)
ホストオンリーネットワークを削除してGenymotionを起動してPlay……動きましたヾ(*・ω・)ノ
念の為Eclipseからも試して見ましたが、ちゃんと動作する様子。

これで開発が捗ります(^q^)
segue による画面遷移メモ


## 参考資料

[StoryboardのUnwind Segueの使い方](http://dev.classmethod.jp/smartphone/iphone/ios_unwind-segue/)  

[Storyboard の画面遷移](http://d.hatena.ne.jp/hoshi_takanori/20131015/p1)  

[push segue と NavigationController メモ](http://qiita.com/qt6hy/items/7ed9adfc180adcf51f60)

## segue

### segue による画面遷移
1. [遷移元]- (BOOL)shouldPerformSegueWithIdentifier
    - 遷移するかどうかの判定
    - [identifier isEqualToString:@"id of segue"]
1. [遷移元]- (void)prepareForSegue
    - 遷移実行に伴う値のやり取り
    - [[segue identifier] isEqualToString:@"id of segue"])
1. （unwind segue なら）[遷移先]unwind segue メソッド（自分で定義したメソッド）
  - (IBAction)unwindSegueToXxx:(UIStoryboardSegue*)segue

### segue に id(identifier) を設定する

#### 通常の segue の場合
Storyboard 上で segue を選択して、identifier に文字列を入力します。

![スクリーンショット 2014-05-11 16.16.21.png](https://qiita-image-store.s3.amazonaws.com/0/30578/feec79b6-777b-f4c6-1390-5a1f44a47ee3.png "スクリーンショット 2014-05-11 16.16.21.png")

#### unwind segue の場合

![スクリーンショット 2014-05-11 16.23.10.png](https://qiita-image-store.s3.amazonaws.com/0/30578/f77aa87d-b192-18fd-ac08-1aaa3eb2db02.png "スクリーンショット 2014-05-11 16.23.10.png")

### modal segue で単に前の画面に戻る
下記自体は segue ではないので、前述した shouldPerformSegueWithIdentifier とか prepareSegue などは発生しない。
* [self dismissViewControllerAnimated:YES completion:NULL]


## 関連メモ
*  制御のために segue には identifier（文字列） を設定する。
*  modal segue を明示的に呼び出す: performSegueWithIdentifier

## 画面遷移に関連して UIViewController の関連メソッド
```objective-c
- (void)viewDidLoad
{
    // View が表示される最初の1回だけ呼ばれる
    NSLog(@"viewDidLoad");
}

- (void)viewWillAppear:(BOOL)animated
{
    // View が表示される直前に呼ばれる
    NSLog(@"viewWillAppear");
}

- (void)viewDidAppear:(BOOL)animated
{
    // View の表示完了後に呼ばれる
    NSLog(@"viewDidAppear");
}

- (void)viewWillDisappear:(BOOL)animated
{
    // View が別の View へ切り替わる直前に呼ばれる
    NSLog(@"viewWillDisappear");
}

- (void)viewDidDisappear:(BOOL)animated
{
    // View が別の View へ切り替わった後に呼ばれる
    NSLog(@"viewDidDisappear");
}

```

### 実際の呼び出しの流れ
最初の画面が 1stViewController、そこから modal で 2ndViewController を呼び出した時の流れ。

1. 最初の画面を表示
  1. -[1stViewConroller viewDidLoad]
  1. -[1stViewConroller viewWillAppear:] 
  1. -[1stViewConroller viewDidAppear:] 
2. modal segue で２番目の画面を呼び出す
  1. -[1stViewConroller shouldPerformSegueWithIdentifier:sender:] 
  1. -[1stViewConroller prepareForSegue:sender:] 
  1. -[2ndViewConroller viewDidLoad] 
  1. -[1stViewConroller viewWillDisappear:] 
  1. -[2ndViewConroller viewWillAppear:] 
  1. -[2ndViewConroller viewDidAppear:] 
  1. -[1stViewConroller viewDidDisappear:]
3. unwindSegue で最初の画面に戻る
  1. -[2ndViewConroller shouldPerformSegueWithIdentifier:sender:]
  1. -[2ndViewConroller prepareForSegue:sender:] 
  1. -[1stViewConroller unwindSegueTo1stViewConroller:]
  1. -[2ndViewConroller viewWillDisappear:]
  1. -[1stViewConroller viewWillAppear:] 
  1. -[1stViewConroller viewDidAppear:] 
  1. -[2ndViewConroller viewDidDisappear:]
UIAlertView で学ぶ protocol



## UIAlertViewDelegate protocol に対応することを宣言する
protocol を省略しても動作はする見たいだけど、明示的に書いておいたほうがいいですね。

```objective-c
// .h ファイル
// protocol は <> 内に書く。複数ある場合はカンマで区切る
@interface YourClass : NSObject <UIAlertViewDelegate>
@end
```

## UIAlertView の delegate メソッドを定義
```objective-c
// .m ファイル
// UIAlertView の delegate メソッド
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{ 
    switch ( alertView.tag )
    {
    case 0: // tag:0 の Alert
        if ( 0 == buttonIndex )
        {
            // [Cancel]処理
        }
        else
        {
            // [OK]処理
        }
        break;

    case 1: // tag:1 の Alert
        break;

    default:
        break;
    }


}
```

## UIAlertView を呼び出す部分

```objective-c
// .m ファイル
// ここでは、何らかのイベント時に Alert を表示するような流れ
- (IBAction)onTest:(id)sender
{
    // 利用箇所
    UIAlertView* alert = [[UIAlertView alloc]
                          initWithTitle:@"たいとる"
                          message:@"メッセージ"
                          delegate:self
                          cancelButtonTitle:@"Cancel"
                          otherButtonTitles:@"OK", nil];
    
    // Alert 識別のためのタグ設定
    alert.tag = 1;
    
    // 表示
    [alert show];

    // UIAlertView の show は同期待ちなどしません。
    // なので、show で表示後にすぐにここの行に到達します。
    // 画面が閉じた場合処理は delegate メソッドの方に記述します。

}

```

## 独自 protocol を作ってみる
``` objective-c

// .h
@protocol YourClassDelegate <NSObject>
 
- (void)yourClass:(YourItem*)newItem;
 
@end
 
@interface YourClass : NSObject
 
@property id<YourDelegate> delegate;
 
@end

```

``` objective-c

// .m
@implementation YourClass


- (void)method1
{
	// デリゲートが適切に設定されているかを確認して実行
	if ([self.delegate respondsToSelector:@selector(yourClass:)])
	{
		YourItem*		item = [YourItem new];	
 		[self.delegate yourClass:item];
    }
}

@end

```



## 関連リンク
[標準クラス(UIAlertView等)のdelegateをBlockで書く](http://qiita.com/ryota-ku/items/90f65a46336fcf686137)

[デリゲートを自作クラスに実装する](http://www.objectivec-iphone.com/introduction/delegate/delegate.html)
Javascriptのオブジェクト入門

## オブジェクトとは
Javascriptでは、変数型として、数値、文字列、真偽値、null、undefinedがあるが、これ以外の値は全てオブジェクトである。
Javascriptでは、配列も関数も、正規表現も全てオブジェクトである。

オブジェクトは、複数のプロパティを含むコンテナで、プロパティは名前と値で構成される。
プロパティ名は、任意の文字列が利用可能で **空文字も利用可能**である。
プロパティの値は、undefinedを除く全てのJavascriptの値をセット出来る。

### オブジェクトリテラル

オブジェクトリテラルは、2つの中括弧で囲まれ、その中に名前と値のペアが列挙されたもので、式が記述可能な場所であればどこでも記述出来る。
プロパティ名の前後に付けるクォート("")は、文字列が予約でなくでJavascriptの名前に則っていれば省略することが可能になる。
例えば、「first-name」の場合はクォートが必要だが「first_name」だったら省略可能。

```js
var stooge = {
    "first-name": "Hoge",  // クォートが必要
    "": "empty",           // プロパティ名は空文字も指定可能
    first_name: "Fuga"     // Javascriptの名前に則ってるのでクォート省略可能
};

console.log(stooge["first-name"]);  // Hoge
console.log(stooge[""]);            // empty
console.log(stooge["first_name"]);  // Fuga
console.log(stooge.first_name);     // Fuga

console.log(hoge["first-name"]); // hoge
```

### 値の取得

基本的に文字列を[]で囲んで指定することで、オブジェクトから値を取り出すことが可能。
もし文字列が文字列リテラルで、予約語でないJavascriptの名前のルールに則っているなら、[]の代わりに.を利用することも出来る。
.を使った方がシンプルですっきりするので好む人がおおい。

* 存在しないメンバを取得した場合は、undefinedが返される
* ||演算子を使って、デフォルト値を設定することが出来る
* undefinedに対して、さらにそのプロパティを取得しようとするとTypeError例外が投げられる。&&演算子を利用するとこの事態を防げる。

```js
var stooge = {
    "first-name": "Hoge",  // クォートが必要
    "": "empty",           // プロパティ名は空文字も指定可能
    first_name: "Fuga"     // Javascriptの名前に則ってるのでクォート省略可能
};

// 存在しないメンバを指定
console.log(stooge["middle-name"]); // undefined
console.log(stooge.firmily_name);   // undefined

// ||演算子でデフォルト指定
var middle = stooge["middle-name"] || "middle";
var firmily_name = stooge.firmily_name || "firmily";
                               
console.log(middle);         // middle
console.log(firmily_name);   // firmily

// undefinedに対してプロパティを取得しようとした時の例外を&&で防ぐ
console.log(stooge.hoge);         // undefined
console.log(stooge.hoge.fuga);    // TypeError例外が投げられる
console.log(stooge.hoge && stooge.hoge.fuga);         // undefined
```

### 参照

オブジェクトは参照渡しが行われて、コピーされることはない。

```js
 var x = {};
 x.nickname = 'hoge';
 var y = x;  // nicknameというプロパティを持ったxを参照することになる
 
 console.log(x.nickname); // hoge
 console.log(y.nickname); // hoge
 
 // 参照元のxの値を更新したので、yの値も変わる
 x.nickname = 'fuga';
 
 console.log(x.nickname); // fuga
 console.log(y.nickname); // fuga
```

### プロパティの列挙

for in文を利用すると、オブジェクト内に存在する全てのプロパティを取得することが出来る。

```js
var hoge = {
    first_name: "Hoge",
    last_name: "Fuga",
};
var name;
for (name in hoge) {
    console.log(name); // Hoge, Fuga
}
```

ただし、このfor in文の場合、プロパティの順序は保証されないので、保証したい場合はプロパティの順序を記述した配列を用意して、for文で回すしかない。

```js
var hoge = {
    first_name: "Hoge",
    last_name: "Fuga",
};

var i;
var properties = [
    'first_name',
    'last_name'
];

for (i = 0; i < properties.length; i++) {
    console.log(hoge[properties[i]]);
}
```
UITextField のキーボード非表示に関するメモ


## 一番シンプルな方法

### Storyboard アクションを使う
対象の UITextFiled の "Did End On Exit" アクションメソッドを追加して、そこに処理を追加する。すると Enter 押下時にキーボードが非表示になる。

```objective-c
// Storyboard アクションを使う
@interface ViewController : UIViewController
- (IBAction)onDidEndOnExit:(id)sender;
@end

- (IBAction) onDidEndOnExit:(id)sender {
    // 特にハンドラを設けるだけで、何もしなくてもキーボードが非表示になるみたい。
#if 0    
　　 [sender resignFirstResponder];
    //[self.view endEditing:YES]; // or これでもいいらしい
#endif
}
```

## UITextFieldDelegate を使う方法

```objective-c
// .h ファイル
// UITextFieldDelegate protocol を使う
@interface ViewController : UIViewController <UITextFieldDelegate>
@end

// .m ファイル
- (void)viewDidLoad
{
    // delegate 設定
	[self.textField setDelegate:self];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    return YES;
}

```

## おまけ：入力中に他の場所をタッチしたら、キーボードを消したい

#### GestureRecognizer を使う
1. 部品として ViewController に Tap GestureRecognizer を追加
1. Storyboard アクションを追加。（Ctrl押しながらドラッグとか）
   ![Tap.png](https://qiita-image-store.s3.amazonaws.com/0/30578/3d6a685d-bce6-f6b2-642a-942c65ef064f.png "Tap.png")

1. あとは、view の endEditing か UITextField が firstResponder なら、resignFirstResponder を呼び出すように書くだけ。

```objective-c
- (IBAction)onTap:(id)sender {
    [self.view endEditing:YES];
    
    // 以下のようにも書ける
    //if ( self.textField.isFirstResponder )
    //{
    //    [self.textField resignFirstResponder];
    //}
}
```
golang勉強メモ：変数宣言の省略形式と組み合わせ代入

変数宣言の省略形式では、変数のどれか一つが新しい変数でなければならない。すべてが新しい変数である必要はない。この点はvarと異なる。

```go
func main() {
    a, b := 1, 2
    println(a, b)
    // a, b := 1, 2
    //  => `no new variables on left side of :=`となる
    // var a, b, c int = 3, 4, 5
    // => `a redeclared in this block` となる
    a, b, c := 2, 3, 4
    println(a, b, c)
}
```

この例では、既存のa,bは単に代入となる。
ブロックの中ではスコープが異なるので別の変数となる。

```go
func main() {
    a, b := 1, 2
    println(a, b)
    {
        a, b, c := 3, 4, 5
        println(a, b, c)
    }
    println(a, b) // => 1, 2
}
```

関数の戻り値のパラメータに名前が付いていて、returnで戻り値を省略している場合に、戻り値のパラメータをスコープで隠してしまっていると、コンパイルエラーになってくれる。

```go
func main() {
    println(f())
}

func f() (a int) {
    {
        a, b := 1, 2
        println(a, b)
        // return
        // => `a is shadowed during return`となる
        return a
    }
}
```

あと、goで意味のないサンプルコードを書くのは難しい。
C#からC++のDLLを使う


Javaのコードばかり書いてたら、C#からC++のDLLを扱う場面で苦戦したのでメモをかねてまとめました。

**コメントの方でも別の方法の提案を頂いています。**

ミス等があればコメント・編集リクエスト願います。

* Visual Studio 2013
* C#は.NET Framework 4.5を使用

## DLL側

```cpp:mydll.h
extern "C" {
	__declspec(dllexport) int add(int a, int b);
	__declspec(dllexport) int* arr_a(int length);
	__declspec(dllexport) void arr_b(int* arr, int length);
}
```

__declspec(dllexport) はDLLで公開したい関数に必要。
extern "C" は、C++の仕様で関数名が変わってしまうのを防ぐ。


```cpp:mydll.cpp
#include "mydll.h"

int add(int a, int b) {
	return a + b;
}


int* arr_a(int length) {
	int* arr = new int[length];

	for (int i = 0; i < length; i++) {
		arr[i] = i;
	}

	return arr;
}


void arr_b(int* arr, int length) {
	for (int i = 0; i < length; i++) {
		arr[i] = i;
	}
}
```

なんてことのない、普通のプログラム。

## C#側

```csharp:Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

// DllImportに必要
using System.Runtime.InteropServices;

namespace UseMyDLL
{
	class Program
	{
		[DllImport("MyDLL.dll", CallingConvention = CallingConvention.Cdecl)]
		private extern static int add(int a, int b);

		// ポインタはC#側ではIntPtrに
		[DllImport("MyDLL.dll", CallingConvention = CallingConvention.Cdecl)]
		private extern static IntPtr arr_a(int length);

		[DllImport("MyDLL.dll", CallingConvention = CallingConvention.Cdecl)]
		private extern static void arr_b(IntPtr arr, int length);

		static void Main(string[] args)
		{
			callAdd();
			callArr_a();
			callArr_b();
		}

		// 戻り値がintの場合
		private static void callAdd()
		{
			int addResult = add(1, 2);

			Console.WriteLine("== add ==");
			Console.WriteLine(addResult + "\n");
		}

		// 戻り値がポインタの場合
		private static void callArr_a()
		{
			const int NUM = 5;
			int[] arr = new int[NUM];

			// 戻り値のポインタをIntPtrで受け取る
			IntPtr ptr = arr_a(NUM);

			// マネージ配列へコピー
			Marshal.Copy(ptr, arr, 0, NUM);

			// これでメモリが解放される？
			// (追記)さすがに駄目でした
			//Marshal.FreeCoTaskMem(ptr);

			Console.WriteLine("== arr_a ==");
			foreach(int n in arr)
			{
				Console.Write(n + " ");
			}
			Console.WriteLine("\n");
		}

		// 引数がポインタの場合
		private static void callArr_b()
		{
			const int NUM = 5;
			int[] arr = new int[NUM];

			// アンマネージ配列のメモリを確保
			IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int)) * NUM);

			// 引数でポインタを渡す
			arr_b(ptr, NUM);

			// マネージ配列へコピー
			Marshal.Copy(ptr, arr, 0, NUM);

			// アンマネージ配列のメモリを解放
			Marshal.FreeCoTaskMem(ptr);

			Console.WriteLine("== arr_b ==");
			foreach (int n in arr)
			{
				Console.Write(n + " ");
			}
			Console.WriteLine("\n");
		}
	}
}
```

## 実行結果

```
== add ==
3

== arr_a ==
0 1 2 3 4

== arr_b ==
0 1 2 3 4
```

うまく動いていそう
EPUB3を支える技術

EPUB3 は、当然ながら、既存のXHTML/XML技術を元に、仕様策定が進められました。
XHTMLは多くの人が知るものですが、メタデータや日本語関係のCSS3など、その背景が、Web業界からすると有名でないものも多いように思います。

ここでは、以下のような事を書こうと思います。決して、EPUB3 を支える技術を網羅的に書いたわけでは無いので、ご了承下さい。
（何か、追加や誤りの訂正があれば、歓迎します。）

* Dublin Core
* DCMI Metadata Terms
* Schema.org
* wiriting-mode
* CSS Text Level 3


Dublin Core
===========
Dublin Core（ダブリンコア）は、メタデータの代表的な仕様。タイトルや作者情報などを記載できる。Dublin Core Metadata Initiative が策定を行う。
OPFファイルで、タイトルなどを記述するのに使う。大元となる、Dublin Core の仕様では、[基本的な15項目のみ](http://dublincore.org/documents/dces/)が定義されている。

DCMI Metadata Terms
===================
より詳細な情報・型などが定義される。
EPUB3では、サブタイトルなど Dublin Core に無い部分を定義するために使われる。
http://dublincore.org/documents/dcmi-terms/

Schema.org
==========
Web では、Dublin Core よりもこちらの方が有名かもしれない。Google のSEOなどでは、おなじみのメタデータ。EPUB3では、あまり使われていなかった。しかし、EPUB3.0.1では、[Reserved prefixとして、追加されている](http://www.idpf.org/epub/301/spec/epub-changes.html#sec-pub-reserved-prefixes)。

writing-mode
============
これは有名なスタイルだと思うが、縦書きやアラビア語圏のrtolなどを実現するためのスタイル。現在（2014/04）でも仕様策定が進行中のため、EPUB3では、当時のドラフト仕様を採用した。
[EPUB Content Documents 3.0](http://www.idpf.org/epub/30/spec/epub30-contentdocs.html#sec-css-writing-modes)の仕様書では、[CSS3WritingModes-20110428](http://www.idpf.org/epub/30/spec/epub30-contentdocs.html#refCSS3WritingModesModule-dated)を参照している。これは、最新のドラフトと一部の値が変わっている。そのため、EPUB3 上は、`-epub-`のprefixを付けることになっている。

CSS Text Level 3
================
いわゆる、CSS3 と言われるものの一部。ただし、CSS3 Text は、あまり、目立っていないかも知れない。
http://www.idpf.org/epub/30/spec/epub30-contentdocs.html#sec-css-text
同じく、`-epub-`のprefixを付けることになっている。以下がEPUB3で参照する対象。

* -epub-hyphens*
* -epub-line-break
* -epub-text-align-last
* -epub-text-emphasis
* -epub-text-emphasis-color
* -epub-text-emphasis-style
* -epub-word-break
ELB経由でもallow fromでクライアントIPのチェックが出来るようにする

ELB経由だとREMOTE_ADDRがELBのVPC内ローカルIPになってしまうので、単純なallow fromでのアクセス許可が効かず、X-Forwarded-ForヘッダをSetEnvIfやRewriteCondとかでチェックする必要があって面倒です。

# X-Forwarded-Forを信頼させる

httpd-2.4からは[mod_remoteip](http://httpd.apache.org/docs/current/mod/mod_remoteip.html)ってのが使えるようになっているので以下の設定を書くことでいい感じにしてくれます。ちゃんと、信頼できる接続元（VPC内のローカルIP）のヘッダだけを信頼するということが出来ていい感じです。

```text:httpd.conf
# ELB経由でもallow fromで元IPをチェックできるようにする
RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxy 10.0.0.0/8
RemoteIPTrustedProxy 172.31.0.0/16
```

# おまけ
## AmazonLinuxで php-5.5 + httpd-2.4 を使えるようにする手順
AmazonLinuxの現在のデフォルトではphp-5.3とhttpd-2.2なので、僕はいつも最初に↓こんな感じにyumで両者を最新に上げてます。

```bash:
sudo yum remove httpd-tools php[0-9]\* php-\*
sudo yum install php55 php55-cli php55-gd php55-mbstring php55-mcrypt php55-mysqlnd php55-pdo php55-pecl-apc php55-pecl-imagick php55-pecl-memcached php55-pgsql
```

これでPHPは`php55-*`系に、httpdは`http24-*`系のパッケージに入れ替わります。あと大体良く使うphpモジュールも一緒に入れちゃいます。
ちなみにhttp24でmod_sslを使いたい場合はmod24_sslみたいに`mod24_*`て名前のパッケージが用意されてます。
Unityのキャラ移動いろいろ

Unity2D

### キーボードの入力に応じて Direction を決定して、GameObject の velocity を変化させることで移動させる

```csharp
public class Player : MonoBehaviour {

	public float speed = 5;
	// Use this for initialization
	void Start () {
	}
	
	// Update is called once per frame
	void Update () {
		float x = Input.GetAxisRaw ("Horizontal");
		float y = Input.GetAxisRaw ("Vertical");
		Vector2 direction = new Vector2 (x, y).normalized;
		rigidbody2D.velocity = direction * speed;
	}
}

```
macosxのphpにmcryptをインストール

#MacOSXのphpにmcryptをインストール

##なぜ
laravelをインストールすると

```zsh
Mcrypt PHP extension required.
Script php artisan clear-compiled handling the post-install-cmd event returned with an error

[RuntimeException]
Error Output:

```
mcrtptの所でエラーになる

```zsh
$php -m | grep mcrypt
```

phpにmcryptがインストールされていない

###なので、MacOSXにphpのmcryptをインストール

OSXバージョン     :10.9.2
phpバージョン     :PHP 5.4.24 (cli) (built: Jan 19 2014 21:32:15)
Homebrewバージョン:Homebrew 0.9.5

```zsh
$brew search mcrypt
libtomcrypt   mcrypt php53-mcrypt  php54-mcrypt	php55-mcrypt  php56Zmcrypt
$brew install php54-mcrypt
$php -m | grep mcrypt
mcrypt
```

インストールされた。

laravelも無事インストールされた。
OK
Deviseでpassword_confirmを入力しない方法


## 目的
ユーザー登録時にパスワード確認を入力しないフォームを実現したい。
なにかスマートなやり方があるかも知れますが、とりあえずの対応です。

## 解決方法
とりあえず、登録前にpassword_confirmフィールドにpasswordを代入する。

```rb:obotframeworkb:users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
  before_action :set_password_confirmation! , only: [:create]

  private
  def set_password_confirmation!
    params[:user][:password_confirmation] = params[:user][:password]
    @para = params
    pry
  end
end
```

```rb:routes.rb
#上書きしたいコントローラーを設定
  devise_for :users , :controllers => {
                      :registrations => 'users/registrations' ,
                      :sessions => 'users/sessions'
                    }
```
Volleyを使ってpatchメソッドを利用する方法

Volley利用する際にはシングルトンで利用するため、こんな感じのクラスを用意していると思います

```java:VolleySingleton.java
public class VolleySingleton {
    private static VolleySingleton mInstance = null;
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
 
    private VolleySingleton(){
        mRequestQueue = Volley.newRequestQueue(MyApplication.getAppContext());
    }

    public static VolleySingleton getInstance(){
        if(mInstance == null){
            mInstance = new VolleySingleton();
        }
        return mInstance;
    }
```

Volleyでpatchメソッドに投げると

>com.android.volley.NoConnectionError: java.net.ProtocolException: Connection already established
>	at >com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:134)
>	at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:110)
>Caused by: java.net.ProtocolException: Connection already established
>	at java.net.HttpURLConnection.setRequestMethod(HttpURLConnection.java:633)
>	at >com.android.volley.toolbox.HurlStack.setConnectionParametersForRequest(HurlStack.java:227)
>	at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:106)
>	at >com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:93)
>	... 1 more

ネットワークプロトコルが正しく実行できなかったよ的な例外が発生します。

対応としてはRequestQueueの作成にcom.android.volley.toolbox.HttpStackを利用します。

```java:VolleySingleton.java
public class VolleySingleton {
    private static VolleySingleton mInstance = null;
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
 
    private VolleySingleton(){
        String ua = "user_agent";
        HttpStack httpStack = new HttpClientStack(AndroidHttpClient.newInstance(ua));

        mRequestQueue = Volley.newRequestQueue(MyApplication.getAppContext(), httpStack);
    }

    public static VolleySingleton getInstance(){
        if(mInstance == null){
            mInstance = new VolleySingleton();
        }
        return mInstance;
    }
```

これでpatchメソッドのurlにリクエストしても例外が発生せずにレスポンスを取得することができます。

※ソース切り貼りしてるので動作確認してません

参考
http://stackoverflow.com/questions/22411475/android-volley-http-patch-request
macにbrewでいれたmongodbが突然動かなくなった人のためのヒント

はまったのでメモ。

ふと思い立って

```
$ brew update
$ brew upgrade
```

とかやりますよね。僕はやります。そしておもむろにmongodbを起動するわけですよ。

```
$ mongod
```

すると

```
2014-04-29T16:36:23.567+0900 [initandlisten] exception in initAndListen: 10296
*********************************************************************
 ERROR: dbpath (/data/db) does not exist.
 Create this directory or give existing directory in --dbpath.
 See http://dochub.mongodb.org/core/startingandstoppingmongo
*********************************************************************
, terminating
```

▂▅▇█▓▒░(’ω’)░▒▓█▇▅▂うわあああああああ

/data/dbが無いと怒られています。ごめんなさい。すいません。

あ、ちなみにバージョンはこんな感じです。

```
$ mongod --version
db version v2.6.0
$ brew --version
0.9.5
```

まぁ、単純に /data/db ディレクトリを作ってmongodすれば解決なのですが、
じゃぁ、前まで動いていた古いデータはどこにあるのん？という話ですよ。というか、古いデータ使えないといろいろ辛いじゃないですかーやだー。

で、いろいろ調べたら古いデータは以下にありますた。

*/usr/local/var/mongodb/*

場所さえわかればこっちのもの。起動オプションなりmongod.confなりで指定して起動すればいいだけです。

```
$ mongod -dbpath /usr/local/var/mongodb
```

あ、僕は起動オプションつけるのすら面倒なので、/data/dbにシンボリックリンク貼りました。

```
$ sudo mkdir /data
$ sudo chmod 777 /data
$ ln -s /usr/local/var/mongodb /data/db
```

これで単純に mongod ってたたけばmongodbが起動します。めでたしめでたし。


ちなみに、もしかして……とおもって調べてみたら古いmongod.confは案の定 */usr/local/etc/mongod.conf* にありましたとさ。


めでたしめでたし。

尾張。