OmniAICreator/Qiita-1.07M huggingface dataset:
Swiftはじめたい...その９ 関数定義


# 今回は関数定義を試してみます。

## func
### func 関数名(引数型) -> 返り値型 {} という形式です。 

+ 普通な感じです。

```swift:func
// いわゆるprocedure
func procedureStyle(a:String , b:Int , c:Bool) {
    print(a , b , c)
}
// 2つめ以降は引数名も指定する
procedureStyle("文字",b:123,c:true) // 文字 123 true

// いわゆるfunction
func functionStyle(a:String , b:Int , c:Bool) -> String {
    return a + " " + String(b) + " " + String(c)
}
print(functionStyle("文字",b:123,c:true)) // 文字 123 true
```

+ Objective-Cを見たことある人には、ラベル名を指定するのも慣れてると思います。

### ラベルとデフォルト

+ ラベルとデフォルト値が指定できます。

```swift:ラベルとデフォルト
// 引数にはラベルが使えます。
func labelStyle(moji a:String , kazu b:Int , bool c:Bool) -> String {
    return a + " " + String(b) + " " + String(c)
}
// ラベルを明示して呼び出します。
print(labelStyle( moji:"文字", kazu:123, bool:true)) // 文字 123 true

// デフォルト値も指定できます。
func defaultStyle(moji a:String = "NULL" , kazu b:Int = 0 , bool c:Bool = false) -> String {
    return a + " " + String(b) + " " + String(c)
}
// 空だとデフォルト値が使われます。
print(defaultStyle()) // NULL 0 false
```

+ 個人的にはラベルが好きですね。func(1,2,"aaa",false)とかって書かれててもわかりにくいしね。

### ラベルを指定しないようにする。

+ アンダーバー(_)を加えると、他の言語のようにラベルを使わないようにもできました。

```swift:ラベルなし
func noLabelStyle( a:String , _ b:Int , _ c:Bool) -> String {
    return a + " " + String(b) + " " + String(c)
}
// ラベルを明示して呼び出します。
print(noLabelStyle( "文字", 123, true)) // 文字 123 true

```

+ ひとつ目の引数のところには、そもそも要りません。

### 複数の返り値

+ 複数の値を返すこともできます。

```swift:複数の返り値
// 複数の返り値もできます。
func tupleResponse(moji a:String , kazu b:Int , bool c:Bool) -> (String , Int , Bool) {
    return ( a, b, c )
}

print(tupleResponse(moji:"文字",kazu:123,bool:true)) // ("文字", 123, true)
```

+ ま、perlならよゆーですけど。

## 引数が可変

+ 引数を可変にできます。Objective-Cっぽいですね。

```swift:可変引数
// 引数の数が可変
func variableStyle(nums:Int...) {
    print(nums)
}

variableStyle(1,2,3,4) // [1, 2, 3, 4]
```

+ 配列できますね。ただし１種類しか使えません。
+ ``` func variableStyle(nums:Int...,strs:String...) ``` はNGでした。

## 関数を返す

+ 関数を返すこともできます。

```swift:関数
// 返り値に関数を返すこともできる。
func returnFunc(isType:Bool) -> (String)->(String) {
    func fa(str:String) -> String {
        return "HELLO , \(str)"
    }
    func fb(str:String) -> String {
        return "BYE   , \(str)"
    }
    
    return isType ? fa : fb
}

let ff = returnFunc(true)
print(ff("John")) // HELLO , John

print(returnFunc(true)("Jobs")) // HELLO , Jobs
print(returnFunc(false)("Tim")) // BYE   , Tim```
```

+ JavaScriptっぽいですね。イマドキです。

## まとめ

+ 関数定義はふつうな感じです。
+ Objective-Cっぽくもあり、JavaScriptっぽい感じもします。

# 今日はここまで

+ 次はクラス定義に進む前に、細々とした関数や用法を試そうと思います。
Swiftで右クリックメニュー(context menu)を出す

「右クリックメニュー」を「**コンテキストメニュー**」と言う習慣がないゆとりなので、右クリックした時にメニューを出す方法を調べたいだけなのにちょっと苦労しました。（わかれば超簡単です。）



# サンプル
右クリック時に以下のようなメニューを表示するサンプルを作りました。

![スクリーンショット 2016-01-16 16.59.25.png](https://qiita-image-store.s3.amazonaws.com/0/61792/1e7ab2ba-8219-16a0-06dc-ce744fbc9e6d.png)


## やり方
NSViewの```func menuForEvent(_ event: NSEvent) -> NSMenu? ```をオーバーライドすれば右クリック時にこのメソッドが呼ばれます。

この関数の戻り値でMenuの内容を返してあげればOKです。


```swift:MyView.swift
import Cocoa

class MyView: NSView {

    override func drawRect(dirtyRect: NSRect) {
        super.drawRect(dirtyRect)
    }
    
    override func menuForEvent(event: NSEvent) -> NSMenu? {
        // メニューの項目を作る
        let menu = NSMenu(title: "hoge menu")
        menu.addItemWithTitle("hoge", action: "hogeSelected:", keyEquivalent: "A")
        menu.addItemWithTitle("piyo", action: "piyoSelected:", keyEquivalent: "5")
        menu.addItemWithTitle("huga", action: "hugaSelected:", keyEquivalent: "Z")
        
        return menu
    }
    
    func hogeSelected(sender: AnyObject) {
        NSLog("hoge")
    }
    
    func piyoSelected(sender: AnyObject) {
        NSLog("piyo")
    }
    
    func hugaSelected(sender: AnyObject) {
        NSLog("huga")
    }
}

```
余談ですが、```NSMenu.addItemWithTitle```の引数の内容は以下の通り

* 第1引数 → 表示されるタイトル
* 第2引数 → 選択時に飛ぶメソッドのセレクタ（これが空だとMenuItemがDisableになる）
* 第3引数 → ショートカットキー（上記サンプルのA,Zのショートカットは他で使われているので自動的にshiftも付加されていると思われる）
PHPのコードを書くときに気をつけたいこと

## この記事は?
PHP、個人的には「書けば動く感」とか、ゆるい感じが気に入っていたりします。
しかし仕事で書く場合は特に、他の人が見て「ある程度」分かる必要があります。
僕が数ヶ月間、✙闇✙の深いシステムのメンテナンスを担当して「ここは気をつけたい」と感じた部分をまとめたいと思います。

## ループ処理
例えば、配列をforeachなんかで回したい場合...

```php

$arr = [0, 1, 5, 0, 3];
$filtered_arr = [];
foreach ($arr as $key => $val) {
  if ( ! empty($val)) {
    // ここになにか処理を書く
    echo "{$key} is not 0 : {$val}";
    $filtered_arr[] = $val;
  } else {
    continue;
  }
}
```

こういうコードがあった時、個人的に気に食わない点があります。

まず、ここですね。

```php
if ( ! empty($val)) {
```

### if文の順番
メイン処理の分岐とcontinueするときの分岐がありますが、その順番を逆にした方が良いですね。
こんな感じに。

```php
if (empty($val)) {
  continue;
}
// ここになにか処理を書く
echo "{$key} is not 0 : {$val}";
$filtered_arr[] = $val;
```
なぜかといいますと、先程の例では、メイン処理が「echoして配列に突っ込む」だけなので、まだいいのですが、
「メインの処理を把握し終わって(読み終わって)初めて、continueを発見できる」ことになるので、
処理の流れを把握しづらいです。

「if文見つけた時点でelse文見ろよ」って方もいらっしゃるかもしれないですが、そもそも上の書き方をしておけば、
continueを発見するのにそんな手間はいらないのです。

「処理の流れが把握しづらい」ってのがキモですね。

### empty使わないで...
empty関数は[PHPマニュアル](http://php.net/manual/ja/function.empty.php) によると`変数が空であるかどうかを検査する`とあります。
ただ、実際のところ、これが真になる条件は

* null
* false
* 空文字
* 要素が0個の配列
* 変数が宣言されているが、値が設定されていない

のように、いくつかあります。
要するに、どの条件をチェックしているのか明確ではないのです。

僕は

```php
if (strlen($str) <= 0) {}

if (count($arr) <= 0) {}

if ($intval <= 0)
```
のように、「どんな値になることを期待しているのか明確にする」ことを意識してに書くようにしています。


### 車輪の再開発しないで
そもそもですが、array_filter使えよってお話ですよ。

```php
$arr = [0, 1, 5, 0, 3];
$filtered_arr = array_filter($arr, function($val) {
  return ($val !=== 0)
});
foreach ($filtered_arr as $val) {
  echo "{$key} is not 0 : {$val}";
}
```

## クラス設計

```php
/*ShopCartController.php*/
class ShopCartController {
  // カートに入ってる商品の合計を返す
  public function item_total_amount() {}
}

/*ShopOrderController.php*/
class ShopOrderController {
  // カートに入ってる商品の合計を返す
  public function get_allitem_amount() {}
}

```
さすがにこれは大丈夫ですよね。
「馬鹿馬鹿しい...」とお思いかもしれないですが、
**実際にあった話です**

おわかりかと思いますが、
![notfood_1452931361140.png](https://qiita-image-store.s3.amazonaws.com/0/28859/8d720bd3-b8f6-b95b-5636-68a122ebe8b4.png)

ですし、書くべき場所に書きましょう。こういう処理はちゃんとまとめましょう。
あと当然ですが、まとめるべき場所はコントローラではないです。


## さいごまでありがとうございます
以上です。
GsonでEnumを処理する

* 環境：JDK8, gson-2.5

[Gsonでenumをいい感じに処理する](http://qiita.com/kazy/items/3fd0aa15345b374e7b6c) を見て気になったので。

```java:GsonEnum.java
package org.example.javalabo;

import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;

public class GsonEnum {
    public static void main(String args[]) {
        Gson gson = new Gson();
        assertThat(gson.fromJson("0", Platform.class), is(Platform.Twitter));
        assertThat(gson.fromJson("1", Platform.class), is(Platform.TwitterDM));
        assertThat(gson.toJson(Platform.Twitter), is("\"0\""));
        assertThat(gson.toJson(Platform.TwitterDM), is("\"1\""));
    }

    public enum Platform {
        @SerializedName("0")
        Twitter,
        @SerializedName("1")
        TwitterDM;
    }

}
```
`int`と`String`で変換がちょっとずれるということに目を潰れば`@SerializedName`で簡単。
JSON と Enum の対応が String で良いなら何も問題はないと思われます。
IntelliJ Community Edition で Servlet 3.1 の web.xml を編集する

IntelliJ の Community Edition で Servlet version 3.1 の `web.xml` を書くと、以下のようにエラーとなってしまう。 (Ultimate Edition ではエラーになりません)

![web_xml_error.png](https://qiita-image-store.s3.amazonaws.com/0/5822/548f8cf6-67f8-31da-b0db-504ababfa838.png)

これは 3.1 用の XML Schema ファイルが IDE に組み込まれていないから。

ファイルを自力でダウンロードして設定をするとエラーにならなくなります。

1. http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javaee/index.html#7 にある以下のファイルをどこかきまったディレクトリにダウンロードしておく
    * `web-app_3_1.xsd`
    * `web-common_3_1.xsd`
    * `jsp_2_3.xsd`
    * `javaee_7.xsd`
    * `javaee_web_services_client_1_4.xsd`

2. Preferences の Languages &amp; Frameworks &gt; Schemas &amp; DTDs の External Schemas &amp; DTDs のボックスの下部にある「+」ボタンを押す
3. URI のテキストボックスに「http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd」と入力し、 Explorer タブを選択する
4. さきほどダウンロードした `web-app_3_1.xsd` ファイルをファイルブラウザから選択し、 OK を押す
    * ほかの4つの xsd ファイルについては明示的に指定しなくても `xsd:include` によってきちんと読み込まれているっぽい

以上で `web.xml` の編集でエラーにならなくなるし、補完もちゃんときくようになります。

参考文献: [java - Missing schema definitions in IntelliJ - Stack Overflow](http://stackoverflow.com/questions/28350039/missing-schema-definitions-in-intellij)
Web Application周りのテスト方法

色々な方法があると思うけど、簡単な3種類をまとめておく。

## テスト対象のコード

```go
package main

import (
	"net/http"

	"github.com/facebookgo/grace/gracehttp"
	"github.com/sebest/xff"
	"goji.io"
	"goji.io/pat"
	"golang.org/x/net/context"
)

func main() {

	mux := goji.NewMux()

	mux.HandleC(pat.New("/*"), NewMux())

	err := gracehttp.Serve(&http.Server{Addr: ":8080", Handler: mux})
	if err != nil {
		panic(err)
	}
}

func NewMux() *goji.Mux {

	mux := goji.NewMux()

	mux.Use(xff.Handler)
	mux.HandleFuncC(pat.Get("/:name"), Hello)

	return mux
}

func Hello(ctx context.Context, w http.ResponseWriter, r *http.Request) {

	w.Write([]byte("Hello, " + pat.Param(ctx, "name") + "\nRemote Address: " + r.RemoteAddr))
}
```

## テストコード

### その1: 関数に対してテスト

普通に関数に対してテストを行う。
特に難しいことは、していない。

```go
func TestHello(t *testing.T) {

	t.Parallel()

	ctx := context.WithValue(context.Background(), pattern.Variable("name"), "john")

	req, err := http.NewRequest("", "", nil)
	require.NoError(t, err)

	resp := httptest.NewRecorder()
	Hello(ctx, resp, req)

	require.Equal(t, http.StatusOK, resp.Code)
	require.Contains(t, resp.Body.String(), "Hello, john")
	require.NotContains(t, resp.Body.String(), "127.0.0.1")
}
```

### その2: Multiplexer に対してテスト

Routing とか、 Middleware とかテストしたい時は、こっちの方が適切だと思う。

```go
func TestUsersMultiplexer(t *testing.T) {

	t.Parallel()

	mux := NewMux()

	req, err := http.NewRequest("GET", "/john", nil)
	require.NoError(t, err)

	resp := httptest.NewRecorder()
	mux.ServeHTTP(resp, req)

	require.Equal(t, http.StatusOK, resp.Code)
	require.Contains(t, resp.Body.String(), "Hello, john")
	require.NotContains(t, resp.Body.String(), "127.0.0.1")
}
```

### その3: Server を立ち上げてのテスト

E2E 的なテストをしたい時や、 RemoteAddr を用いている場合は、こちらの方法が良い。

```go
func TestServer(t *testing.T) {

	t.Parallel()

	ts := httptest.NewServer(NewMux())
	defer ts.Close()

	resp, err := http.Get(ts.URL + "/john")
	require.NoError(t, err)

	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	require.NoError(t, err)

	bodyStr := string(body)

	require.Equal(t, http.StatusOK, resp.StatusCode)
	require.Contains(t, bodyStr, "Hello, john")
	require.Contains(t, bodyStr, "127.0.0.1")
}
```

他にも良い方法あったら、コメント下さい。
Go言語 Gmailのsubjectの日本語文字化けに対応する

## はじめに
Goで[Gmail API] (https://developers.google.com/gmail/api/quickstart/go)を触っていた際に、「本文」は正しく日本語が表示されるのに「件名(subject)」が文字化けする事象に遭遇しました。

Gmail APIには、base64urlにエンコードしたstringを渡します。
下記のようなコードだと、`件名`の部分で __文字化け__ が発生します。

```go
package main

import (
	"encoding/base64"
	...
	"google.golang.org/api/gmail/v1"
)

func main() {
	...
	msgStr := "to: hoge@gmail.com\n" + "subject: 件名\n\n" + "message: 本文"
	msg := []byte(msgStr)
	message := gmail.Message{}
	message.Raw = base64.URLEncoding.EncodeToString(msg)
	...
}
```

## ハマりどころ
メールのヘッダー部分（subjectを含む）は、「７ビットアスキーコード」でなければなりません。
参考：http://hogem.hatenablog.com/entry/20100122/1264169093

Goの文字エンコーディングはUTF-8であり、1ビットが破棄され日本語文字化けを引き起こしていました。

## 対処法
下記の流れで変換してあげました。

```bash
UTF-8(Go文字列でのデフォ) -> ISO-2022-JP -> (byteスライス) -> base64urlString
```

```go
package main

import (
	"encoding/base64"
	"io/ioutil"
	"strings"
	"golang.org/x/text/encoding/japanese"
	"golang.org/x/text/transform"
	...
	"google.golang.org/api/gmail/v1"
)

// Convert UTF-8 to ISO2022JP
func toISO2022JP(str string) ([]byte, error) {
	reader := strings.NewReader(str)
	transformer := japanese.ISO2022JP.NewEncoder()

	return ioutil.ReadAll(transform.NewReader(reader, transformer))
}

func main() {
	...
	msgStr := "to: hoge@gmail.com\n" + "subject: 件名\n\n" + "message: 本文"
	// ISO-2022-JP(JISコード) へ一度変換する
	msgISO2022JP, _ := toISO2022JP(msgStr)
	msg := []byte(msgISO2022JP)
	message := gmail.Message{}
	message.Raw = base64.URLEncoding.EncodeToString(msg)
	...
}
```

参考：http://qiita.com/spiegel-im-spiegel/items/2e475b48226330aa5570

## おまけ
下記のレポジトリで実際に使っています。
https://github.com/yyoshiki41/go-gmail-drafts
自分のミスによりRoute 53のAレコード切り替えでのサーバ移行で失敗した話


はじめてDNSを使って、運営していサーバを別のサーバに移行しようと思ったときに失敗した話です。

そのサービスではドメインとサーバをRoute 53のAレコードにIPアドレスを登録して運営していました。

![server_pptx.png](https://qiita-image-store.s3.amazonaws.com/0/30079/eedf0330-47f8-888d-9b84-8d2f847c24a8.png "server_pptx.png")

Route 53でAレコードをIP-AからIP-Bに変えて移行するつもりでした。

**しかし！！！**

Route 53で実行したあと、サーバBのアクセスログを見るとアクセスは来ているのに、自分のブラウザではサーバAの情報が表示されたままです。
そうです、TTLが切れていなかったのです。概念としては覚えていたのですが、すっかり実際のを確認するのが抜け落ちていました。

![Route_53_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/30079/980abce0-327d-f725-6359-123265dd142a.png "Route_53_Management_Console.png")

Route 53では上記のように確認できます。図では180秒になってます。
そのときのドメインのTTLは1時間に設定したままになってました。
ブラウザがサーバAのドメインをキャッシュしているため、最大1時間待たないと切り替わらなかったのです。

１時間は長すぎると思うのですが、他のサービスはどれくらいにしているのでしょうか。調べてみました。


| ドメイン | TTL |
|-------------|:------------:|
| yahoo.co.jp |     300     |
| google.co.jp |     300     |
| qiita.com |     60     |

ちなみにRoute 53のAレコードのALIASに設定するときのELBのTTLは60秒になってました。

# まとめ

ドメインのAレコードのIPは切り替えるときにTTLも確認して適切な長さにする。
Dockerの作業済みコンテナからイメージを作って移植を楽にする

tuboneです。
[前回](http://qiita.com/tubone/items/11a7ceb3e7013139abab "前回")はDockerのnode.jsイメージを利用してnode.jsが動くコンテナを作り、そこからhubotを導入しました。

Dockerでは通常、イメージからコンテナを生成、起動するのが一般的ですが
前回のように、コンテナ内で作業をしてしまった場合、せっかくでしたらイメージとして保存し、別環境に簡単に移植できた方が便利です。
イメージを作る方法としてはDockerfileが定番ですが、
Dockerにはコンテナからイメージを作るCommitというコマンドがあるので今回はこちらをつかったイメージ作成をしてみたいと思います。

#dockerコンテナに接続する
###補足:コンテナからの抜け方の違い
（冗長このうえないので知っている人は無視してください）

dockerのコンテナでbashなどを起動している場合はexitで抜けるとコンテナのbashがExit（停止）して元の環境に移行しますが、バックで動かしたまま抜ける方法もあります。
Cntl + p , Cntl + q で プロセスをExitせず抜けることができます。

Exit(停止)していないコンテナに再接続するには attach を利用します。

```console
root@localhost:/# docker attach hubot1
```
停止しているコンテナを起動するにはstartを利用します。

```console
root@localhost:/# docker start hubot1
hubot1
```

#Dockerコンテナを終了させる
dockerのコンテナに接続している場合はコンテナのbash上でexitすれば大丈夫です。

```console
root@811aa8ed56dd:/# exit
exit
```
psコマンドで停止したことが確認できました。

```console
root@localhost:/# docker ps -a
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                     PORTS               NAMES
811aa8ed56dd        node                "/bin/bash"            40 hours ago        Exited (0) 7 seconds ago                       hubot1
```

また、コンテナが動いている状態でコンテナに接続されていない場合はstopコマンドでいけます。

```console
root@localhost:/# docker ps -a
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                    PORTS               NAMES
811aa8ed56dd        node                "/bin/bash"            40 hours ago        Up 5 seconds                                  hubot1
```
このようにpsコマンドで動いている状態のコンテナを確認し…
stopコマンドで…　コンテナを停止させます。

```console
root@localhost:#/ docker stop hubot1
hubot1
```
exitしていることが確認できました。

```console
root@localhost:/# docker ps -a
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                     PORTS               NAMES
811aa8ed56dd        node                "/bin/bash"            40 hours ago        Exited (0) 4 seconds ago                       hubot1
```

#停止したDockerコンテナからイメージを作る

停止したコンテナからイメージを作るときはcommitコマンドを使います。

```console
root@localhost:/# docker commit hubot1 hubot:tubone
292281c11f0c2adf2a052b2b30625df0f48d81d3ab523635eb97b360f03096b4
``` 
imagesコマンドで確認してみます。

```console
root@localhost:/# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
hubot               tubone              292281c11f0c        49 seconds ago      691 MB
node                latest              8c599b26d97b        2 days ago          643 MB
``` 
hubot:tuboneができていることが確認できました。

#作ったDockerイメージからコンテナを作る

runでコンテナを生成起動します。
ここらへんは前回と同じです。 

名前は便宜上hubot2にしました。

```console
root@localhost:/# docker run -it --name "hubot2" hubot:tubone /bin/bash
root@f1bff93c0d2c:/#
```

お疲れ様でした。
AWS ELB(Elastic Load Balancer)を使うときの注意点

# はじめに

ELB導入時に注意すべき点があったので、紹介します。

特に注意すべき、以下の点について紹介します。

* KeepAliveの設定
* リダイレクトの設定
* ELBを配置するVPCサブネットの大きさ
* ELBを配置するVPCサブネットのACL

# WebサーバにKeepAliveを設定する

ELBからWebサーバへ接続する際に、TCP KeepAlive機能を有効にすることで、TCPコネクションを維持し、接続効率を向上させることができます。

例えば、Apacheでは以下の設定項目を修正します。
Keepaliveのタイムアウト時間は、長めに取ることで効果を得ることができます。

```httpd.conf
KeepAlive On
KeepAliveTimeout [ELBのタイムアウト時間より長い時間]
```

検索すると120秒という文献が多く出てきますが、ちょっと古い記事がほとんどです。
もしかすると、昔はタイムアウト時間が60秒に固定されていたのかもしれませんが、現在はタイムアウト時間も設定することができるため、サービスに応じて変更すればよいと思います。

http://kunihikokido.tumblr.com/post/55651256550/amazon-elb-%E3%82%92%E4%BD%BF%E3%81%86%E3%81%A8%E3%81%8D%E3%81%AFkeepalive-on-timeout-120

# Webサーバでのリダイレクトの設定

例えば、正規のドメインへリダイレクトしたいとき、HTTP->HTTPSにリダイレクトしたいときなど、Webサーバ側でリダイレクトを行う事があると思います。
このとき、ELBのヘルスチェックでアクセスしたときに、リダイレクトレスポンスを返してしまうと、サーバが落ちていると判定されてしまいます。

そのため、ELBのヘルスチェックからのアクセスでは、リダイレクトをしないように工夫しましょう。
Apacheのmod_rewriteを使うときであれば、RewirteCondでUser-Agentを判定して、リダイレクトを行わないようにすることができます。

```httpd.conf
  <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTP:X-Forwarded-Port} !^443$
    RewriteCond %{HTTP_USER_AGENT} !^ELB-HealthChecker # User-Agentで判定する
    RewriteRule ^(.*)?$ https://example.net$1 [R=301,L]
  </IfModule>
```

# ELBを配置するVPCサブネットの大きさ

ELBはアクセス数に応じてオートスケールアウトをします。
このとき、ロードバランサの台数が増加するので、ELBで利用するVPCのプライベートIPアドレスも増加します。
ELBを配置するサブネットが小さすぎるとスケールアウトできなくなるので、サービスの規模に応じて、サブネットは少し大きめに設計する方がよさそうです。


# ELBを配置するVPCサブネットのACL

ELBを配置するサブネットのACLでは、WebサーバからTCP1024-65535のインバウンドを許可しなければなりません。
Linuxの標準的なエフェメラルポートは32768-65535ですが、ELBで利用するポートは非常に広いため、設定に注意が必要です。



http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/VPC_ACLs.html#VPC_ACLs_Ephemeral_Ports
PSR-7のミドルウェアは、何故ああなのか？

> [追記：2018/03/04] ミドルウェアの仕様が「[PSR-15: HTTP Server Request Handlers](https://www.php-fig.org/psr/psr-15/)」として標準化されました。ここで説明した内容と大きく異るインターフェースが採用されてます。採用の経緯は[こちらのPSR-15ブログ（英語）](https://mwop.net/blog/2018-01-23-psr-15.html)が参考になります。

PSR-7のフレームワークとしては、[zend-expressive](https://github.com/zendframework/zend-expressive)、[SlimPHP/Slim 3](http://www.slimframework.com/)、そしてフレームワークではありませんが[Relay/Relay](http://relayphp.com/)などが出てきました。

嬉しいのは、ミドルウェアのAPIが全て同じことです。

```php
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

function __invoke(
    ServerRequestInterface $request, 
    ResponseInterface $response, 
    callable $next);
```

ひとつミドルウェアを作れば、上記3つのフレームワークのどれでも使いまわせることになります。

なんて素晴らしい！

でも、**なぜ、ミドルウェアはこの形なのでしょう？**

### Express.JS

この形は、node.js用のウェブアプリケーションフレームワークである[Express.js](http://expressjs.com/ja/)のミドルウェアと同じ、という説明があります。でも、答えになってない！

疑問が頭から離れず夜も寝られなくて。やっといくつか理由を考えついたので書いてみます。



ServerRequestInterface `$request`
---------------------------------

まずは最初の引数、`$request`から。

これがないと、なんの処理をしていいのか皆目わからない。ので、必須なのは自明、と言った感じでしょうか。

ちなみに。

Symfonyや、同じコンポーネントを使っているStackPHPでのミドルウェアは、`$request`だけにフラグが２つという構造になっています。（[HttpKernelInterface](https://github.com/symfony/http-kernel/blob/3.0/HttpKernelInterface.php)参照）

> 例えばAPIを`$request`だけにしてしまえば、簡単で分かりやすいのに、なぜ3つも引数が増えてしまうのだろう？というのが疑問の始まり。


ResponseInterface `$response`
-----------------------------

次は`$response`。

ミドルウェアに、なぜレスポンスオブジェクトが必要なのか？

PSR-7や最初に説明したミドルウェアの大事な点として、**フレームワークに依存しないコードを書きたい**というのがあります。

例えば認証用ミドルウェアなどは、認証に失敗した場合にレスポンスを返す場合があります。**フレームワークに依存しないということは、オブジェクトを生成できない**、と同じことだと気が付きました。

実際にPSR-7には**オブジェクト生成に関するAPIはありません**。

なので、レスポンスオブジェクトを渡してもらう必要があるわけです。


callable `$next`
----------------

最後の`$next`というコーラブル変数。これは、こんな感じで使います。

```php
function __invoke($req, $res, $next) {
    // ここで前処理をする！
    if($next) {
        $res = $next($req, $res); // next, please!
    }
    // ここで後処理もできる！
    return $res;
}
```

この形の良い所は、**次のミドルウェアを呼ぶ前と後の両方で処理を書ける**ことです。

ところで`$next`がない場合は、どうやって後処理をするのでしょう？

Symfonyの場合は、[TerminableInterface](https://github.com/symfony/http-kernel/blob/3.0/TerminableInterface.php)というのを使います。ミドルウェアが`TerminableInterface`を実装している場合は、*アプリの実行が終了*したら、`terminate`メソッドが呼ばれることになってます。

> 多分。実は確認できないので、間違ってるかも。

突然、**面倒な感じになってきました**。

また前処理、後処理以外でも、場合によっては**次の処理を呼ばない**という実装も簡単に実装できます（コメント参照）。外側のフレームワークに依存することなく、とても柔軟性の高い処理を実装できるといえると思います。

最後に
====

今のAPIで最初に疑問に思ったのは、`$next`が入ることでした。本来の処理に必要な`$request`と`$response`以外に、次のミドルウェアを呼び出すという、別の責務がミドルウェアに発生するからです。

> このAPIでミドルウェア作ると、他の形に応用しずらい気がするんですよね。理由は`$next`が入り込んでくるから。

でも、この形が一番シンプルになる気がしてきました。やはり使われるコードというのは理由があるのですね。後から考えると当たり前な結論な気がしますが、考えている間は面白かったです。

> なお、この形が**本当に標準のようになるかは、まだ分かりません。**
Nginx 基本設定

# Nginx設定基本
nginxの簡単なまとめ。

## 設定ファイル

基本設定は /etc/nginx/nginx.conf に書く。
nginx.confにはデフォルトのログの設定やworker processの実行ユーザー等の設定が記述されている。
webサーバーなどの詳細設定は/etc/nginx/conf.d/*.conf に書いていく。

### 設定例
設定のまとまりをディレクティブとよぶ。
ディレクティブはhttp, server, locationの順にネストされたブロック({}で囲われる。)によって表現される。



例

```
http {
  server {
    listen 80;
    server_name example.com;
    
    location / {
      127.0.0.1:3000;
    }

    location /static/ {
      /var/www/static/
    }
  }
}

```
上記の例では以下のことをしている。

- バーチャルホストexample.comの80番ポートをhttpプロトコルでlistenする。

- example.com以下をローカルホスト127.0.0.1:3000に対応させる。

- example.com/static/以下を/var/www/static/に対応させる。

- nginxの実行ユーザーが/var/www/staticへのアクセス権を持たないとforbiddenエラーが起きる。


*****

適宜追記。
拡大鏡のショートカット


プレゼンテーションのときなどに、細かい文字が見にくいかなーと思いつつ、画面の解像度をいちいち変更するのはアフォだなーと思っていたら、MSのイベントで拡大鏡を使いまくっていた。

拡大鏡をGUIで起動するのはまた手間がかかるのだが、ショートカットが一通り分かったので、メモ。

    [Windows]キー＋[＋]キー    拡大
    [Windows]キー＋[－]キー    縮小（ただし、100％未満にはならない）
    [Windows]キー＋[Esc]キー    拡大を解除し、通常に戻る
    
これで多少はプレゼンテーションがスマートになるだろうか。
Goで帳票をPDFに作成するライブラリ。 請求書などの複雑なフォーマットにも対応

[goreport https://github.com/mikeshimura/goreport](https://github.com/mikeshimura/goreport)

下記のサンプルの様なレポートが、作成可能です。
プログラムですべてコントロール出来るので、色々な要件に対応出来ます。
例えば

- 上の行と同じ項目は非表示にする。　
- 相手先毎の　１ページ目と２ページ目以降のFormatを変える。
- 小計を表示したいが、対象が一行の場合は表示不要
- あるグループがブレークしたら、強制的に改ページする。
- ページ xx of xxx (トータルページ）の表示を、グループブレークでページが１から振り直した場合でも対応する。

単純なレポートのサンプル  
![Simple1](https://bytebucket.org/mikeshimura/goreport/wiki/image/simple1.jpg "Simple1")  

[pdf](https://bytebucket.org/mikeshimura/goreport/wiki/pdf/simple1.pdf)  


中程度のレポートのサンプル  
![Medium1](https://bytebucket.org/mikeshimura/goreport/wiki/image/medium1.jpg "Medium1")

[pdf](https://bytebucket.org/mikeshimura/goreport/wiki/pdf/medium1.pdf)  



複雑なレポートのサンプル  
![Complex1](https://bytebucket.org/mikeshimura/goreport/wiki/image/complex1.jpg "Complex1")

[pdf](https://bytebucket.org/mikeshimura/goreport/wiki/pdf/complex1.pdf)  


![Complex2](https://bytebucket.org/mikeshimura/goreport/wiki/image/complex2.jpg "Complex2")

[pdf](https://bytebucket.org/mikeshimura/goreport/wiki/pdf/complex2.pdf)
XMLを駆逐する

# XMLと私

というわけで、設定ファイルや何やらでXMLを使っていたり、サーバとの連携でXMLしか返さないAPIを叩いている開発者はまだそれなりにいると思います。中には返されるXMLが正しくパースできない形式なのでクライアント側で修正するなど涙ぐましいコードをコミットして血潮を沸かせている人もいるに違いありません（実体験）。

Appceleratorのトレーニングでも、サーバとの連携ではJSON形式のデータでやり取りすることが推奨されています。理由は、JavaScriptなのでそのままパースして利用できることに加えて、XMLと比較してやり取りするデータのペイロードが少なくて済むからです。

とはいえ、既存のAPIサーバがJSONに対応していなければ綺麗事はいってられないのも事実。TitaniumにもXMLを扱う機能は用意されており、ものすごく頑張ればSOAPも利用できるのですが、出来ることなら避けたいところ。

# 変換しちゃおう

そこで、クライアント側でXMLをJSONに変換して利用する方法を検討してみました。まず最初にNode.jsの状況を確認したところ、[xml2js](https://www.npmjs.com/package/xml2js)というパッケージがポピュラーなようです。ざっと確認したところ、でもこのままではTitanium上では利用できません。

そこで、ブラウザで利用するために[ビルド済みのJSファイル](https://github.com/ron-liu/xml2json/blob/master/xml2json.js)があったのでこちらを使ってみました。requireから呼び出せるように末尾に

```js
module.exports = xml2json;
```

一行だけ追記しておきます。使い方はこちらの通り。以下、app/assets/直下にtest.xmlというファイルが存在する前提で書いています。

```js
var xml2json = require('xml2json');
var file = Ti.Filesystem.resourcesDirectory + 'test.xml';
var xmlString = Ti.Filesystem.getFile(file).read().toString();
Ti.API.info(xml2json.parser(xmlString));
```

これで動作します。簡単ですね。

簡単ですよ。

ええ。

ライセンスさえ無視すれば、ね。

そうなんです、このxml2jsonライブラリはGPL V.2で公開されているので、この使い方だとソースコードを公開する必要がありそうですね。実際どうなのか確認したことはないのですが、法務部に確認したしと思へども個人事業主だから法務部とかないし、せめては新しき背廣をきてきままなる旅にいでてみん（萩原朔太郎）じゃなかった、GPLの精神は尊重しましょう。

# 他のライセンスで再挑戦

言葉にできない悲しい事情からソースコードを公開できない場合は、また別の解決方法を探す必要があります。そこでもうちょっと検索したら、なんだ@hamasyou作のこんなのがあるじゃないか。

http://hamasyou.com/blog/2010/09/15/titanium-xml2json-xml-json/

手元のテストファイルでは大丈夫だったので、これをrequireできるようにします。しました。こちらに置きました。

https://gist.github.com/yagitoshiro/1eb671efc203b4a2086c

末尾に以下を追記しただけです。

```js
function xml2json(dom){
  var parser = new com.hamasyou.XML.TiDomParser();
  return parser.dom2Json(dom.documentElement);
}
module.exports = xml2json;
```

使い方はいたって簡単、requireしてTitaniumのXMLオブジェクトを渡すだけ。

```js
var xml2json = require('xml2json');
var file = Ti.Filesystem.resourcesDirectory + 'test.xml';
var xmlString = Ti.Filesystem.getFile(file).read().toString();
var xml = Ti.XML.parseString(xmlString);
Ti.API.info(xml2json(xml));
```

こちらは元々Artistic licenseなのでプロプライエタリなプロダクトでの再利用も問題ありません。

# その他のやり方

他にも既存のXML => JSONライブラリをWebViewとevalで呼び出す方法もありますが、その時は改行に注意しましょう。

```js
var file = Ti.Filesystem.resourcesDirectory + 'test.xml';
var xmlString = Ti.Filesystem.getFile(file).read().toString();
$.webview.addEventListener('load', function(e){
  var data = $.webview.evalJS('xml2json("'+xmlString.replace(/[\r\n]/g, '')+'");');
});
```
ELBがかんでて.htaccessでのリダイレクトがうまく機能しなかったときの対応

# .htaccessのリダイレクトが上手くいかない

先日あるECサイトをリリースするに当たって、メンテナンス画面を表示するように`.htaccess`ファイルでリダイレクトの設定をしていたのだが、なぜかメンテナンス画面は表示されず、真っ白な画面が表示されてしまった。

VM上のデモ環境やお客さんの検証環境でも問題なくリダイレクトされていたので、
当時は(　ﾟдﾟ)ﾎﾟｶｰﾝ　となったw

# 実際の記述内容
リダイレクト処理を記述した`.htaccess`をさらす。

```apache:.htaccess
# カスタマイズしたメンテナンス画面のURL
ErrorDocument 503 /maintenance.html

# リライトルール
RewriteEngine On

# メンテナンス画面リダイレクト処理
RewriteCond %{REQUEST_URI} !^/maintenance.html
RewriteCond %{REMOTE_ADDR} !^××.××.××.××
RewriteRule ^(.*)$ [L,R=503]
```

やってることは、指定のグローバルIP以外からのアクセス、かつhttp://_ドメイン_/maintenance.htmlじゃなければメンテナンス画面にリダイレクト。
これで大丈夫と思っていたのだが、結果は画面が真っ白…

※ちなみにR=503なのは、Google先生に覚えられてしまうのを避けるためです。


# 原因と対応方法
なんかエラー出てんのかなーと思い、ログを確認してみたところ、ELBの`heathcheck`さえもリダイレクトしてしまっているので、ELBからすれば「あ、コイツ死んでるな。」と判断されてしまい、通信が終了してしまっていた模様。
対応方法は、以下の一行を追加したらOKだった。

```apache:追記内容
RewriteCond %{REQUEST_URI} !^/healthcheck.html
```

`healthcheck`は通さないとねー。

しかし、今度は指定のグローバルIPでもメンテナンス画面が表示されてしまう問題が発生。
これはちょっと見たらすぐに分かることだが、ELBからサーバーへの通信では、そのままではIPが取得できないので`X-Forwarded-For`で記述する必要がある。

```apache:変更点
RewriteCond %{REMOTE_ADDR} !^××.××.××.××
↓
RewriteCond %{HTTP:X-Forwarded-For} !^××.××.××.××
```

はい。これで問題なく、指定のグローバルIPではサイトが見れた。

# まとめ
LBの設定とかLBからの通信など、インフラ周りはまだまだ勉強不足なため度々こける。ちゃんと勉強しよう。また、リダイレクト処理を書くための正規表現の勉強する必要があるな。
Ubuntu 15.10 でシリアルコンソールを有効にする

KVMの仮想マシンとしてUbuntu 15.10を立ち上げたのですが、シリアルコンソールを有効にする方法を探すのに手間取ったので紹介します。

## ブート後にシリアルコンソールを有効にする

`ubuntu serial console`などのワードで検索をしても、以前のupstartでの方法が多くヒットしてしまいます。Ubuntu 16.04からはsystemdに移行してしまうので、systemdでの方法が望ましいです。

検索していたところ、こちらの記事が見つかったので参考にしました。
http://qiita.com/h141dev/items/195a28a08eccb89a38d3

どうやら`/etc/systemd/system/getty.target.wants/serial-getty@ttyS0.service`に設定が用意されているようなので、enable, startをおこなうのみでよさそうです。

以下のコマンドのみで終了です。

```console
$ sudo systemctl enable serial-getty@ttyS0.service
$ sudo systemctl start serial-getty@ttyS0.service
```

## ブート時からシリアルコンソールを有効にする

OSがブートする前からシリアルコンソールを有効にするためには、GRUBへの設定が必要です。
以下の設定を`/etc/default/grub`に追加して、`update-grub`を実行します。

```:/etc/default/grub
GRUB_TERMINAL=serial
GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"
```

```console
$ sudo update-grub
```
シェルスクリプト　その１

シェルについての知識は浅いですが、今読んでる本の気になったところをメモしておきます。

・シェルにはいくつかの種類があるがスクリプトを書くときは、どのマシンも搭載しているBシェルで書こう。

・スクリプトファイルの冒頭の一行目を"#!/bin/sh"にすることでBシェルで実行される。また、何も書かなければ現在使用中のシェルが自動的に選択される。

・今までよく見る機会はあったが使うこともあまりなかった"chmod"はファイルのアクセス権変更のためのコマンド。オプション・使用例はhttp://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230728/?rt=nocnt

・シェルでは改行（エンターキー）ごとに一つのコマンドが実行される。二行に分けて書くなら"\"で区切れる。

・一つの行に複数コマンドを記述する場合は";"でコマンドごとに区切る。

・シェルではC言語などとは違い０が真、それ以外は偽。

・"|": パイプラインは左側コマンドの実行結果を右コマンドの入力として処理する。

・"&"をコマンドの後ろにつけるとバックグラウンドで実行。バックグラウンドはサブシェルであるためサブシェル上で実行される。Ex:"make &"　オプションは"&"の前か後かがわからない。

・"||"は左側コマンド失敗時のみ右側コマンドを実行。

・"&&"は左側コマンド成功時のみ右側コマンド実行。

・"()"でコマンドを囲むとサブシェルで実行するので現在使用しているシェルで作業を続けれる。

・"{}"でグルーピングすることでコマンドの結果をひとまとめに表示可能。コマンドごと";"で区切る（最後のコマンドも）。

・"test"コマンドはよくわからないが"[]"で代用可能で中にはオプション・引数が入る。

参考資料：入門UNIXシェルプログラミング　改訂第２版　第１章（発行所：SBクリエーティブ株式会社）

余談：　まだこの本は読み始めたばかりですがかなり読みやすく楽しめるので、シェルスクリプトに興味のある方はぜひ購入を検討して良いと思います。

[シェルスクリプト　その２](http://qiita.com/woolon/items/c69482474ba1564d5057)
[シェルスクリプト　その３](http://qiita.com/woolon/items/59c26dcb040adefae0f3)
[シェルスクリプト　その４](http://qiita.com/woolon/items/514db422f8ccea0ca94c)
[シェルスクリプト　その５](http://qiita.com/woolon/items/6366dd6dac12387d84b7)
[シェルスクリプト　その６](http://qiita.com/woolon/items/6e89c67220b9095a6414)
[シェルスクリプト　その７](http://qiita.com/woolon/items/4e3c986587f428742b79)
【便乗】フィボナッチ数列でベンチマーク


### 参考

[フィボナッチで各種言語をベンチマーク @tukiyo3](http://qiita.com/tukiyo3/items/2f9f8f9821a1fa09d597)を見て，D言語がないとぼやき，
[フィボナッチで各種言語をベンチマーク - satosystemsの日記](http://d.hatena.ne.jp/satosystems/20121228/1356655565)を見て，Nim がないからやろうかと思った男がいたそうな．


# フィボナッチ数列でベンチマーク - 便乗編
## 対象言語
というわけで，C と D言語 と Nim で比較しようと思います．
Nim 使ったことなかったので，試してみたかっただけです．

## 結果

計測方法：10回くらい`time`コマンド使った上でおおまかに平均をとる

| 言語 | 時間<small>[s]</small> |
|:---:|:----:|
|  C  | 0.60 |
| Nim | 0.61 |
|  D  | 0.94 |


### 感想

+ Nim が思いのほか頑張ってる
+ D言語はもうちょっと頑張れよ
+ 計測方法がゆるふわすぎる気もするが，見た感じ Nim と C に有意差はなさそう
+ D言語と計測方法はもうちょっと頑張れよ


## コードとか
参考記事と同じにしているのであまり意味もないですが載せます．
たぶん一番ベーシックな実装です．

### C
古き良き，ときどきクソ野郎○と叫びたくなる，可愛いやつ．

``` fib.c
#include <stdio.h>

int fib( int n )
{
	return n < 2 ? n : fib( n - 1 ) + fib( n - 2 );
}

int main(void)
{
	printf("%d\n", fib(40));
	return 0;
}
```

`-O3`オプションの`gcc-4.8.4`でコンパイル

### D言語
我らがアイドルD言語くんは今回登場しません．

```fib.d
import std.stdio

int fib( int n )
{
	return n < 2 ? fib( n - 1 ) + fib( n - 2 );
}

void main(void)
{
	fib(40).writeln;
}
```

`dmd-2.66.0`でリリースビルド

### Nim
Python みたいな構文．

```fib.nim
proc fib( n: int ): int =
	if n < 2: n else: fib( n - 1 ) + fib( n - 2 )

echo( fib(40) )
```

これも最適化オプションつけて`nim-0.12.0`でビルドしてます．

前は生理的に受け付けなかったPythonを最近克服しつつあるので好印象を抱いている一方，<del>環境である</del>エディタであるVimさんのご機嫌が斜めなせいで，Vim script書いてる時間の方が長いっていうね．．．
[JavaプログラマのためのHaskell]三日目・型の話

[前回](http://qiita.com/noco/items/4b448d518b428a7310e8)の続き.

<h1>静的型チェックと型推論</h1>
**静的な**：　「コンパイル時に」.つまりコンパイル時に処理系が型をチェックしてくれるということ.
**型推論**：　引数や返り値の型宣言を省略しても、言語処理系がその型を推論して補ってくれる→Haskellでは、必ずしも型を明示的に書かなくてもいい.

<h1>基本的な型</h1>
・Int：　最低30ビット幅の符号付き整数値　※例　-1, 0, 1, 1000
・Char：　文字　※例　`a`, `A`, `\n`
・String：　文字列　※例　"abc", "String"
・Bool：　真偽値　※例　True, False
・[◯◯]：　◯◯のリスト.[Char], [Int]など　※例　[1, 2, 3]
この他にもあるがまた今度.


<h1>関数の型</h1>
引数の型と返り値の型の組み合わせで関数の型の表現をする.
例えば、引数が文字列で、返り値がリストであるlines関数は、以下.
String -> [String]
これは、第一引数がStringで、第二引数が[String]の関数の型.
一般に関数の型は以下のように表す.
第一引数の型 -> 第二引数の型 ->...->返り値の型

<h1>型変数</h1>
例として、length関数の型を見た時、その型は
[a] -> Int
であり、このaを型変数と言い、どんな型と置き換えても良いことを表す.aに限らずアルファベット小文字であれば何でも使える.

<h1>型の宣言</h1>
Haskell処理系では型推論の機能があるので、必ずしも型を宣言する必要はないが、明示的に型を宣言することもできる.一般的な型の宣言は以下.
関数名::第一引数の型 -> 第二引数の型 ->...-> 返り値の型


今回はここまで！
[第二回](http://qiita.com/noco/items/4b448d518b428a7310e8#_reference-efca621a02ce4c3804e4)
[第四回](http://qiita.com/noco/items/2b93de4fa45f71d7b4b5)

出典
青木峰郎.ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門.ソフトバンク クリエイティブ株式会社,2006,372p.
Ruby | 継承元を除外して、新しく追加したメソッドだけを表示する方法

# 結論

`methods` / `instance_methods` の引数に false を与えれば良い。

```rb
Example.methods(false)
```

```rb
Example.instance_methods(false)
```

# 問題

たとえば次のクラスがある場合。

```rb
class Example < BasicObject
  def self.some_method
  end
end
```

クラスメソッドを一覧表示してみると。

```rb
Example.methods
```

結果は。

```rb
[:some_method, :allocate, :new, :superclass, :freeze, :===, :==, 
:<=>, :<, :<=, :>, :>=, :to_s, :inspect, :included_modules, :include?, :name, :ancestors,
 :instance_methods, :public_instance_methods, :protected_instance_methods, 
:private_instance_methods, :constants, :const_get, :const_set, :const_defined?, 
:const_missing, :class_variables, :remove_class_variable, :class_variable_get, 
:class_variable_set, :class_variable_defined?, :public_constant, :private_constant, 
:singleton_class?, :include, :prepend, :module_exec, :class_exec, :module_eval, 
:class_eval, :method_defined?, :public_method_defined?, :private_method_defined?, 
:protected_method_defined?, :public_class_method, :private_class_method, :autoload, 
:autoload?, :instance_method, :public_instance_method, :nil?, :=~, :!~, :eql?, :hash, 
:class, :singleton_class, :clone, :dup, :itself, :taint, :tainted?, :untaint, :untrust, 
:untrusted?, :trust, :frozen?, :methods, :singleton_methods, :protected_methods, 
:private_methods, :public_methods, :instance_variables, :instance_variable_get, 
:instance_variable_set, :instance_variable_defined?, :remove_instance_variable, 
:instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, :extend, 
:display, :method, :public_method, :singleton_method, :define_singleton_method, 
:object_id, :to_enum, :enum_for, :equal?, :!, :!=, :instance_eval, :instance_exec, 
:__send__, :__id__]
```

多いよ！

# 解決

引数に false を与えて実行した場合。

```rb
Example.methods(false)
```

結果は。

```rb
[:some_method]
```

超いいね！

## 補足

インスタンスメソッドの表示についても、事情は同じである。

```rb
Example.instance_methods
Example.instance_methods(false)
```


# 余談

「メタプログラミング Ruby (第二版)」 でこの使い方を知ったのだが。
具体的な書き方を忘れていた。

`methods_without_ancestors` (例) とかいう感じで、別のメソッドを探していた。ググってもうまく見つからなかった。
結果は同じメソッドの引数違いだった。

# 環境

- Ruby 2.2.4



<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# メンター受付


https://menta.work/user/5694

<!-- Update From Qiita API -->
Ruby 勉強メモ（１）-最初の一歩-

# Ruby 勉強メモ（１）
## はじめに
Rubyを始めた頃の勉強メモが残っていたので振り返り。
ほとんど個人的にビックリしたことをメモしていた程度のものです。

## Ruby の特徴
- Ruby は全てがオブジェクト。
- nil とは値がないというオブジェクト
- 破壊的メソッドと非破壊的メソッドがある
- if 文は後置でも大丈夫らしい。ソースの意味合いで変えるとgood！！
- 「p」はPHPでいう「var_dump」
- メソッド呼び出し時、()省略可。
- セミコロンもいらない。
- ブロックという概念。
 - スコープを意識する必要有り
- メソッド呼び出し時、値の返却時 return がいらない！！

## Rubyのnilチェック、空文字チェックについて

- nil?
 - nilの場合true
 - それ以外はfalse

- empty?
 - StringやArrayに実装されているメソッド
 - 空の文字列や配列の場合true
 - nilに対して呼び出すとNoMethodError?が発生する(超注意)

- blank?
 - nil? + empty?のようなメソッド
 - nilまたは空のオブジェクトをチェックできる。
 - Railsで拡張されたメソッドなので、Rubyのみでは使えない

- present?
 - !blank?を実行する
 - Railsで拡張されたメソッドなので、Rubyのみでは使えない

通常のRubyでnilチェックと空文字チェックを同時に行う場合は下記のような書き方になる。
変数.nil? || 変数.empty?
nil?とempty?を逆にすると、変数がnilの場合.empty?を行うと、
NoMethodErrorをはくので注意が必要。

## 文字操作
s = 'welcome to Ruby World'
puts s[0]	#=>w
puts s[0,1]	#=>w
puts s[0,2]	#=>we
puts s['Ruby']	#=>Ruby
puts s['hoge'] = 'hoge'	#welcome to hoge World!

なん・・・だとっ・・・！
文字列操作ってこんなに簡単でしたっけ？

# 文字列への * 
あと、こんなこともできる。
puts 's' * 10	#=> ==========

デバックする時に、「p」と一緒にすごい重宝しています


# 感想
当時はプログラマーとして９ヶ月目くらいで、
JavaとPHPしか経験していなかったので、
Rubyの世界が本当に新鮮でした。

もう少し深いところまでRubyは勉強していきたいです。
Dockerのエラー対処方法 /var/run/docker.sock: no such file or directory.




* メモ


## エラー内容

```
docker run -it ubuntu:14.04 /bin/bash
Post http:///var/run/docker.sock/v1.20/containers/create: dial unix /var/run/docker.sock: no such file or directory.
* Are you trying to connect to a TLS-enabled daemon without TLS?
* Is your docker daemon up and running?
```


## 対処

* env コマンド打って、DOCKER_HOSTがあるか確認する
 * env | grep DOCKER
* sudo で実行しない



## 参考

* [boot2docker - docker error: /var/run/docker.sock: no such file or directory - Stack Overflow](http://stackoverflow.com/questions/25372781/docker-error-var-run-docker-sock-no-such-file-or-directory)
sqlite3 の bundle install が上手くいかなかった時のお話


# sqlite3 の bundle install が上手くいかなかった時のお話
## 事象
aws に上げた unicorn のエラーログが常に出力されていた
(気づかずに寝たため、起きた時には大量のログが・・・orz

```
/home/centos/app/vender/bundle/ruby/2.1.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/connection_specification.rb:177:in `rescue in spec': Specified 'sqlite3' for database adapter, but the gem is not loaded. Add `gem 'sqlite3'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord). (Gem::LoadError)
```
sqlite3 がダメって言ってる？
確かに bundle install した時に何かがひっかかっていた記憶が・・・

調査してみたところ、原因が判明。

## 依存ファイルが問題
sqlite3 は依存ファイルが必要とのこと。
というわけで、yum でインストール

```
sudo yum install sqlite-devel
```

そのあと、bundle install で問題なくsqlite3が入ったことを確認。
無事に unicorn から大量のエラーログが出なくなったことを確認できました。
めでたし、めでたし。
fluentdのdstatプラグイン設定でハマった時のメモ


## はじめに
* 以下の記事を参考させていただいてfluentdのdstatプラグイン設定を試してみた際に、設定でハマって試行錯誤したときのメモ。
  - http://blog.nomadscafe.jp/2014/03/dstat-fluentd-elasticsearch-kibana.html
  - 記事時点からdstatプラグインとmapプラグインでバージョンアップがあり、それに伴いいくつか変更点があり設定がうまく行かなかったことが原因だったが、発生したエラー内容見てもいまいち原因がわからず試行錯誤する中で解決したので備忘録的にメモ。

## 前提条件
### 検証に用いた環境
* CentOS 7.1 64bit (Vagrant上のVM)
* fluentd (td-agent) 0.12.19
* fluent-plugin-dstat 0.3.1)
* fluent-plugin-map 0.0.5
* dstat 0.7.2

### 検証に用いたシステム構成
前述の記事などを参考にしてFluentd+ElasticSearch+Kibana+dstat環境を構築。

## うまく行かなかった最初の設定
```/etc/td-agent/td-agent.conf
  <match dstat>
    type map
    tag "map.dstat.cpu-usr"
    time time
    record {"value" => record["dstat"]["total cpu usage"]["usr"], "stat" => "cpu-usr", "host" => record["hostname"]}
  </match>
```
## 上記設定で発生した事象
* td-agentのサービスを起動するとコケる(FAILED)。
* 下記のようなエラーを吐く。

```/var/log/td-agent.log
2015-12-31 18:43:19 +0000 [error]: unexpected error error="undefined method `dstat' for #<String:0x007f22ccfca508>"
2015-12-31 18:43:19 +0000 [error]: suppressed same stacktrace
````
* データが出力(output)されない。

## うまく行かなかった理由
* fluent-plugin-dstatのレコード出力内容が微妙に変わった。→レコード名がスペース区切りからアンダースコア区切りに変わった。
    - 旧フォーマットの例："total cpu usage"
    - 新フォーマットの例："total_cpu_usage"
* fluent-plugin-mapの設定フォーマットが微妙に変わった？
  →プラグインのREADMEのサンプルをtagとrecordの中身はカッコで囲むようにフォーマットが変わった模様。
    - 旧フォーマット例：tag "map.dstat.cpu-usr"
    - 新フォーマットの例：tag ("map.dstat.cpu-usr")

## うまく行った設定
以下のとおり設定を修正したらうまく行った。

```/etc/td-agent/td-agent.conf
  <match dstat>
    type map
    tag ("map.dstat.cpu-usr")
    time time
    record ({"value" => record["dstat"]["total_cpu_usage"]["usr"], "stat" => "cpu-usr", "host" => record["hostname"]})
  </match>
TerminalからIntelliJ IDEAを開く


こんな感じでエイリアス作っておく。

```.bashrc
alias ij='open -b com.jetbrains.intellij'
```

こんな感じで呼べば、そのフォルダをIntelliJ IDEAで開いてくれる。

```bash
$ cd ~/your_repository
$ ij .
```

ghq + pecoでターミナルからインクリメンタルにリポジトリ探して、そのままIntelliJ IDEAで開けるのでめっさ捗る。
ListViewのスクロール時に背景が黒くなる場合は、cache color hintを設定する。

ListViewは、スクロール時に背景が固定色(#FF191919)で塗りつぶされるので、背景色を黒から変更したListViewの場合は、cache color hintに、背景色に近い色を設定しておくと、幸せになれる　というお話。

背景が単色でない場合は、#00000000(透明)を設定するといいらしい。

なんでこんな事になっているかというと・・
スクロール可能なことを示すために、端の方に影を付ける処理をしているから。

その時に、Porter-Duff(色のブーリアン演算みたいなことをするもの)で色をとってきて、塗り重ねて・・とかすると、(単色背景の場合は毎回同じ色を取得することになるし)処理が無駄すぎるので、先に色を決めておけばいいよね、デフォルト色は黒だし。
というのが、cache color hintに設定されている値(#FF191919)。

情報源(英語)：
http://android-developers.blogspot.jp/2009/01/why-is-my-list-black-android.html

翻訳版(日本語)：
http://www.techdoctranslator.com/resources/articles/articles-index/listview-backgrounds


ついでなので。
スクロールしなくてもリストの背景色がおかしいよ？という場合は、リストのアイテムの背景色に`@null`などを入れておくと幸せになれるはず。テキストカラーにも気をつけよう！(クリックした時も、要チェック。)
※設定するのは、ListView自体ではなくて、ListViewに表示されるアイテムのレイアウトの方。

この場合の背景色がおかしくなる原因は、Styleで設定された(半透明な)背景色が、パーツを重ねた回数分、塗り重ねられているから。

ちなみに、フラグメント(ListFragmentとか)の場合はテーマ(スタイル)が反映されなかったりするので、要注意。StackOverflowの隠れた常連さんだったり・・
Activityでテーマを適用したContextを元に、フラグメント側でそのテーマを適用したContextWrapperを・・とか色々方法はあるようですが、ListViewのように、入れ物と中身が独立しているものは、ほぼお手上げ状態。
その場合は、あきらめてデフォルト色を使ったほうが無難です。
Powershell / slack / vivado > Generate Block Design終了時slack通知 (v0.2) > mem_init_files\ps7_init.tclチェックに変更 > 5回通知された

http://qiita.com/7of9/items/8ed747115ee472387674
ではsystem.hwdefファイル更新時にはGenerate Block Designはまだ終了してなかった。

代わりのファイルとして mem_init_files\ps7_init.tcl を対象にしてみた。

### code (v0.2)

```main.ps1
#
## 前提 > 以下のファイルがそろった環境で実行する
# 1. secret_slack_url.txt - slackのURL (git ignore対象ファイル)
# 2. target_dir.txt - Vivadoのhw/, SDK/ を含むフォルダ
# 3. このスクリプトファイル

<#
v0.2 2016 Jan 16
    - check [mem_init_files\ps7_init.tcl] instead of [system.hwdef]
    - add find_ps7InitTcl()
v0.1 2016 Jan 15
    - add notifyToSlack()
    - add get_lastWriteTime_hwdef()
    - add find_hwdef()
    - add get_target_dir()
    - add get_slack_url()
    - add main()
#>


function get_slack_url() 
{
    $slkurl = ( Get-Content .\\secret_slack_url.txt )
    return $slkurl
}

function get_target_dir()
{
    $trgDir = ( Get-Content .\\target_dir.txt )
    return $trgDir
}

function find_hwdef($targetDir)
{
    $hwdf = ( Get-ChildItem $targetDir -Recurse "system.hwdef" )
    return $hwdf.Fullname
}

function find_ps7InitTcl($targetDir)
{
    $tcllst = ( Get-ChildItem $targetDir -Recurse "ps7_init.tcl" )
    foreach($tclfile in $tcllst) {
#        echo $tclfile.Fullname
        if ( ($tclfile.Fullname).IndexOf("mem_init_files") -gt 0) {
#            echo "found"
            return $tclfile.Fullname
        }
    }
    return ""
}

function get_lastDateTime($afile)
{
    if ( $afile.Length -eq 0 ) {
        return (Get-Date)
    }
    return (Get-ChildItem $afile).LastWriteTime
}

function notifyToSlack($msgToSlk, $slkurl) {
  $enc = [System.Text.Encoding]::GetEncoding('ISO-8859-1')
  $utf8Bytes = [System.Text.Encoding]::UTF8.GetBytes($msgToSlk)

  $notificationPayload = @{ 
    channel = "#zybo";
    username = "7of9";
    text = $enc.GetString($utf8Bytes);
  }

  Invoke-RestMethod -Uri $slkurl -Method Post -Body (ConvertTo-Json $notificationPayload)
}

function main() 
{
    $slackUrl = get_slack_url
    $targetDir = get_target_dir

<#
    if ( $TRUE ) { # for debug
        $targetDir = "dummy"
    } 
#>

<#
    $hwdef = find_hwdef($targetDir)
    echo $hwdef
#>    

    $ps7initTcl = find_ps7InitTcl $targetDir
    $pretime = get_lastDateTime($ps7initTcl)
    echo $pretime

    $msg = "Start"
    notifyToSlack $msg $slackUrl

    while ( 1 ) { 
        $curtime = (Get-ChildItem $ps7initTcl).LastWriteTime
        echo $curtime
        if ( $curtime -gt $pretime) {
            echo "Generate Block Design"
            notifyToSlack "Generated Block Design" $slackUrl
            $pretime = $curtime            
        }

        sleep 5
    }

}

main
```

### 結果

Generate Block Designが5回通知された。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/3b850f58-7179-2bb1-eb1b-2041d45a7119.png)

同じフォルダのMakefileにしても5回通知された。

5回の通知の時差は1分程度。これがBlock Designを変更した時にどれくらい開いていくか。

### 検討

5回の更新については zybo_bsd.ip_user_files\sim_scripts\systemフォルダにある以下の５つのフォルダと関係あるのだろうか?

- ies
- modelsim
- questa
- vcs
- xsim

常に5回更新が決まっているのであれば、5回目だけ通知するとしてもいいかもしれない。
あるいは、5回の通知に(1/5)のような表記を入れる。

エクスプローラで更新日時の変更を見ていると、やはり5つのフォルダが順番に更新され、それに合わせて通知されている。

一番最後に処理されたのは vcs フォルダだった。
powershell / vivado > mem_init_files以下のps7_init.tclを探す実装 > foreach() / IndexOf()

```txt:動作確認
Windows 8.1 pro (64bit)
```

Vivadoにてps7_init.tclは色々なフォルダに作成される。
そのうち、mem_init_files以下のものを探すスクリプトを実装してみた。

```testFindPS7initTcl.ps1
#
## 前提 > 以下のファイルがそろった環境で実行する
# 1. target_dir.txt - Vivadoのhw/, SDK/ を含むフォルダ
# 2. このスクリプトファイル

<#
2016 Jan 16
   test code for find ps7_init.tcl under mem_init_files\
#>

function get_target_dir()
{
    $trgDir = ( Get-Content .\\target_dir.txt )
    return $trgDir
}

function findPs7InitTcl($targetDir)
{
    $tcllst = ( Get-ChildItem $targetDir -Recurse "ps7_init.tcl" )
    foreach($tclfile in $tcllst) {
#        echo $tclfile.Fullname
        if ( ($tclfile.Fullname).IndexOf("mem_init_files") -gt 0) {
            echo "found"
            return $tclfile.Fullname
        }
    }
    return ""
}

function main() 
{
    $targetDir = get_target_dir
#    echo $targetDir

    $ps7file = findPs7InitTcl $targetDir
    echo $ps7file
}

main
```

```target_dir.txt
C:\ZyboDev\zybo_160112_baseDesign
```

```txt:結果
found
C:\ZyboDev\zybo_160112_baseDesign\hw\zybo_bsd\zybo_bsd.ip_user_files\mem_init_files\ps7_init.tcl
```

覚えたpowershell

- foreach()
- IndexOf()

参考  http://powershell.wiki.fc2.com/wiki/%E6%96%87%E5%AD%97%E5%88%97%E3%81%AE%E6%93%8D%E4%BD%9C
シェルスクリプトで文字列を分割し末尾を取得したい

シェルスクリプトで「/home/hoge/fuga」や「/home/hoge/fuga/foo」のような文字列を「/」で分割した時の末尾の文字列（fugaとfoo）を取得してみたときのメモ

# trコマンドを使う

以下で出来ました。
trコマンドで「/」を「 」に変換し、一旦配列に入れ、その後末尾を取得しました。

```bash
path="/home/hoge/fuga"

array=( `echo $path | tr -s '/' ' '`)
last_index=`expr ${#array[@]} - 1`

# print fuga
echo ${array[${last_index}]}
```

以下のように関数にしてみました。

```bash
function get_last_dir() {
  path=$1

  array=( `echo $path | tr -s '/' ' '`)
  last_index=`expr ${#array[@]} - 1`
  echo ${array[${last_index}]}
  return 0
}

# main
path="/home/hoge/fuga"
last_dir=`get_last_dir $path`
echo $last_dir
```

# IFSを使ってみる

IFS(Internal Field Separator )をデフォルトの「$' ¥t¥n'」から「/」に変更して配列に格納し、その後末尾を取得します。
ちなみに`dir=($path)`という部分を`dir=(echo $path)`としていると動かなかった。。（なんでか分かってないですが。。。）

```bash
function get_last_dir() {
  path=$1

  IFS_BACKUP=$IFS
  IFS='/'
  array=($path)
  IFS=$IFS_BACKUP
  last_index=`expr ${#array[@]} - 1`
  echo ${dir[${last_index}]}
  return 0
}

# main
path="/home/hoge/fuga"
last_dir=`get_last_dir $path`
echo $last_dir
```
技術英語 > Now, please [describe the specifics] of this study. > Particular vs. Specific

@ LOE > October 5, 2012
http://loe.org/shows/shows.html?programID=12-P13-00040
>  Now, please <font color=red>describe the specifics</font> of this study. 

http://dictionary.reference.com/browse/specifics

http://www.dailywritingtips.com/particular-vs-specific/
> Particular vs. Specific
...
> Generally speaking, I’d choose specific when the content seems to call for precision.
みんなでAmazonCloudDrive！約月600円で1TB ※アプリで躓いている方へ

# Dropbox OneDriveなんてやめちゃえ！
というのは言いすぎですが、```Amazon Cloud Drive```の```Amazon.com```版は
~~保存容量無制限で年$59.99です。※2016年7月28日現在~~
~~```110円/$```換算で月550円弱ですね。安いです。~~
*※追記： co.jpもUnlimited版出ました。年間13,800円（1,150円）です高い。*
<font color="Red">※米国時間2017年6月8日無制限プランが終了し、同額では1TBまでになりました。ご注意ください。</font>

最初は飛びついて契約したものの、スマホでアプリをインストールしたら
```Amazon.co.jp```アカウントでのサインインしかできなくて
```Amazon.com```の契約とひもづけなかったので断念していました。

日本じゃないんだよ。日本じゃ・・・

# が、しかし

AndroidならびにiPhoneで```.com```に繋げる方法がわかったので共有します！
> ※追記: Cloud Drive Photosもいけたよ！
※追記の追記: Photosは日本でもAmazonPrime会員なら無制限になりました。**Photosだけならね！**

## Android

言語設定をEnglishにしてください。

おわり。

## iPhone

```:設定
書式
└地域 - アメリカ合衆国
```

にしてください。
おわり。

詳細に言えば「設定>一般>言語と地域>書式-地域」を「アメリカ合衆国」へ変更。

※2016-07-28追記
以下、@eru_tndl さんが確認してくださいました。
## macOS

デスクトップアプリをインストール後、ターミナルから下記のコマンドを実行。

```shell-session:amazon.com
$ defaults write com.amazon.clouddrive.mac AppleLocale 'en_US'
```

元に戻す（amazon.co.jp）につなげるようにする場合には、

```shell-session:amazon.co.jp
$ defaults write com.amazon.clouddrive.mac AppleLocale 'ja_JP'
```

## Windows

- コントロールパネル -> 時計、言語、および地域 -> 地域 -> 日付、時刻、または数値の形式の編集
- 形式タブの `形式(F)` を `英語 (米国)`に変更


#補足

Q. え？言語設定じゃないの？ｗ
A. はい。言語は日本語のままで大丈夫です。

プロキシ通してアメリカからリクエストしても意味無くて試行錯誤。
結果がこれだよ。
Network.Mail.Client.Gmail でのメール送信方法

[Network.Mail.Mime でのメール送信方法](http://qiita.com/satosystems/items/43ad35db2a289c15c998) では、sendmail が必要でしたが、Network.Mail.Client.Gmail を使用すればこちらも簡単にメール送信が行えます。

```Gmail.hs
{-# LANGUAGE OverloadedStrings #-}

import Network.Mail.Client.Gmail
import Network.Mail.Mime

main :: IO ()
main = sendGmail
    "foo@gmail.com"                           -- username
    "password"                                -- password
    (Address Nothing "from@example.com")      -- from
    [Address Nothing "to@example.com"]        -- to
    []                                        -- cc
    []                                        -- bcc
    "Subject"                                 -- subject
    "body1\nbody2\nbody3\n"                   -- body
    []                                        -- attachments
    30000000                                  -- timeout (in microseconds)
```

これだけです。私は Google アカウントは二段階認証で保護していますが、このコードを実行するにあたり特に二段階認証は要求されませんでした。

このコードのポイントは最後のタイムアウトで、これが短すぎるとメール送信が成功しません。上記サンプルでは 30 秒に指定していますが、私の環境では 3〜4 秒で送信が完了してプログラムが自動的に終了します。
java学習


## 基本構文
*基本データ型*
整数型(int)、浮動小数点型(double)、文字型(char)、論理型(boolean)

*参照型*
配列型、クラス型(String)、インターフェイス型

## ライブラリの利用について
* java言語のメソッドには、 **クラスメソッド**と **インスタンスメソッド**の2種類がある。
* ライブラリクラスは *import* 文を書いてパッケージ名とクラス名を宣言しなくてはならない。
* java.lang パッケージはjavaの最も重要なクラスが入っているので例外的にimport文は書かなくても良い。

## カプセル化
クラスに渡すフィールドについて、不正な値を外部から渡されることがないように制御する機能の一つ。
具体的には、クラスに定義しているフィールドを”private”の修飾子を付与することで外部から当フィールドを使用不可（不可視）とすることである。

*教科書引用*
*データと機能をひとまとめにし、メンバを保護する機能をカプセル化という。*

## methodのオーバーロード/多様性（ポリモーフィズム）
同一クラスの中に同じ名前のmethodを定義することが出来る。ただし、各methodの引数について以下の条件がある。
**引数の型** & **個数** がそれぞれ異なること！

### 多様性（ポリモーフィズム）
**似たような複数の処理をオーバロードしておけば、１つのメソッド名をおぼえて使うだけで、自動的にその型・個数に応じた処理が行われる。**ということになります。
その状況に応じて別々の働きをもつことを多様性（ポリモーフィズム）といいます。

## コンストラクタ
要は、クラスをインスタンス化（オブジェクトの具現化）した際に処理されるイベントプシージャみたいなもの。
**コンストラクタもオーバロードすることができる**
通常のオーバロードと同じく引数の型と数を変える必要がある。また、使用する方法はクラスをインスタンス化するときのステートメントにて、呼び出したいコンストラクタに適した引数を指定すればよい。
*this(); の記述を使えば別のコンスタクタを呼び出すことが出来る。*
*ただし必ずコンスタラクタ内かつ、そのコンスタラクタの先頭に記述する必要がある。*