2014/12/08


GoLangでJavaのenumっぽいライブラリ作った話 - おいぬま日報

なんとかなるわけなんだけど、これを毎回書くのは面倒なので...

もっと良いやり方があったらぜひ教えて欲しいところです。

http://oinume.hatenablog.com/entry/introducing-goenum

golang でユーザ型の値を文字列化する場合 Stringer というインタフェースを実装します。具体的には

func (l Lang) String() string {
    switch l {
    case Go:
        return "Go"
    case Python:
        return "Python"
    case Ruby:
        return "Ruby"
    }
    panic("Unknown value")
}

上記サイトで書かれている様に String() という関数を実装します。実は golang のオフィシャルから stringer という、その名の通りのツールが提供されています。

まず、Stringer を実装していないコードを書きます。

package main

import (
    "fmt"
)

type Fruit int

const (
    Apple Fruit = iota
    Orange
    Banana
)

func main() {
    var fruit Fruit = Apple
    fmt.Println(fruit)
}

このまま実行すると 0 と表示されます。ここで以下の様にして stringer というツールをインストールします。

$ go get golang.org/x/tools/cmd/stringer

そしてソースコードと同じディレクトリで以下の様に実行します。

$ stringer -type Fruit fruit.go

すると fruit_string.go というファイル名の以下のコードが生成されます。

// generated by stringer -type Fruit fruit.go; DO NOT EDIT

package main

import "fmt"

const _Fruit_name = "AppleOrangeBanana"

var _Fruit_index = [...]uint8{51117}

func (i Fruit) String() string {
    if i < 0 || i >= Fruit(len(_Fruit_index)) {
        return fmt.Sprintf("Fruit(%d)", i)
    }
    hi := _Fruit_index[i]
    lo := uint8(0)
    if i > 0 {
        lo = _Fruit_index[i-1]
    }
    return _Fruit_name[lo:hi]
}

あとはこのソースも含めてビルドし、再度実行してみると今度は Apple と表示される様になります。便利ですね。

尚、const で iota を使う場合ですが、上記の様に型を指定しておくと違う型の変数へ Apple を代入する際にエラーが出て便利です。

package main

import (
    "fmt"
)

type Fruit int
type Animal int

const (
    Apple Fruit = iota
    Orange
    Banana
)

const (
    Monkey Animal = iota
    Elephant
    Pig
)

func main() {
    var fruit Fruit = Apple
    fmt.Println(fruit)

    fruit = Elephant
    fmt.Println(fruit)
}
./fruit.go:26: cannot use Elephant (type Animal) as type Fruit in assignment
Posted at by



2014/12/02


通常、golang のデフォルトの HTTP クライアントは環境変数 HTTP_PROXY もしくは HTTPS_PROXY を参照してプロキシに接続し、環境変数 NO_PROXY で指定されたホストが無視される仕組みになっています。しかし一般ユーザにとって環境変数の設定は、難易度の高い作業だったりします。

使用例

たとえばこういうコードに…

package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
)

func main() {
    res, err := http.Get("http://www.google.com")
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
    defer res.Body.Close()
    io.Copy(os.Stdout, res.Body)
}

一行追加すると:

package main

import (
    "fmt"
    "io"
    "net/http"
    "os"

    _ "github.com/mattn/go-ieproxy/global" // ← この行
)

func main() {
    os.Setenv("HTTP_PROXY""")
    os.Setenv("HTTPS_PROXY""")
    res, err := http.Get("http://www.google.com")
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
    defer res.Body.Close()
    io.Copy(os.Stdout, res.Body)
}

たったこれだけで、IE のプロキシ設定が引き継がれます。無ければデフォルトと同じ様に、環境変数で動作します。

仕組み

ieproxy は ieproxy.ProxyFromIE という関数を提供していて、これが http.Transport.Proxy を実装しています。この関数は http クライアントのプロキシ仲介有無を行っているのでつまりは http.Client の Proxy を設定できます。http.Cilent が HTTP リクエストを実行する際にはこの Proxy が呼び出されて判定処理が行われますが、ieproxy.ProxyFromIE はレジストリから IE のプロキシ設定を取得しつつプロキシの判定を行うような実装になっているので、このように HTTP 通信に引っかけてプロキシをすげかえることができるわけです。

さらに github.com/mattn/go-ieproxy/global パッケージでは http.DefaultTransport.Proxy を ieproxy.ProxyFromIE に書き換え(!)しているので、インポートするだけですべての HTTP 通信が(標準の http パッケージを利用していれば)勝手に IE のプロキシ設定になります。

注意: Windows でしかビルド出来ません。

参考資料: ソースに一行追加するだけですべての HTTP 通信をロギングするモジュールを書いた #golang - 詩と創作・思索のひろば

mattn/go-ieproxy - GitHub
https://github.com/mattn/go-ieproxy
Posted at by



2014/11/18


今日、嫁から電話があり...


嫁「送り主の分からない小包が届いてる」

僕「どんなん?誰から?俺に?」

嫁「それが分からんねん。英語ばっかりや」

僕「なんて書いてる?」

嫁「フェーフェー、フェデークス...」

僕「それ、運送会社や」

嫁「英語ばっかりで分からんわ。開けていい?」

僕「いや、間違いかも知れんし」

嫁「宛名は合ってるねんで」

僕「なんやろ覚えが無い」

嫁「カードでなんか買い物したんちゃうん...」

僕「してないわー」

家で見ても、確かに送り主が分からない。おそるおそる開けて見ると















DSC01360

どどーん。なんか真っ黒いの出てきたと思ったら、ブランケット出てきた。しかも「Google」って書いてある。

DSC01362

かっ... かっちょ... かっちょええやん...

DSC01363

おーぷんそーす ぷろぐらむ おふぃす...

Google is sending out blankets to open-source developers | Hacker News

My perspective comes from the corporate world. On the one hand, it's nice to be acknowledged for wor...

https://news.ycombinator.com/item?id=5650075

これやーーーーー!

ありがとうございます!ありがとうございます!

大事にします!

ただ一つだけ...

出来れば送り主、書いて下さい!

Posted at by