OmniAICreator/Qiita-1.07M huggingface dataset:
【Ruby】構文とメソッドのループ書き換えメモ


以降使う配列サンプル

```rb
pcs = [ { :os  => "Windows", :ver => ["XP", "7"] },
        { :os  => "Mac", :ver => ["OS X v10.8", "OS X v10.9"] } ]
```

##### 要素を順に取り出す
何の捻りも無いfor文。

```rb
for num in 0..pcs.length do
  puts pcs[num]
end
```

for文を書き換えただけの何の変哲もないeach文。

```rb
pcs.each do |pc|
  puts pc
end
```

↓出力結果

```
{:os=>"Windows", :ver=>["XP", "7"]}
{:os=>"Mac", :ver=>["OS X v10.8", "OS X v10.9"]}
```

##### 要素とindexを繰り返し取得する

この配列pcからOS名とバージョンを取得するとき、下のように構文とメソッド使っても取得できます。

```rb
length = 0
while length < pcs.length do
  pcs.each do |pc|
    puts "OS:#{pc[:os]}"
    puts pc[:ver]
    puts "-----"
  end
  length += 1
end
```

これを[each_with_index](http://ref.xaio.jp/ruby/classes/enumerable/each_with_index)を使ってメソッドのみで書き換え。

```rb
pcs.each_with_index do |pc, length|
  puts "OS:#{pc[:os]}"
  puts pc[:ver]
  puts "-----"
end
```

↓出力結果

```
OS:Windows
XP
7
-----
OS:Mac
OS X v10.8
OS X v10.9
-----
```

下のような書き換えでも同じ出力結果が得られます。

```rb
pcs.each_with_index do |pc, length|
  puts "OS:#{pc[:os]}"
  pc[:ver].length.times.each do |size|
    puts pc[:ver][size]
  end
  puts "-----"
end
```

`pc[:ver].length.times.each do |size|` の部分は単純にpc[:ver]の長さ分要素を繰り返しているだけです。
ちなみにこう(↓)すると

```rb
puts "方法1"
pcs.each_with_index do |pc, length|
  puts "OS:#{pc[:os]}"
  puts "Ver:#{pc[:ver]}"
  puts "-----"
end

puts "方法2"
pcs.each_with_index do |pc, length|
  puts "OS:#{pc[:os]}"
  pc[:ver].each do |v|
    puts "Ver:#{v}"
  end
  puts "-----"
end
```

こう(↓)なります。

```
方法1
OS:Windows
Ver:["XP", "7"]
-----
OS:Mac
Ver:["OS X v10.8", "OS X v10.9"]
-----

方法2
OS:Windows
Ver:XP
Ver:7
-----
OS:Mac
Ver:OS X v10.8
Ver:OS X v10.9
-----
```
社内エンジニアのアウトプットを促進するため、各スタッフのQiita投稿／ストック数をChatworkに送りつけるボットを作る


# 前提

僕の所属している会社では、[Qiita Organization](http://qiita.com/organizations)に企業登録してます。理由としては、アウトプットの奨励であったり、企業ブランディングであったりです。まぁそれは置いといて。

Qiita Organizationで、なにができるかというと、単純に会社に所属しているメンバーを追加することぐらいで、特別な機能があるわけじゃないんですが、社内のエンジニアにQiita投稿を楽しんでやってもらえるキッカケ作りとして取り組んでます。

## やりたいこと

というわけで前置きが長くなりましたが、投稿モチベーション維持のため、社内エンジニアのQiita投稿数／獲得ストック数を毎日クロールして、Chatworkのグループに送りつけることで、Qiitaスペックの見える化をしたい。

### クロール対象ページ

- http://qiita.com/organizations/basicinc/members

### 使うもの

- kimono https://www.kimonolabs.com/
- PHP
- Chatwork API

# kimonoを使って、WebページをAPI化

一番面倒くさいの、ページから各ユーザ名と数値を取得する部分。だけど、今はkimonoっていう凄いやつがいるので使ってみます。こいつは、指定したWebページを勝手にクロールして、JSON形式とかでリクエストできるAPI化してくれちゃいます。便利。

## ブックマークレットで該当ページを編集

言葉で説明すると、なんか面倒っぽいけど、実際は5分もかからずいけます。

![メンバー_-_株式会社ベーシック___Qiita.png](https://qiita-image-store.s3.amazonaws.com/0/2152/b44bfd42-c473-70e4-70df-e577fcc2af17.png "メンバー_-_株式会社ベーシック___Qiita.png")

該当ページでブックマークレットを実行し、編集画面にします。

![メンバー_-_株式会社ベーシック___Qiita 2.png](https://qiita-image-store.s3.amazonaws.com/0/2152/bcece726-b311-4cf4-0a80-53f270700f43.png "メンバー_-_株式会社ベーシック___Qiita 2.png")

ユーザ名のリストがほしいので、ユーザ名の場所をおもむろにクリックします。ユーザ名の箇所全体が黄色にマーキングされるので、チェックアイコンをクリックして、全要素を追加してください。左上が要素の数表示されます。

そして左上に「user」というプロパティ名を入力します。

![メンバー_-_株式会社ベーシック___Qiita 3.png](https://qiita-image-store.s3.amazonaws.com/0/2152/caa3241a-150b-5bc4-6e1d-73c1c3b35a08.png "メンバー_-_株式会社ベーシック___Qiita 3.png")

今度は、右上の「＋」ボタンを押して新しいフィールドを設定します。

![メンバー_-_株式会社ベーシック___Qiita 4.png](https://qiita-image-store.s3.amazonaws.com/0/2152/f421f56b-f34a-2b2a-c096-346bcf69618e.png "メンバー_-_株式会社ベーシック___Qiita 4.png")

続いて、投稿数とストック数を同様にクリックします。あとは保存すればOK。クロールするタイミングも柔軟に設定可能。今回は1日に1回にしました。

# PHPでAPIアクセスして、chatworkのAPIで投稿

本当はHerokuとかでやりたかったんですが、計画実行のクレカ登録とか面倒だったので、余っているサーバのcrondで動かすことにしました。超絶面倒くさいので、色々糞なコードですが。

```qiita.php
<?php
// kimonoで作ったAPIのURL
$uri = 'https://www.kimonolabs.com/api/example?apikey=hogehoge';
$json = json_decode(file_get_contents($uri));

// Chatworkに投稿するためのメッセージ作成
$message = <<<EOM
[info][title]今日のQiita[/title]
今日のQiitaの投稿数とストック数だよ。
EOM;

$topStock = 0;
$topUser = '';
foreach ($json->results->collection1 as $val) {
	$val->stock = htmlentities($val->stock, null, 'utf-8');
	list($posts, $stock) = explode('|', str_replace(array(' ', '&nbsp;', 'posts', 'post', 'stocked', "\n"), "", $val->stock));
	$message .= $val->user->text . " ： " . $posts . "投稿 / " . $stock . "ストック\n";
	if ($topStock < $stock) {
		$topStock = $stock;
		$topUser = $val->user->text;
	}
}

$message .= <<<EOM

現時点のトップは、{$topUser}です
[/info]
EOM;

system('curl -X POST -H "X-ChatWorkToken: 【ChatworkのAPIキー】" -d "body=' . $message . '" "https://api.chatwork.com/v1/rooms/【ルームID】/messages"');
```

これで、指定チャットにたいして投稿できます。あとはcrondで1日1回設定すればOK。

![スクリーンショット 2014-08-01 16.02.43.png](https://qiita-image-store.s3.amazonaws.com/0/2152/44c75303-590a-2be5-8e3e-54bb6b28e394.png "スクリーンショット 2014-08-01 16.02.43.png")
さくらインターネットでのDBバックアップ方法

とある案件で、CMSのデータベースのバックアップを定期的に取りたかったのだが

さくらインターネットだと、

2.2. プログラムのコマンドパス
には、mysqldumpのコマンドパスがないようなので、
http://support.sakura.ad.jp/manual/rs/tech_cgi.html


こちらの記事を参考に(shはサポートしているので)
http://wataame.sumomo.ne.jp/archives/1482
http://nintenman.n-wii.net/other/73

シェルスクリプトを作成し、cronで１日１回叩く。
goのimport宣言

さり気ないけれどGoで
`import`を宣言するとき、頭に`.`や`_`や名前をつけることが出来る。
それを使ってパッケージのメソッドにアクセスする。

```go
package main

import (
  "fmt"
  . "fmt" // Println
  _ "fmt" // 利用なし
  f "fmt" // f.Println 
)

func main() {
  fmt.Println("Hello World") // Hello World
  Println("Hello World")     // Hello World
  f.Println("Hello World")   // Hello World
}
```

ちなみに `_`は、そのファイルでは使わないけれど、他パッケージで利用したい場合に使う。

# 参考

* [Import declarations - The Go Programming Language Specification](http://golang.org/ref/spec#Import_declarations)
Fluentd の debug_agent 経由で ruby-prof を起動する

Fluentd の debug_agent (druby) 経由で RubyProf.start/stop できるようにして、任意のタイミングで外からプロファイラを起動/終了できるようにしたい。

## Fluentd の設定

ruby-prof gem を入れておく

```
$ fluent-gem install ruby-prof
```

debug_agent を起動するようにしておく

```
# fluent.conf
<source>
  type debug_agent
  bind 127.0.0.1
  port 24230
</source>
```

## fluent-debug で外からつなぐ

```
$ /usr/lib/fluent/ruby/bin/fluent-debug -p 24230
```

irb に次のコードを打ち込んで RubyProf を start できる

```rb
code = <<-CODE
require 'ruby-prof'
RubyProf.start
CODE
Engine.method_missing(:instance_eval, code)
```

終了させ、同時にファイルに吐き出すには次のようにする


```rb
code = <<-CODE
result = RubyProf.stop
File.open('/tmp/foo.txt', 'w') {|f|
  RubyProf::FlatPrinter.new(result).print(f)
}
CODE
Engine.method_missing(:instance_eval, code)
```

## fluent-rubyprof

上記のコードを毎回コピペするのも馬鹿らしいので、fluent-rubyprof というコマンドを作った。 => https://github.com/sonots/fluent-rubyprof

```
$ fluent-gem install fluent-rubyprof
```

してもらって

```
$ fluent-rubyprof start -p 24230
```

で RubyProf を start して、

```
$ fluent-rubyprof stop -p 24230 -o /tmp/fluent-rubyprof.txt
```

で停止＆出力できる。
Windowsのconsoleでutf-8 + ansi colorを出力したいときのラッパー

```py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import subprocess

reload(sys) 
sys.setdefaultencoding("utf-16")

HAS_COLORAMA = True

try:
  import colorama
  colorama.init()
except:
  HAS_COLORAMA = False

p = subprocess.Popen(sys.argv[1:], stdout=subprocess.PIPE)

def decode_ansi(s):
  assert s[0] == '[', "string does not start with control sequence"
  for i in range(1, len(s)):
    if s[i] == 'm':
      break

  return s[i+1:], s[1:i].split(';')

for line in p.stdout:
  substrs = line.split(chr(27))
  sys.stdout.write(substrs[0].decode('utf-8'))
  for s in substrs[1:]:
    s, cs = decode_ansi(s)
    if HAS_COLORAMA:
      sys.stdout.write("\033[%sm" % ';'.join(cs))
    sys.stdout.write(s.decode('utf-8'))
```
Herokuでmemcachedを使う

ローカルでmemcachedが動いてる状態からHerokuのAdd-on追加して本番で動かすまで

##Herokuのadd-onにあるmemcachedは２種類
* [Memcachier](https://addons.heroku.com/memcachier)
* [Memcached Cloud](https://addons.heroku.com/memcachedcloud)

今回は無料で25MBメモリのあるMemcached Cloud を使う

##クレジットカード情報登録
Add-onを を使うには無料でもクレジットカード登録が必要
マイページのAccountから登録
https://dashboard.heroku.com/account 

##Add-on 追加
これにそってやる
https://devcenter.heroku.com/articles/memcachedcloud

####1.Add-on追加

```ruby
$ heroku addons:add memcachedcloud:25
Adding memcachedcloud:25 on {APP_NAME}... done, v9 (free)
Use `heroku addons:docs memcachedcloud` to view documentation.
```

####2.Herokuのアプリ設定ファイルに追加されたか確認

```ruby
$ heroku config
=== {APP_NAME} Config Vars
.
.

MEMCACHEDCLOUD_PASSWORD:     文字列文字列
MEMCACHEDCLOUD_SERVERS:      文字列文字列
MEMCACHEDCLOUD_USERNAME:     文字列文字列
.
.

```
`MEMCACHEDCLOUD_PASSWORD`,`MEMCACHEDCLOUD_SERVERS`,`MEMCACHEDCLOUD_USERNAME`が追加されている

####3.ソース修正しデプロイ

```ruby:production.rb
.
.

if ENV["MEMCACHEDCLOUD_SERVERS"]
    config.cache_store = :dalli_store, ENV["MEMCACHEDCLOUD_SERVERS"].split(','), { :username => ENV["MEMCACHEDCLOUD_USERNAME"], :password => ENV["MEMCACHEDCLOUD_PASSWORD"] }
end
.
.
```
heroku configにある`MEMCACHEDCLOUD_PASSWORD`,`MEMCACHEDCLOUD_SERVERS`,`MEMCACHEDCLOUD_USERNAME`
をいれる


####4.起動確認

```$ heroku addons:open memcachedcloud```
ブラウザに起動状況とリソース状況が表示される
StatusがACTIVEなら起動中
  
  
  
以上
運用中のAPIに対するリクエストがこけていた場合にログから抜き出してリトライするワンライナー


# ユースケース

（自社サービスのドメインが`http://example.com`として）

- 特定APIに対するリクエスト`http://example.com/api/v1/items`が失敗しているようだった。
- リクエストを再現してみたい／もしくは問題と思われる箇所を修正したので再度リクエストを流したい

ような時。

# やってみる

### アクセスログ（/var/log/nginx/access.log）

```
93.184.216.119 - - [08/Apr/2014:11:30:15 +0900] "GET /api/v1/items HTTP/1.1" 500 4373 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36"
```

例えばこんなログがあった場合。

### 任意のログを抜き出して、リクエストをリトライ

```
$ cat /var/log/nginx/access.log |grep "/api/v1/items" | awk '{print "curl -i \"http://example.com" $7 "\" >/dev/null"}' | bash

% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
105  1270  105  1270    0     0   6337      0 --:--:-- --:--:-- --:--:-- 12828
```

これで

`http://example.com/api/v1/items`

のリクエストたちをリトライできます。

見ての通りですが、リトライしたいログの抜き出しパターンの匙加減は`grep "/api/v1/items"`にて。


デバッグ時のお供に。
Githubでコミット時に、匿名アカウントになってしまう

#現象

Githubにcommit+pushしても、自分のアカウントとして認識してくれない。
Githubにログインして直接コミットしたら、ちゃんと認識してくれる。

![skitch-スクリーンショット_2014-08-01_14_54_26.png](https://qiita-image-store.s3.amazonaws.com/0/47881/d5beb1cc-41bc-8651-afb5-36389085f55a.png)

pushできるってことは、アカウントを認識してるからじゃないの？？って不思議になった。


#対処方法


commitの詳細ページをみたら、どうやらcommit時のメールアドレスが知らないアドレスだよって言われてる。

![skicth^スクリーンショット_2014-08-01_14_54_49.png](https://qiita-image-store.s3.amazonaws.com/0/47881/57e943c5-a90f-80c5-1ffe-df8ffe317ad2.png)

つまり、commit時のメールアドレスでアカウントを判定しているようだ。

なので、解決方法としては、

1. commit時のメールアドレスをGithub側に登録してあげる


2. commit時のメールアドレスをGithubアカウントに設定済みのメールアドレスに変える

```
git config (--global) user.email="Githubに登録済みのアドレス"
 ```

のいずれかで解決する。

#その他

気になった試したのだが、commit時のメールアドレスを他人のものにしてcommitすると、他人のcommitとして登録されてしまう。
Githubの問題というよりGit自体がそういう仕様なのだからしょうがないのだろうか。
Objective-C 使って、Swiftにかわった時にハマりそうところまとめ

自分でswift本よんで、実際にプロジェクト使う時ハマるかもしれないところをまとめてみました(追加していく予定)。
# Selector

swiftには @selectorがない、stringはそのままにSelectorになる(自動変換)
performSelector: も使えない、代わりに"?"を使う

```swift
let mySelector: Selector = "tappedButton:"

myButton.addTarget(self, action: "tappedButton:", forControlEvents: .TouchUpInside)
```

# NSError point
NSError ** swiftでは使えない。代わりにNSErrorPointerを使う

```swift
var writeError: NSError?
let written = myString.writeToFile(path, atomically: false,
    encoding: NSUTF8StringEncoding,
    error: &writeError)
if !written {
    if let error = writeError {
        println("write failure: \(error.localizedDescription)")
    }
}
```
# Closures  _block
objective-c block使ってるとき block内でblock外の変数値変えるできるにするためには 変数に _blockにつける必要ある。
それがswiftの Closuresではデフォルトの仕様になってます。つまり変数に_blockつけなくても変えるようになった.

# if ([obj isKindOfClass:[Foo class]]) { … })
```swift
var someValue : Any?
 
someValue = "String"
 
if someValue is String {
    println("someValue is a String")
} else {
    println("someValue is something else")
}
```
【Git】ローカル環境にリモートリポジトリを置く方法 (Mac)

共同作業をしていて、GitHubやGitLabにまだ開発環境が整っていないときは、ローカル環境にリモートリポジトリを設置すると作業が捗ります。

一人で何か作業したいな〜って時にもいいかもしれません。

##前提
* リモートをする側とされる側がSSH接続が可能
* リモートをする側とされる側が同じネットワークにある

多分これが確認出来ていれば、大丈夫。おそらく・・・

##リモートリポジトリを設置する側のPCの設定をする
* 設定 -> 共有 -> リモートログインにチェックを入れる

![スクリーンショット-2014-07-31-17.20.02（2）.png](https://qiita-image-store.s3.amazonaws.com/0/48677/2f5607c3-37bb-1e47-e61f-95617a868493.png)

##リモートリポジトリ置き場を作成
* 設置したい場所にリモートリポジトリのディレクトリを作成

```
mkdir repository //ディレクトリの作成
cd repository //ディレクトリの移動
```

* ○○.gitディレクトリを作成して、共有用ベアリポジトリを作成します

```
mkdir project.git //ディレクトリの作成
cd project.git //ディレクトリの移動
git init --bare --share //共有用ベアリポジトリの作成
```

> --bareはリモートリポジトリだよというオプション

####権限が必要なディレクトリの場合
User直下など権限が必要なディレクトリにリモートリポジトリを設置する場合には、`sudo`コマンドが必要になることがあります。
また、リモートリポジトリ用のディレクトリに`chown`コマンドで所有者を設定してあげる必要があります。

```
sudo chown USER:USER /repository
```

##作業ディレクトリに移動してpushする
リモートが空の状態なので、適当にpushしてみましょう。

```
cd //作業ディレクトリに移動
git init //リポジトリの作成
git remote add origin ssh://USER_NAME@SERVER_NAME:PORT/共有用リポジトリまでのパス/repository/project.git //リモートリポジトリの設定
touch README.md //ファイルの作成
git add .
git commit -m "first commit"
git push origin master
```

#####sshのユーザーネームとサーバーネームがよく分からない場合は、「設定 -> 共有」から確認できます。

![スクリーンショット-2014-07-31-17.20.02（3）.png](https://qiita-image-store.s3.amazonaws.com/0/48677/d25f5a9a-7555-9b49-6f85-4f7c97f29b64.png)

#####port番号は、ネットワークユーティリティから調べることが出来ます。
Finderの検索から「ネットワーク」と入力 -> ネットワークユーティリティを選択 ->「Portsscan」からIPアドレスを入力して確認

![スクリーンショット-2014-07-31-21.18.01（4）.png](https://qiita-image-store.s3.amazonaws.com/0/48677/54b04faa-38d5-3453-407f-e5fedd931e88.png)


##あとはcloneすればOK
ここまで準備が終われば、他のPCからでも使う事ができます。

```
git clone ssh://USER_NAME@SERVER_NAME:PORT/共有用リポジトリまでのパス/repository/project.git
```

##参考
* [【Git】ローカルリポジトリからリモートリポジトリ、環境作成方法](http://parrot.hatenadiary.jp/entry/20101202/1291260115)
* [リモートリポジトリを置く](http://blog.peacois.me/archives/32)
Vagrant仮想マシン上のnode/http-serverとKarma-Jasmineをホストマシンからブラウザで見る

AngularJSのTutorialをやるのに、とりあえず仮想マシン上でチュートリアルを進めるのに必要になりました。

```ruby:Vagrantfile
...
  config.vm.network :forwarded_port, guest: 8000, host: 8000
  config.vm.network :forwarded_port, guest: 9876, host: 9876
...
```

これで

- `http://localhost:8000/app/index.html`にアクセスすればAngularJS Tutorialのページにアクセスでき、
- `http://localhost:9876`にアクセスすればテスト結果のページにアクセスすることができます。
devstackのscreenのhardstatusを変更する

devstackのhardstatusがいまいち見にくいので変えたかった。localrcで変更できる：

```
SCREEN_HARDSTATUS='%{= .b}%-Lw%{=b .r}%>%n%f %t*%{= .b}%+Lw%< %-=%{g}(%{d}%H/%l%{g})'
```
iOSのメッセージアプリ風のテキスト入力UIの実現方法(iOS7)

iOSのメッセージアプリの以下のような挙動を真似したい。

1. キーボード上部からの下ドラッグに合わせてキーボードが隠れる。
ドラッグを上に戻すと、キーボードを隠す途中でもキャンセルできる

2. メッセージ入力ボックスは、入力フォーカスを持たない状態では画面最下部にドックされているが、
フォーカスを持った状態だと、キーボードの上部に配置され、常に表示される。


1.についてはコンテンツを表示する UIScrollView の keyboardDismissMode プロパティをUIScrollViewKeyboardDismissModeInteractive に設定してやればよい。

2.については、UIKeyboardWillShowNotification 等を通知を捕まえて、メッセージ入力ボックスをキーボード表示アニメーションに合わせて移動させる方法があるが、厳密にキーボードアニメーションに追従させないと、アニメーション中にメッセージボックスとキーボードの間に隙間ができるため見た目が悪い。なにより面倒くさい。。


上記解決するため、以下方法を用いた。([Stackoverflow のこちら](http://stackoverflow.com/questions/19764293/inputaccessoryview-docked-at-bottom)を参考にさせていただいた)


- **UIViewControllerの** inputAccessoryView で入力ボックス（UITextField, UITextArea 等を含む任意のビュー）を返す

- **UIViewControllerの** canBecomeFirstResponder メソッドをオーバーライドする。

「UIViewControllerの」というところがポイントである。標準キーボード上部に任意のビューを配置する方法として UITextField 等の inputAccessoryView をオーバーライドする方法が一般的であるが、今回の場合は UIViewController で行っている。

また、入力ボックスとして返すビューは **UIViewController のルート view 階層には含めない**。
(含めるとキーボード非表示時に画面下部にドックしない)

```objc

#import "DebugViewController.h"

@interface DebugViewController () <UITextFieldDelegate>

@property(nonatomic, weak) IBOutlet UIScrollView *scrollView;

// テキスト入力ボックス
@property(nonatomic, weak) IBOutlet UITextField *textField;

// キーボード上部に表示する、textField を含むビュー. UIViewController.view のビュー階層に置かずに、強参照にする.
@property(nonatomic, strong) IBOutlet UIView *textFieldContainer;

@end

@implementation SBDebugViewController {
    BOOL _showInputView;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    _textField.delegate = self;
    _scrollView.contentSize = [UIScreen mainScreen].bounds.size;
    _scrollView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    _showInputView = YES;
    [self reloadInputViews];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    _showInputView = NO;
    [self reloadInputViews];
}

// こちらをオーバーライドすることで下にドックする view が得られる.
- (UIView *)inputAccessoryView
{
    if (_showInputView) {
        return _textFieldContainer;
    }
    else {
        // nil にして [self reloadInputViews]; しないとメモリリーク!
        // inputContainer が外部で強参照されているらしい.
        return nil;
    }
}

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

@end

```

何故か inputAccessoryView で返したビューは参照が解放されないので
ビューが非表示になるタイミングで reloadInputViews を呼び、nil を返し直して参照を解放している。
アニメーションの完了が分かるAnimationDrawer

#完了が通知されないフレームアニメーション
久しぶりにネィティブANdroidに帰ってきて不便を感じたのがフレームアニメーションの完了が感知できない件。

AnimationDrawableのソースとにらめっこしながら半日、色々やってみたけど、ここの[フォーラム](http://stackoverflow.com/questions/2214735/android-animationdrawable-and-knowing-when-animation-ends)にある時間を計測するのがもっともスマートだと判明。

```InformStateAnimationDrawable.java
/**
 * InformStateAnimationDrawable
 *
 * Created by hoshi_7 on 2014/07/31.
 */
public class InformStateAnimationDrawable extends AnimationDrawable{
    private OnAnimationStateListener mListener;
    private Handler mHandler;

    public InformStateAnimationDrawable(AnimationDrawable drawable) {
        mHandler = new Handler();
        for (int index = 0; index < drawable.getNumberOfFrames(); index++) {
            this.addFrame(drawable.getFrame(index)
                          , drawable.getDuration(index));
        }
    }

    public void setOnAnimationStateListener(OnAnimationStateListener listener){
        mListener = listener;
    }

    @Override
    public void start() {
        super.start();
        if(mListener != null) {
            mHandler.postDelayed(new Runnable() {
                public void run() {
                    mListener.onAnimationEnd();
                }
            }, getTotalDuration());
        }
    }

    public int getTotalDuration() {
        int duration = 0;
        for (int i = 0; i < this.getNumberOfFrames(); i++) {
            duration += this.getDuration(i);
        }

        return duration;
    }

    public interface OnAnimationStateListener {
        public void onAnimationEnd();
    }

}
```

OnAnimationStateListenerという大層なインタフェースなのは途中のフレームが完了するタイミングにもイベントを飛ばす機会があるかもしれないので、あったらonAnimationFrame(int index);とかを足そうと思っていたから。

アクティビティ側

```Activity.java
//AnimationDrawableからAnimationDrawableのサブクラスへの直接キャストできないのでこの作り

AnimationDrawable animDrawable = (AnimationDrawable)getResources().getDrawable(R.drawable.sample_anim);
InformStateAnimationDrawable frameAnimation = new InformStateAnimationDrawable(animDrawable);

//OnAnimationStateListenerインタフェースの実装をsetする
frameAnimation.setOnAnimationStateListener(new InformStateAnimationDrawable.OnAnimationStateListener() {
    @Override
    public void onAnimationEnd() {
       //アニメーション終了時の処理
    }
});

//リソースセット
mTodayLogo.setImageDrawable(frameAnimation);
//アニメーションスタート
frameAnimation.start();
```
Homebrewでphp-build及びphpenvインストール後に5.5系をインストールするための手順


[Qiita:phpenvとphp-buildでPHPのバージョンを切り替えられるようにする](http://qiita.com/ispern/items/97e3e6d910eb98b5de75#2-3)を参考にしてphpenv及びphp-buildをインストールできたものの、5.5.15をインストールしようとした際にライブラリの不足でヘクってしまいました。
php-build => ライブラリ不足の発見 => brew install => php-build... を繰り返すのは不毛なので、私がインストールした際の手順を残しておきます。

```エラーメッセージとその対応
 # configure: WARNING: bison versions supported for regeneration of the Zend/PHP parsers
$ git checkout adf87c6f6f6f7fa93e85e0ce2ba1135582716f6c /usr/local/Library/Formula/bison.rb 
$ brew install bison
$ bison --version
$ brew link bison --force
$ source ~/.bash_profile
 # configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers.
$ brew instal re2c
 # configure: error: jpeglib.h not found.
$ brew install libjpeg
 # configure: error: png.h not found.
$ brew install libpng
 # configure: error: mcrypt.h not found. Please reinstall libmcrypt.
$ brew reinstall libmcrypt
```

対応の際に参考になったサイトはこちら。

- [わすれっぽいきみえ:phpenv + php-buildでphpのバージョン管理](http://kimikimi714.hatenablog.com/entry/2014/03/06/phpenv_%2B_php-build%E3%81%A7php%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86)
- [Linux & iOS & Android Labs:PHP 5.2.8 インストール Linux](http://blog.77jp.net/php-528-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB-linux)
- [Qiita:phpenvとphp-buildでPHPのバージョンを切り替えられるようにする](http://qiita.com/ispern/items/97e3e6d910eb98b5de75#2-3)

先人の皆様、ありがとうございました。
CloudWatch Logsをさわってみた

CloudWatch Logsをさわってみたメモを残す。

# CloudWatch Logsの位置付け

今までログ収集のベストプラクティスは最終的にS3に収集 → Glacierだったのが、収集場所としてCloudWatch Logsという選択肢が増えた感じ。

# 料金

 * 今のところ以下のような感じらしい。
  * [料金 - Amazon CloudWatch （リソースとアプリケーションのモニタリング） | アマゾン ウェブ サービス（AWS 日本語）](http://aws.amazon.com/jp/cloudwatch/pricing/)

```bash
$0.50 per GB ingested
$0.03 per GB archived per month**
```

----

  * 1ヶ月で100GBのログデータを取り込み、ログが圧縮されて20GBになるとすると、$50.60/月くらい。
   * おそらくS3がバックエンドで使われており、保存の料金は安い感じ。
   * ぱっと見で結構かかる気はするけど、EC2とEBSでログを保管することに比べたら安い感じ（運用保守もいらないし）。

```bash
100GB x $0.50 + 20GB x $0.03 = $50.60
```

# 収集したログの分類

収集されたログはLogStreamとLogGroup(LogStreamの集合)で分類される。

フィルタがLogGroup単位なので、LogGroupの中に別の種類のログ混ぜるのは止めた方が良さそう。

# CloudWatch Logs Agentでのログ収集をやってみた

* [CloudWatch Logsエージェントを検証してみた | mooapp](http://moomindani.wordpress.com/2014/07/16/cloudwatch-logs-5point-investigation/)の検証見てるとログ収集まかせて良さそう。

```bash
# インストールスクリプト取得
$ wget https://s3.amazonaws.com/aws-cloudwatch/downloads/awslogs-agent-setup-v1.0.py

# インストール
# 対話モードでも可だけど以下のようにするとサイレントなので自動化に向きそう。
# 設定のプロトは対話モードで作るとか
$ sudo python awslogs-agent-setup-v1.0.py --configfile https://gist.githubusercontent.com/mechamogera/aa03714bede13b8c535f/raw/c24c3f51b6591a09cb815d337df9e60643d3ac98/awslogs.conf --region us-east-1 --non-interactive

Step 1 of 5: Installing pip ...DONE

Step 2 of 5: Downloading the latest CloudWatch Logs agent bits ... DONE


Step 5 of 5: Setting up agent as a daemon ...DONE


------------------------------------------------------
- Configuration file successfully saved at: /var/awslogs/etc/awslogs.conf
- You can begin accessing new log events after a few moments at https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#logs:
- You can use 'sudo service awslogs start|stop|status|restart' to control the daemon.
- To see diagnostic information for the CloudWatch Logs Agent, see /var/log/awslogs.log
- You can rerun interactive setup using 'sudo ./awslogs-agent-setup.py --region us-east-1 --only-generate-config'
------------------------------------------------------

# 最初から起動していて自動的に起動するようにもなっている
$ sudo service awslogs status
 (pid  5795) is running...

$ sudo chkconfig awslogs --list
awslogs        	0:on	1:on	2:on	3:on	4:on	5:on	6:on

# 設定ファイルの変更時はrestartすると反映された
```

# AutoScaling対応について

一工夫必要そう。

 * LogGroupでまとめておくと、フィルタがあるのでその範囲でリアルタイム監視できるし、現状動いている単体インスタンスのログも調べるのは出来そう。
 * ただ、インスタンスが多かったり、入れ替わりが多かったりするとLogStreamが多くなって目的のログを捜すのが大変になりそう。
  * 現状のAPIではLogGroup中のLogStream全てに対するSearchがない
  * CloudWatch Logs Agentは複数ソースからの単一LogStreamをサポートしていない([CloudWatch Logs Agent Reference - Amazon CloudWatch](http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/AgentReference.html)のFAQs)
 * 今のCloudWatch Logs Agentでは対応してないがLogStreamを日付別でわけて同じLogStreamに各インスタンスのログをソース情報を付与した上で集約できるといい？

# ログ取得用のRubyスクリプトを作ってみた

LogGroupにLogStreamが多くなる場合、Management Console上でLogGroupから該当のログを見つけ出すのが大変そうなので作ってみた。
ただ、LogStreamが増えれば増えるほど取得に時間がかかりそう。

* [CloudWatch LogsのGroupから一括でLogを取得するスクリプト](https://gist.github.com/mechamogera/b3c7076b8171d26c70ea)
GVimでJavaScriptのシンタックスチェックしようとしたら、abnormal statusとか言われて困った話

# VimでJavaScriptのシンタックスチェックをしたい

## プラグイン導入

_vimrcを修正

```
NeoBundle 'scrooloose/syntastic'
```

## Syntasticの設定

_vimrcを修正

```
let g:syntastic_check_on_open = 0 "ファイルオープン時にはチェックをしない
let g:syntastic_check_on_save = 1 "ファイル保存時にはチェックを実施
" jshint 設定ファイルの場所を指定
let g:syntastic_javascript_jshint_args = '--config "' . $HOME . '/.jshintrc"'
```

4行目のjshint設定ファイルの場所を指定しなかったがために、エラーにあって困った。。

ここでちゃんと指定してれば、以下は起きないハズなので読まなくてOKです。。

- - -

## 発生したこと

適当に書いたJavaScriptファイルで動作確認しようとしたら、こんなエラー

```
Checker javascript/jshint returned abnormal status
```

なんか動いてないっぽい。。

## jshintのインストール確認

```
npm install jshint --global
```

## jshint 設定ファイル

ホームディレクトリ以下に、.jshintrcを作る。

```
{
  "indent" : 2,      // インデント
  "camelcase":true,  // キャメルケース
  "maxlen" : 80,     // 一行の最大文字数
  "unused" : true,   // 宣言のみで使用していない変数を検出
  "eqeqeq":true,     // ==、!=の使用禁止
  "undef" : true,    // グローバル変数へのアクセスを禁止
  "devel" : true,     // console、alertを許可
  "globals": {
    "$": false,
    "jQuery": false
  }
}
```
以前作っていたファイルが、地味にJSONの文法エラーで更にハマる。。

### .jshintrcの文法確認

コンソールからちゃんと動くかやってみる。

```
jshint --config %HOME%\.jshintrc test.js
```

↓こんなんでで来る場合は、JSON文法エラー

```
ERROR: Can't parse config your_config_file_path_here
```

↓ちゃんとチェックしてくれたらOK

```
test.js: line 3, col 8, Creating global 'for' variable. Should be 'for (var key ...'.
test.js: line 3, col 15, 'options' is not defined.
test.js: line 4, col 17, 'options' is not defined.
test.js: line 4, col 25, 'key' is not defined.

4 errors
```

errorsって言われてもなんか嬉しいｗｗ


### Syntasticをデバッグモードにしてもっと情報をもらう

再びvimにて。。
ノーマルモードから、syntasticの設定をセット。
テストしたいJSファイルを保存するとチェックが走る。

```
<ESC>
let g:syntastic_debug=3
:w
```

ここで設定ファイルが読み込めてない的なエラーを発見。

- - -
参考URL：[Checker javascript/jshint returned abnormal status · Issue #1029 · scrooloose/syntastic](https://github.com/scrooloose/syntastic/issues/1029)

唯一これしかヒットしなくて、英語だし、長いし・・ひぇ～と思ってたんだけど、
下の方でキレ気味に

「いいから
```let g:syntastic_javascript_jshint_conf = $HOME . '/.jshintrc'```
やれよ。」

って記述がビンゴでした。
ありがとう。
IntelliJ IDEA : 選択した文字列を任意のサイトで検索

# エディタの選択文字列を任意のサイトで検索

phpファイルを編集しているとき、関数名で[PHPマニュアル](http://php.net/manual/ja/index.php)を検索したくなるので、
ファイルの拡張ごとにURLを指定してブラウザを開くスクリプトを作りました。

[search_with.sh](https://gist.github.com/nakyau/bf24a4060c5bcf42d781)

## search_with.sh

convert_url()の部分で拡張子に対応するURLを設定しています

```bash
    case $EXTENSION in
        'php' ) URL='http://php.net/search.php?lang=ja&show=quickref&pattern=%s';;
        'hs' ) URL='http://www.haskell.org/hoogle/?hoogle=%s';;
        *  )  ;;
    esac
```

定義されていない拡張子の場合はデフォルトのサイトになります。

```bash
URL='https://www.google.com/#q=%s'
```

[PHPマニュアル](http://php.net/manual/ja/index.php)では検索する際に関数名での _ （アンダーバー）が -（ハイフン）になるので
convert_word()で検索文字列を変換しています。

```bash
    case $EXTENSION in
        'php' ) WORD=`echo "$WORD" | tr _ -` ;;
         *  )  ;;
    esac
```

好みの設定を追加して使ってください。

## 設定

スクリプトを任意の場所に置いてから
IntelliJのメニューから Preferences -> External Tools
「＋」ボタンでダイアログを開き、以下のように設定します。

![search_with_setting.png](https://qiita-image-store.s3.amazonaws.com/0/19304/e14a2706-4112-3d0c-0e5b-2566e6ae2842.png)

Tool Settingsだけ重要です。その他の項目は任意に設定してください。
#### Tool Settings:
```
  Program: /path/to/search_with.sh ※スクリプトを置いた場所
  Parameters: "$SelectedText$" $FileExt$ "/Applications/Google Chrome.app" 
```
※Parametersの3つ目の値はブラウザアプリケーションのパスです。

設定を適用して完了。

## 使い方

エディタの文字列を選択した状態で右クリック。
Show in: で指定したメニューにツール名が現れるのでクリック

または

Preferences -> Keymap で任意のショートカットを指定。
エディタの文字列を選択した状態でショートカットキーを入力。

## 課題

- 文字列選択が面倒なので、カレットのある場所のワードを\$SelectedText\$に取りたい
- Javascriptの関数名検索ができるよいサイトあったら教えてください

## 応用

似たような処理で変数名を英語辞書検索するツールも作りました。
[search_english.sh](https://gist.github.com/nakyau/52ffac902697df3c91f0)
クラス内のメソッド名に予約語 (list とか) を使用する方法

Stack Overflow からの転載です。
マジックメソッド```__call()```をオーバーライドし、```call_user_func_array()```で実際には予約語となる関数を呼び出す事で実現出来ます。
詳細はコードで。

**引用元**
[namespaces - Is it possible to use new as a method name in PHP 5.3? - Stack Overflow](http://stackoverflow.com/questions/4291574/is-it-possible-to-use-new-as-a-method-name-in-php-5-3)

**コード (引用元から転載)**

```php
/**
 * @method String new new($args) returns $args
 */
class Foo
{
     protected function _new($args)
     {
         return $args;
     }
     public function __call($method, $args)
     {
         if($method === 'new') {
             return call_user_func_array(array($this, '_new'), $args);
         } else {
             throw new LogicException('Unknown method');
         }
     }
}
$foo = new Foo;
echo $foo->new('hello'); // return hello
echo $foo->boo();        // throws Exception
```
SFTP用ユーザを作る

SFTP用ユーザが必要になったのでそれを作るメモです。

## とりあえず確認

```console:Terminal
$ less /etc/group
$ less /etc/passwd
```

なんかまあ、グループとかユーザの確認。

## ユーザの作成

```console:Terminal
# groupadd username
# useradd -d /home/username -g username username
```

SFTP用ユーザとSFTP用ユーザのグループを作ります。

```
# mktemp -u XXXXXXXX
# passwd username
```

初期パスワードの指定をするのに`mkpasswd`とかいうコマンドがあるらしいのだけど、入ってなかったので`mktemp`で代用した……（いいのかなこれ）

```
# mkdir -p /home/username/.ssh
# touch /home/username/.ssh/authorized_keys
# chmod 0700 /home/username/.ssh
# chmod 0600 /home/username/.ssh/authorized_keys
```

あとは`.ssh`ディレクトリとか作ったりとか。`authorized_keys`に鍵の追加もしておく。

## SSHログイン時のコマンド指定

usernameにログインしたときに最初に実行されるコマンドを指定する。`authorized_keys`の先頭に書けば良いみたい。

```
# vi /home/username/.ssh/authorized_keys
```

```diff:~username/.ssh/authorized_keys
-ssh-rsa ...
+command="internal-sftp" ssh-rsa ...
```

`authoriezed_keys`の追加した鍵の行の先頭に`command="internal-sftp" `を追加する。

## sshd周りの設定

上で`command`の設定したからForceCommandの指定は要らなかったかも……

```conf:/etc/ssh/sshd_config
# Example of overriding settings on a per-user basis
#Match User anoncvs
#       X11Forwarding no
#       AllowTcpForwarding no
#       ForceCommand cvs server

Match User username
       X11Forwarding no
       AllowTcpForwarding no
       ForceCommand internal-sftp
```

`ChrootDirectory`も指定した方がいいのかな。

## sshdの再起動

```
# service sshd restart
```

sshdを再起動して設定を反映させる。

## 確認

```console:Terminal
$ sftp -o IdentityFile=/path/to/private-key -P port username@ipaddr
Connected to ipaddr.
sftp>
```

SFTPで接続できた。

```console:Terminal
$ ssh -o IdentityFile=/path/to/private-key -p port username@ipaddr
This service allows sftp connections only.
Connection to ipaddr closed.
```

SSHだと接続が切断された。

これでSFTP用のユーザができるはず。
Goで適当に空いてるportをListenする

テストに使うのに、適当に空いてるportをListenしてそのアドレスを知りたい。

```go
package main

import (
	"fmt"
	"log"
	"net"
)

func main() {
	l, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(l.Addr())
}
```

実行結果

```
127.0.0.1:55007
```

typester氏に教えて頂きました。
Cocos2d-JSはイケてる? イケてない?


## Cocos2d-JSとは
 - 大手なスマホアプリ用ゲームエンジン **Cocos2d-x** 。(主にC++使って書く)
 - Javascriptでゲームを書いて、そのままブラウザゲーム・iOSアプリ・Androidアプリ
として出力できる！！
 - Cocos2d-xとは別物としてつくられていた、 **Cocos-html5** が本体と統合され、シームレスに使えるようになった!

## 公式が出してるサンプル
 - [Fruit Attack (パズルゲーム)](http://www.cocos2d-x.org/html5-samples/samples/games/FruitAttack/index.html)
 - [MoonWarriors (シューティング)](http://www.cocos2d-x.org/MoonWarriors/index.html)

 - Cocos2d-xの方は、Badlandとかブレフロとか、大ヒットゲームでの採用も多数

## ひととおりの開発フロー

 - `cocos`コマンドでひながたを作る

```
cocos new SampleGame -p com.example.samplegame -d . -l js
```

 - Cocos2d-JSのフレームワークにのっとって、javascriptでゲームを書く

 - ブラウザでプレイ・デバッグ

```
cocos run -p web
```

 - いいところで、iOSやAndroid向けにビルド

```
cocos run -p ios
```

```
cocos run -p android
```


## イケてるところ

### 「実装 → 動作確認」をすばやく繰り返しながらゲーム開発

 - iOS・Android両OSに対応したゲームを、ブラウザで確認しながら実装できる。
 - Cocos2d-xで実装する場合、動作確認をするたびにビルドをする必要があるが、こちらは即時プレビューが可能

### jsのフレームワークとして
 - scriptの遅延読み込みや依存解決、クラスの仕組みが普通によくできてる (独自っぽいけど)

### Cocos2d-x自体との統合がかっこいい

Cocos2d-x本体ともシームレスに統合されていて、開発用のコマンドもインタフェースが共通になっている。

```
# Cocos2d-xのプロジェクト生成
cocos new MyGame -l cpp -d ~/Projects/ -p com.example.mygame

# Cocos2d-JSのプロジェクト生成
cocos new MyGame -l js -d ~/Projects/ -p com.example.mygame
```

## イケてないところ

### まだalpha版

 - APIなどまだ変更される可能性がある
   - 実際、Cocos2d-xの2.x→3.xへの移行時は、いろいろ悲劇が起きている
 - ネットワーク通信系のAPIがまだなさげ！！

### ビルドに時間が掛かる (特にAndroid)

 - 開発中、頻繁に実行する必要はないが、JSからCPP、CPPからOS側と、2段階にビルドがあるので、結構時間がかかる。暇。

### Javascriptの全部のAPI使えるか定かじゃない

## ざっと仕様
 - `cc`というネームスペースに全部入ってる。
 - 独自?のクラスフレームワークを採用している (`cc.Class`)
    - `cc.Layer.extend()`で、Layerをextendしたものを作れる
    - `this._super`とかも生えてる
    - インスタンス化には`new`じゃなく`Klass.create()`を使う
      - これはcppの時点でもそうだったので、クラスフレームワークのルールというよりは、そちらに合わせたのかも
 - デフォルトのサンプルでは、ぜんぶapp.jsに一緒くたに入れてある
   - htmlの編集入るとめんどくさいし、gruntとかで結合の仕組みをつくりたいところ
   - あるいは、けっこうモジュールの仕組みがしっかり作ってあるので、そちらに乗っかってもいい
 - `app.js`とは別に`main.js`もある。
 - `resources.js`、`res`からリソースのURLをとってくるスタイル。`g_resources`は、`main.js`の中でperloadしてた。

 - 物理エンジン(`chipmunk`・`box2d`)や`socket.io`は、モジュールとして追加記述すれば利用できる。

## HTML5系のみなさまに、手を出してみてほしい理由

今後のスマホゲーム市場は、

 - 作りこまれた、体験がリッチなゲーム
 - 軽量でちゃかちゃかしたゲーム

に2分化していく気がする。

後者をスピーディに作る上では、Cocos2d-JSの動作確認の速さは強そう。

Web屋さんの知見がアドバンテージを持っているうちに、手を出してみてはいかが?

## 参考

 - [第十三回 Cocos2dの新パッケージCocos2d-JSについて（前編） - cocos2d javascript bindingsでマルチプラットフォーム開発 - Mobile Touch](http://mobiletou.ch/2014/04/cocos2d%E3%81%AE%E6%96%B0%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8cocos2d-js%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%EF%BC%88%E5%89%8D%E7%B7%A8%EF%BC%89)
   - Cocos2d-html5からCocos2d-JSになって何が起きたのか、まとめ

 - [cocos2d-js(cocos2d-html5) でchipmunkを使う - Qiita](http://qiita.com/iwag@github/items/237333fdd251ec597b6b)
   - chipmunk(物理エンジン)を使う場合のサンプル
   - モジュールのしくみがどうなってるのかもわかりやすい
[Ruby] 二次元配列を列方向に足し合わせる（長さが異なる配列も可）




# やりたいこと

```
# [[1,1,1],[2,3],[4]] の場合、

[1, 1 ,1]
[2, 3    ]
[4        ]
 ↓↓↓ 列（タテ）方向に足し合わせる
[7, 4, 1]

```

もともと以下記事を参考に便利に使わせてもらっていたのですが、

Ruby - 配列の同じ項数同士を足す - Qiita
http://qiita.com/hash/items/7eb4d0eb865de719302d

この手法の場合、異なる長さの配列だとエラーになってしまいます。

### OK（inputする各配列の長さが等しい）

```rb
# [1,1,1],[2,3,4] のinputで、[3,4,5] のoutputが欲しい
[13] pry(main)> [[1,1,1],[2,3,4]].transpose.map{|ary| ary.inject(&:+)}
=> [3, 4, 5]
```

### NG（inputする各配列の長さが異なる）

```rb
# [1,1,1],[2,3],[4] のinputで、[7,4,1] のoutputが欲しい
[14] pry(main)> [[1,1,1],[2,3],[4]].transpose.map{|ary| ary.inject(&:+)}
IndexError: element size differs (2 should be 3)
```

ということで、対策を考えていきます。

# 追記

（2014/8/1 15:53 追記）
コメント欄にてよりベターな方法を教えて頂きました！

```
[42] pry(main)> array = [[1,1,1],[2,3],[4]]
=> [[1, 1, 1], [2, 3], [4]]
[43] pry(main)> array.each_with_object([]) { |e, a| e.each_index { |i| a[i] = a[i].to_i + e[i] } }
=> [7, 4, 1]
```

これにて、以下内容は不要となるので、参考程度に読み流して頂けますと・・。


# TL;DR

以下の2ステップで完了です。

### Arrayクラスをオープンしてsafe_transposeメソッドを追加

```rb
class Array
  def safe_transpose
    result = []
    max_size = self.max { |a,b| a.size <=> b.size }.size
    max_size.times do |i|
      result[i] = Array.new(self.first.size)
      self.each_with_index { |r,j| result[i][j] = r[i] }
    end
    result
  end
end
```

## 使う

```rb
[15] pry(main)> [[1,1,1],[2,3],[4]].safe_transpose.map{|ary|ary.inject(){|s,i|s=s+i.to_i}}
=> [7, 4, 1]
```

これで異なる長さの配列でも利用できるようになりました。

# 詳しく

## transpose最適化

そもそもやろうとしているプロセスとしては、

1. transposeで2次元配列を行列に見立てて、配列を列方向に入れ替え
- 各配列ごとの要素をinjectで足し合わせ

です。

そして今回のエラーの原因としては、
transposeが異なる長さの配列を許可していないから。

```rb
[16] pry(main)> [[1,1,1],[2,3],[4]].transpose
IndexError: element size differs (2 should be 3)
```

ということで、オープンクラスを用いてArrayクラスにsafe_transposeメソッドを定義します。

```rb
class Array
  def safe_transpose
    result = []
    max_size = self.max { |a,b| a.size <=> b.size }.size
    max_size.times do |i|
      result[i] = Array.new(self.first.size)
      self.each_with_index { |r,j| result[i][j] = r[i] }
    end
    result
  end
end
```
これで、足りない項の部分はnilで補ってくれるようになりました。

```rb
[14] pry(main)> [[1,1,1],[2,3],[4]].safe_transpose
=> [[1, 2, 4], [1, 3, nil], [1, nil, nil]]
```

## inject最適化

本当は`inject(&:+)`で書きたいところですが、nilを数値にしてやる必要があるため（※）、こうなります。

```rb
[17] pry(main)> [[1,1,1],[2,3],[4]].safe_transpose.map{|ary|ary.inject(){|s,i|s=s+i.to_i}}
=> [7, 4, 1]
```

※ `safe_transpose`でnilでなく0を返せば`inject(&:+)`でいけるようになりますが、
その場合transposeの意図が変わってしまうため避けました。

もっとスマートなやり方もある気がするので、コメントお願い致します！

## 参考

How to safely transpose Ruby arrays
http://www.matthewbass.com/2009/05/02/how-to-safely-transpose-ruby-arrays/

Ruby - 配列の同じ項数同士を足す - Qiita
http://qiita.com/hash/items/7eb4d0eb865de719302d
AngularJS Tutorialを始めようとしたらbower: not foundと言われnpm installできない

AngularJSのチュートリアルをやろうとすると、配布されているリポジトリで`npm install`できませんでした。

プロジェクトフォルダで、以下のようなエラーが出ました。

```shell-session
$ npm install
...
> angular-phonecat@0.0.0 postinstall /vagrant/angular-phonecat
> bower install

sh: 1: bower: not found
...
```

StackOverflowの記事["postinstall": "./node_modules/bower/bin/bower install"](http://stackoverflow.com/questions/18423965/mean-stack-win-7-git-push-heroku-master-results-in-sh-bower-not-found-error)によると、**package.json**から以下の一行を削除してしまえ、という大胆な回答がありました。

```json:package.json
"postinstall": "./node_modules/bower/bin/bower install"
```

もちろんこれだと**Bower**は入らないので、あとで手動で入れて、Bowerパッケージをインストールします。

```shell-session
$ sudo npm install -g bower
...
$ bower install
...
```

**http-server**パッケージも入っていなかったので手動で入れます。

*＊Ubuntu 14を使ったら自動的に入りました。*

```shell-session
$ npm install http-server
...
```

テストは**Karma**パッケージを使うのですが、これもエラーが出て動きません。仕方ないので手動で入れます。

*＊Ubuntu 14を使ったら自動的に入りました。*

```shell-session
$ npm install karma
...
```

最初はFirefoxブラウザとChromeブラウザを起ち上げてテストを走らせる設定になっているのですが、私の場合仮想マシンで動かしていたので、これらの二つは無効化しました。具体的には、**testフォルダ**の**karma.conf.js**を編集します。

```js:karma.conf.js
...
    plugins : [
            //'karma-chrome-launcher',
            //'karma-firefox-launcher',
            'karma-jasmine'
            ],
...
```

これで`$ npm test`で9876番ポートにテスト結果が表示されるようになります。

End-to-End テストを行うための**webdriver-manager**も入っていません。大丈夫かいな・・・

*＊Ubuntu 14を使ったら自動的に入りました。*

```shell-session
$ npm install webdriver-manager
...
$ npm run update-webdriver
...
```

`$ npm run protractor`・・・これも**protractor**が入っていないと怒られます。

*＊Ubuntu 14を使ったら自動的に入りました。*

```shell-session
$ npm install protractor
...
File exists: /vagrant/angular-phonecat/node_modules/.bin/webdriver-manager
Move it away, and try again.
...
```

と言われるので該当するファイルの名前を変えて再度**protractor**をインストールします。

```shell-session
$ npm install protractor
```

それでも`$ npm run protractor`は、

```shell-session
[launcher] Error: Could not find chromedriver
```

に阻まれるので、**test/protractor-conf.js**を編集してしまいます。

```js:test/protractor-conf.js
...
  //chromeOnly: true,
...
```

すると今度は以下のようなエラーメッセージが出ます。

```shell-session
...
/vagrant/angular-phonecat/node_modules/protractor/lib/driverProviders/local.js:42
        throw new Error('Could not find chromedriver at ' +
              ^
Error: Could not find chromedriver at /vagrant/angular-phonecat/node_modules/protractor/selenium/chromedriver.exe
...
```

どうもこのStackOverflow記事と同じ現象のようですが：[webdriver-manager update](http://stackoverflow.com/questions/22193692/protractor-selenium-could-not-find-chromedriver-at-on-windows)

うーん、ちょっと今はここまで・・・
FacebookとTwitterのAPIのコール回数の制限について

## FacebookのAPIの制限

* access_tokenごとに600秒間に600回
* appごとに1日100万回のAPIコール

## TwitterのAPIの制限
* ユーザごとの制限とアプリケーションごとの制限がある
* 15分ごとに更新、特定ワードの検索は15分ごとに180回ほど
* 以下で確認
* https://dev.twitter.com/docs/rate-limiting/1.1/limits

## 参考
* https://developers.facebook.com/docs/reference/ads-api/api-rate-limiting
* https://developers.facebook.com/policy/
* http://www.quora.com/Whats-the-Facebook-Open-Graph-API-rate-limit
* http://stackoverflow.com/questions/9272391/facebook-application-request-limit-reached
* https://dev.twitter.com/docs/rate-limiting/1.1/limits
* https://dev.twitter.com/docs/rate-limiting/1.1
Ubuntuに最新のNode.jsを入れる

普通に`sudo apt-get install nodejs`とやってしまうと**ver. 0.10.25**が入り、そこからさらにバージョンを上げようとして以下の作業をしてもエラーが出てうまくいきません。気をつけて下さい。

以下のようにします。

```shell-session
$ sudo su
# curl -sL https://deb.nodesource.com/setup | bash -
...
# exit
$ sudo apt-get install nodejs
...
$ node -v
v0.10.29
```
エンジニアじゃなくてもiOS開発に携わる人が絶対に見るべきWWDC2014のセッション三選

WWDC2014のビデオを暇を見つけては見ています。

もちろん開発者のための祭典なので技術的な内容を解説するセッションが多いのですが、実はそうではないセッションもあるのです。特にUI系に関するセッションは非常に魅力的です。

**なぜならアップルがどのようにアプリを作っているかを知ることができるからです。**

WWDCのセッションは今年からは開発者アカウントを持っていなくても見られるようになりました。無料で見ることができるなんてかなりおトクだと思います。[WWDC2014のビデオ、pdfはこちら](https://developer.apple.com/videos/wwdc/2014/)から見ることができます。

エンジニアでも、デザイナーでも、マネージャーでも、iOSアプリ開発に携わる方にはぜひとも目を通しておいてもらいたいのが、こちらの3つ。独断と偏見で選びました。

* Platforms State of the Union
* Designing Intutive User Experiences
* Prototyping: Fake it Till You Make It

もちろんセッションはすべて英語ですが、字幕を表示することもできますし、スライド使いながら進められるので、非常に分かりやすいです。先にスライドをざっくりと見てからビデオを見るのも良いかもしれません。

## [Platforms State of the Union](https://developer.apple.com/videos/wwdc/2014/#102)
WWDCと言えばKeynoteです。なのですが、実際のところ、Keynoteの後に始まるこちらのセッションが開発者的には重要です。Keynoteで新機能の紹介をし、新機能を利用するための技術についての解説をこのセッションで行っています。

なので、ざっくりと技術的なポイントを押さえることができます。アップルが推進したいと思っている技術について紹介されている（と思う）ので、必ず見ましょう。特にエンジニアは。

エンジニアはこれを見てから、それぞれ興味が湧いたセッションを見ると良いと思います。WWDC2014では"What's New in ~"シリーズが基礎編のような扱いとなっています。

もっと知りたいと思ったら、ところどころで「これについてもっと知りたかったらこのセッションを見てくれ！」みたいに紹介してくれるので、関連するセッションを見ましょう。

エンジニアでない方もさらっと目を通しておくと企画、デザイン時に構想を練りやすかったり、エンジニアに対して質問がしやすくなると思います。

## [Designing Intutive User Experiences](https://developer.apple.com/videos/wwdc/2014/#211)
「直感的なユーザーエクスペリエンスのデザイン」とでも訳すのでしょうか。アップルのUXエバンジェリストがプレゼンテーションを行っており、とても面白いです。

間違いなくアプリに関わるすべての人が見る価値のあるものと言えるでしょう。これと[ヒューマンインターフェースガイドライン](https://developer.apple.com/jp/devcenter/ios/library/documentation/MobileHIG.pdf)に目を通しておけば、iOSのお作法はほとんど身に付くのではないでしょうか。個人的に最も推薦しているセッションです。

最近、日本でも話題になりだした“ハンバーガーボタン”論争についてのアップルの公式見解についても解説されていて、特にUX好きな方は必見でしょう。オーディエンスの反応を聞く限り、ハンバーガーボタン論争は結構アツい話題みたいです。

## [Prototyping: Fake it Till You Make It](https://developer.apple.com/videos/wwdc/2014/#223)
こちらは少し趣が変わって、プロトタイピングについての話題です。

対象はアプリに関わるすべての人です。コードを書く人も、コードを書かない人も、デザインする人も、マネージングする人もこの指止まれ！という感じです。

紙とペンを使ってプロトタイピングはやっていると思うのですが、そこからさらに一歩進んでKeynoteを使ってアニメーションを含めたプロトタイピングのやり方まで解説しています。

**というか、Keynoteについてのセッションかと思ってしまいます。**

それはさておき、**アップルが採用している手法を見ることができる**ことはとても貴重なことだと思います。

トーストのお店を探すアプリを作るためのプロトタイピングを行っていくのですが、ユニークな内容で肩肘張らずに見ることができます。最後にちょっとだけコードに関する内容が出てきます。

## まとめ
今回はエンジニア以外の人も見るべきセッションを挙げました。エンジニアはデザイナーや企画に共有、あるいは推奨すると良いのではないかと思います。

今後はエンジニア向けのセッションについても少しずつまとめていきたいと思います。
VPSにGitリポジトリを作る

GitHubやBitbucketは使ってきましたが、VPSにGitリポジトリを作成して使った事はなかったのでメモ。

数ヶ月前の記録なので覚えてないところが多いけど……

環境は私の苦手なCentOSの6.5です。UbuntuやDebianでも大して変わらないかと。

## グループを作る

数人で触る可能性があったので、とりあえずグループを作ります。

```console:Terminal
$ less /etc/group
```

とりあえずグループを確認。

```console:Terminal
# groupadd -g 555 git
```

空いてそうなGIDを使ってgitグループを作成。まあ、わざわざ`-g`を指定しなくてもグループ名だけ指定して実行すれば適当に空いてるGID使ってくれるんだけど……

```console:Terminal
# gpasswd -a username git
```

usernameをgitグループに追加。

## リポジトリを作る

```console:Terminal
$ git init --bare --shared repos.git
```

サーバ上で開発することはないはずなので`--bare`で作業ディレクトリなし（.gitの中身がrepos.git直下に配置される）で作成、`--shared`でグループでの書き込み許可？らしいので付加。

[サーバー用の Git の取得](http://git-scm.com/book/ja/Git-%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E7%94%A8%E3%81%AE-Git-%E3%81%AE%E5%8F%96%E5%BE%97)

```console:Terminal
# chown -R nobody:git repos.git
```

`chown`でgitグループを指定。所有者はnobodyでいいのかな。

## クローンする

ローカルからクローンする場合は以下のような感じ。プロトコルは`git+ssh`でも良いみたい。

```console:Terminal
$ git clone ssh://ssh-username@hostname:port/path/to/repos.git
```

ちなみに、`.ssh/config`にSSHの設定が指定してある場合は

```console:Terminal
$ git clone ssh://config-host/path/to/repos.git
```

とユーザ名やホスト名を指定するところに`.ssh/config`の`Host`で指定した名前を入れてあげればそのまま使ってくれて楽です。

あとはGitHubやBitbucketなどと同じように使えるかと。
Eclipseの設定（自分用メモ）

# 会社用環境構築時のチートメモ

## 文字コード設定
### Preferenceでのエンコード設定

- Window -> Preference -> encode UTF-8
- 
### 起動時の設定
eclipse.exeと同一ディレクトリにあるeclipse.iniに以下を追記

```
-Dfile.encoding=UTF-8
```

### JDKの指定
Edit configulation -> JRE
- separate JREでインストール済のJDKを指定

### Code format (Space)

- tabをspaceに変換
- Window -> Preferences -> Java -> Code style -> Formatter
- built inを拡張できないので、newで新しいスタイルを追加
- editボタンクリック
- Indentationタブクリック
- Tab policyを"space only"に指定

- - -
別に大した設定してなった・・・（メモるまでもなかったかも）
Node.jsで知ったopenとstartの最大の違い #ステマw

<blockquote class="twitter-tweet" data-cards="hidden" lang="ja"><p>皆様、回覧やストックありがとうございます。実は、このopenとstartの違いでこれよりずっと重大な違いが発覚しました！近日中に記事します！ / “Node.jsで知ったopenとstartの違い - Qiita” <a href="http://t.co/8imyqMnRPA">http://t.co/8imyqMnRPA</a></p>&mdash; kjunichi (@kjunichi) <a href="https://twitter.com/kjunichi/statuses/494716143186083840">2014, 7月 31</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

# Node.jsで知ったopenとstartの最大の違い

それは、コマンドに渡せる文字列長でした。

実はこのエントリー、[runstant-cli](https://github.com/kjunichi/runstant-cli)という[runstant](http://phi-jp.github.io/runstant/release/alpha/index.html)をターミナルやコマンドプロンプト、いわゆる、黒い画面から起動するコマンドを作っている際にローカルのブラウザにURLを引数で渡して起動する際に使ったわけで、runstantはURLの後ろに#で始まるハッシュを付け、このハッシュにHTML、CSSそしてJavaScriptを埋め込めこんでおり、結構な長さがあります。

openコマンドは問題ありませんが、startコマンドはなんとなく256文字程度までで、カットされているようでした。
（Windows使ってご飯食べてはいますが、あまり深入りしたくないので、あえて、境界値を調査しないマン）

## startコマンドでどう解決したか

Google URL Shortenerを使って、URLを短くして対処しました。

詳細は以下参照

- [node.jsでプロキシ環境下でもGoogle URL Shortenerを簡単に利用できた](http://abrakatabura.hatenablog.com/entry/2014/08/02/062229)
複数のTaskにスケジュールを設定する。


## tl;dr

Agenda view でmで選択、Bでバッチ処理sでスケジュールを決める

## 経緯
org-modeでTask管理をしていると、Agendaのviewで見た時にscheduleやdeadlineを過ぎたものが大量に占めてどのTaskが重要なのか見にくいことがある。

そこでリスケジュール、デッドラインの再設定をやるのだが、タスク一つづつやるのは面倒だ。

## 方法

1. Agenda viewにする
2. mでリスケ/デッドラインの再設定をしたいTaskを選択
3. Bでorg-agenda-bulk-action
4. menuが出てくるのでs デットラインの場合はd
imageNamedとimageWithContentsOfFileの差分メモ

### 差分早見表  

| Method | Cache	 | Speed | @2x |	Extention | Thread-Safe | 	Load Asset Catalog | Localize | 
|:-------|:-------|:-------|:-------|:-------|:-------|:-------|:-------|
|imageNamed|	YES|Fast|Auto|Unnecessary|NO|ImageSetName|User's Preferences|
|imageWithContentsOfFile|NO|Slow|Auto|Necessary|YES|Not supported|Not supported|

*  PNG以外のフォーマットでは拡張子の省略はできない
*  storyboard上で設定したimageView.imageもキャッシュされる
*  imageWithContentsOfFileの@2x判定は  iOS4.0ではバグがあったが4.1で直った  
*  imageNamedは当初メインバンドルを探し見つからなければユーザー設定言語のlproj内を自動で探す
*  imageWithContentsOfFileでもpathForResourceで作ったパスならユーザー設定のローカライズファイルを探す

### imageWithContentsOfFileで@2xの画像が取得出来ない場合
pathForResourceは@2x画像しかバンドルに無い時に@2xを省略してしまうとnilを返す、
imageWithContentsOfFileの引数に使う場合注意がいる。

```objc
// @2xしかないとnilを返す
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"fileName" ofType:@"png"];
// imageはnilになる
UIImage  *image     = [UIImage imageWithContentsOfFile:imagePath];
```
対策は..

*  @1xのfileName.pngも用意する
*  拡張子を省略せず`@"fileName@2x"`とする
*  以下のように明示的に画像までのパス文字列を引数に渡す

```objc
NSString *bundlePath  = [[NSBundle mainBundle] bundlePath];
NSString *imagePath   = [bundlePath stringByAppendingPathComponent:@"fileName.png"];
UIImage  *image       = [UIImage imageWithContentsOfFile:imagePath];
```
  

参考 
AssetCatalogの良い点やハマリ点
http://aqubiblog.blogspot.jp/2014_02_01_archive.html

UIImage imageNamed: ってスレッドセーフ?
http://togetter.com/li/104905

iOSにおける描画と印刷のガイド
https://developer.apple.com/jp/devcenter/ios/library/documentation/DrawingPrintingiOS.pdf

NSBundleクラスリファレンス
https://developer.apple.com/library/Mac/documentation/Cocoa/Reference/Foundation/Classes/NSBundle_Class/Reference/Reference.html#//apple_ref/occ/clm/NSBundle/pathForResource:ofType:inDirectory:
with構文を簡単に作る

# 背景

* 「準備→作業→後始末」、準備と後始末は共通の手続き、作業はいろいろ。
* try ... finallyは何となく見栄えがよくないような？
* openやfabricのcdのような、with構文を作りたい。
* `__enter__`とか、`__exit__`とか、難しそう・・・。
* rubyのブロック付きメソッドとyieldのような感じで簡単つくれないかなぁ。

# 解法
contextmanagerデコレータを使うことで、比較的簡単に、また、rubyのブロックに近い感覚で書くことができる。

参考リンクのままの例だが

```py
from contextlib import contextmanager

@contextmanager
def tag(name):
    print "<%s>" % name
    yield
    print "</%s>" % name

>>> with tag("h1"):
...    print "foo"
...
<h1>
foo
</h1>
```

こんな感じです。


# 詳細
* withブロックから抜ける手段が無い。

# 参考リンク
http://docs.python.jp/2/library/contextlib.html#module-contextlib
SWIGをwafから使う方法

けっこうめんどくさいが、おそらくできた

## メモ

- https://github.com/krig/waf/tree/master/demos/swig が参考になる
- waf 1.7 だと conf.load('swig') で引っかかった
- waf 1.8にすると通った（気がする）
- ウェブ上のドキュメント少ない


## 紆余曲折の果て

https://github.com/r9y9/swig-and-waf

cコードのpythonラッパ。waf最高