D-7 <altijd in beweging>

Day to day life of a Perl/Go/C/C++/whatever hacker. May include anything from tech, food, and family.

カテゴリ:技術/Tech

「あ〜、インタプリタ言語飽きた。コンパイルしてぇ」と思っていたところ見つけたGo。あれから4年ほど経ちます。

gophercolor


当初 「mattn さんという超絶変態ハッカーが使ってるなぁ」くらいの印象でした。そして触り始めてからも「なんだこれ、オブジェクトじゃないの…?」「interface {}って… え、あとから自動的に紐尽くの…?」「なにこれ、ポインタレシーバーとby valueレシーバーで意味違うの…?」などなど色々と自ら真っ先に罠にかかり、穴にはまりまくって「この言語大丈夫か」と皆さんもそう思っていたかもしれませんし、僕もそう思っていたことがありました。

その後、自分が罠にはまるごとにあちこちで発表したりもし、pecoという思いがけないヒットを書いてしまったり、とにかく大量のGoコードを書き続けていくうちに…

Go言語は僕にとって既に無くてはならない存在になってしまいました。だって、コード書きやすいし、速いし、良いことづくめなんだもの。

そんなところで「本書くんだけど参加しない?」というお声がかかったのでめいっぱい手を上げて1章書かせてもらいました。それがこのほど予約開始になりました。(書影がまだないのが残念…)


Perlを10何年書いてからのGoで、なるほど、これは… という点は何個かあったのでどれをネタにしようか迷ったのですが、今回僕は"reflect"という黒魔術を採り上げさせてもらいました。

reflect芸人


やはりPerlと来たら黒魔術でしょう。Goでは基本必要のないツールですが、必要になったらこれ以外方法がない、というreflect。いくつかのライブラリを書く際にはまりまくったその結果を共有させてもらったので、是非皆さんには僕のテツを踏まないでいただきたいと思います。

P.S. 今回以下のようなものも描かせてもらいました。どこで使われるかな?



 
    このエントリーをはてなブックマークに追加 mixiチェック

大分迷ってしまったのでメモ。
 
type Foo interface { ... }
type Bar struct {...} // implements Foo
type Quux struct {
    A int
    B string
    C Foo
}

これをjson.Unmarshalでデコードしようと思うとするとQuux.Cをデコードするところで「どうやってGo Valueにするのかわからん!」ってGoに文句言われた。ちなみにgo 1.5
続きを読む
    このエントリーをはてなブックマークに追加 mixiチェック

kubernetesを使い始めている。かなり良いのだが、それまでの非kubernetesの世界で使っていたconsulとconsul-templateに依存する形で動的な設定変更をしていて、それが常々不満だった。もちろんロードバランスしちゃえばよいようなものはkubernetesのServiceにしてしまってそこにアクセスするようにしちゃえば手間いらずなんだけど、memcachedとかが意外にこのパターンにはまらんなーと思って困っていた。そこで ちょっと手の空いた時にTwitterで以下のようにつぶやいたところ


すぐに返事が返ってきた


お、それくさい!と思った物の、これどこにもドキュメントがないんだよね!そういうわけでとりあえず適当にクラスタを立ち上げてみて遊んでみようと思うのだが、あれこれどうやってGoogle Cloud Platform上で認証とかするんだ… 

ここから僕のyak shavingな旅が始まります。
 続きを読む
    このエントリーをはてなブックマークに追加 mixiチェック

ちょうど本業のほうでDBへのアクセスが遅い?んだかなんだかでREST APIがタイムアウトしている事象に出会っていたのでよっしゃとgo-sql-proxyを使おうと思ったのだけど、まずこのままだと実行時間とかが計測できない… ということに気づいて色々考えた結果PRを送る事にした。送ったら光速でマージされた。

今度から NewTraceProxyでプロキシを作れば Open/Exec/Queryに関しては所要時間が出力されるようになります。mysqlなら以下のような感じ:

driverName := "mysql"
if traceEnabled {
    driverName = "mysql-trace"
    sql.Register(driverName, proxy.NewTraceProxy(&mysql.MySQLDriver{}, logger))
}
db, err := sql.Open(driverName, dsn)
...

出力はこんな感じ:

tracer_test.go:27: Open (54.116µs)
tracer_test.go:27: Exec: CREATE TABLE t1 (id INTEGER PRIMARY KEY); args = [] (44.535µs)
tracer_test.go:41: Query: SELECT id FROM t1 WHERE id = ?; args = [1] (1.828µs)

わーい、これでボトルネック探すの捗るぞー!… と思っていたら、元々のNewTraceProxyのシグネチャが

func NewTraceProxy(d driver.Driver, o Outputter) *Proxy

で、これだと自前のloggerを受け付けてくれない!
type MyLogger struct { *log.Logger }
とかでも駄目だ!ということでインターフェースを定義してOutputメソッドを実装してればなんでもいいようにしておいたPRを送って取り込んでもらった。これで使えるようになった。YATTA!(けど、デプロイはこれからなのでまだなにか後で追加するかも…)

どちらのPRも光速でマージしてもらって大分たすかった。ありがとうございます。
    このエントリーをはてなブックマークに追加 mixiチェック

grpcをさらっと触ってみた。僕の個人的な結論から言うと、小規模なシステムにはいれるメリットあんまりないけど、複数チームでわりとバラバラに開発をしてるけど同じRPCを叩く必要があり、なおかつそれなりのトラフィックがあるなら有効そう。

他の言語の事は知らん。とりあえずGoでさわる。github.com/grpc/grpc-commonをチェックアウトして、サーバーとクライアントを起動する。ドキュメント読んでるとProtocol Buffersの話とかでてくるけど、動かしたいだけなら全部忘れてよし。

$ cd go/greeter_server
$ go run main.go
$ cd go/greeter_client
$ go run main.go

これだけだと一回RPCが走るだけでつまらないので、client側を変えて100 goroutineでぼちぼちたっぷりのコールをするようにする変更した部分はこんな感じ。ローカルホストにサーバーもクライアントもある状態なので正直正しい計測ではない事はまず言っておく。その前提で ざっくり10000 jobs/sec。HTTP2のオーバーヘッドを含めてだいたいそんなものなのでまぁ悪くないな、って感じ。

と、ツイートしたら"net/rpcと比べてどう?"って聞かれたのでほぼ同じプログラムをnet/rpcで作ったところ、約25K jobs/secいけた。 というわけで生スピードでは負けてしまったが、プロトコルの複雑さの差分と、goのhttp2がついこの間作られたばかりであまり最適化されていない、というのがほとんどの原因だと正直思ってる。

この辺りの厳密な値はちゃんとサーバー立てて検証すべきだし、他の言語でも試すべきなので本当に雑談程度の認識にしておいてください。

それより、やはり方法論としてProtocol Buffersでプロトコルを定義してそれを複数言語用に自動生成できるのが強みかなーと思ってる。JSON Schema的な。あっちの大陸とこっちの大陸で作業してるチームがサーバー・クライアントのコードのひな形を簡単に生成して作業を始められるのは強いのではないだろうか。このコード生成をgoから試すにはgithub.com/google/protobufを入れた上でgithub.com/golang/protobuf/protoc-gen-go を入れる必要があるので注意。

以上、さわってみたエントリでした。
    このエントリーをはてなブックマークに追加 mixiチェック

更新: h2oを0.9.1から1.0.0にしたらこのハック無しでもいけたくさいです!





HTTP2使いになりたい!と思いはじめて数ヶ月。でもなかなかうまいことここぞという使い道がなかったので、2週間ほど前にとりあえず仕事でkuradoを立てた時に前段にh2oを入れて様子を見ていた。kuradoならたくさんグラフ表示されるし、HTTP2の恩恵を受けられるはず…!と思って。HTTP1モードでは当然特になんにも問題はなかったのだが、いざChromeでenable-spdy4を有効にした時になーんか… 崩れる…

具体的にはCSS、画像の類いがこない事が多いが、たまにメインのHTML部分が返ってこない。Chromeの開発者ツールやnet-internalsを見ててもただERR::connectionResetみたいなエラーが返ってくるだけで全然意味がわからなかったので、しばらくそれはそれで忘れてた。

だが、ふとローカル環境で同じセットアップを試そうと思って色々とログを出したりして見ていたら、h2o側にアクセスが行っているタイミングと裏のkuradoのアクセスログが出てくるタイミングが全然合わない状況が認識できた。

はっ… persistent connectionとかkeepalive timeoutとかだ…!

と 細かい理屈が脳内でさっと組み立てられなくても経験値からひねり出せる天啓を得たのでごにょごにょデバッグ開始…

色々な組み合わせを調べてみた結果、とりあえずh2o側の設定で以下のようにすると、動く。YATTA! 

    paths:
      /:
        proxy.reverse.url: http://172.17.42.1:5434/
        proxy.timeout.keepalive: 0

そしたら、SUGEEEEEEEEE! kuradoやcloudforecastはご存じの通り1ページに大量のグラフが出てくるんだけど、それらの描画が爆速になった!これぞまさにライフチェンジング!まぁなんかどこかに問題があるとは思うんだけど、とりあえず期待通りの結果を得られた。

もし「本当はこうするべきだよ!」という方法をご存じの方がいたら是非教えてください!

おまけ:

その後ツイッターでこんなやりとりが。この続きはあるのか…?










追記




    このエントリーをはてなブックマークに追加 mixiチェック

ソーシャルコーディング時代の非技術者と技術者の関わり方についてちょっと考えをまとめたい。なお、これは「技術によって実現されるなにかをベースに商売をしている団体」という前提のもとで書く。たまたまインフラの一部にGitHubを使っているとかそういうのはここに含めない。また、大きめの企業・団体では数の利をいかしてなんとかこのあたりを解決できてしまったりするので、それもここでは含めない。



昔々、自分がメーカー系の会社に勤めていた頃バグトラッカーやレポジトリ(Perforceだった)などにエンジニア以外の人を入れるのは御法度だった。技術者側からの「わけのわからん注文をされる」「話がかみ合わない」など、納得の理由もある。なにより技術的な素養をもたない人達にとってはこれらのツールを使いこなすことが難しく、閲覧することさえなかなかかなわなかった。こちらもごもっとも。

が、21世紀に入って10年以上過ぎている今日、GitHub等のソーシャルコーディングを可能とするプラットフォームを使っている現場においては非技術者も積極的にコードやドキュメントの状態の閲覧、そして時には自ら介入して意見を言う必要があると思っている。そしてプライベートなプロジェクト等ではそのためにGitHubにアカウントを持つべきだと思う。特に小さいチームにおいては全員がプロジェクトに参加できるようにするべきではないだろうか。自分は100人も200人もいるチームなら別だが、10人、20人のチームであるなら自分達が関わっているプロダクトの開発がどのように行われているのかせめて見える・見るようにするためにGitHub等に積極的に参加するべきだと思っている。





自分がこれを必要と思う理由はいくつかある。

まずは分業文化を避けるためである。ある程度それぞれの部署で自力でどうにでもできる大きさの企業なら分業制は効果があるだろうが、小さいチームでは一蓮托生。全員での密なコミュニケーションを取り、なにが今必要なのかをちゃんと共有する必要がある。非技術者がコードやドキュメントの状況を見られない、というのは「自分はコードには責任を持たない」という気持ちを肯定する意味があると思う。それでは駄目だ。当然実装には関わらないが彼らにも当事者でいてもらわないといけない。営業や顧客対応をしている人達こそがプロダクトの本当の姿を知っているのではないだろうか。彼らこそがエンジニアのケツをひっぱたくべきなのではないだろうか。もちろん、全体の状況を鑑みて取捨選択をしたり、エンジニアを余計な労働から守る人も同時に必要にはなるが、それもまた密なコミュニケーションにより状況を相互理解しあう事が必要だと思ってる。

次にエンジニアの怠慢を避けるためである。これは前の点と根っこは一緒なのだが、自分も含めエンジニアというのはやりたくない機能の実装や修正はとにかく先延ばしにしたい、というのが本音だと思う。たまに意識の高い人もいるが、それは稀であると思う。基本人間怠けたいものだ。プログラムを書いている側というのは自分が書かなければ何も始まらないという圧倒的アドバンテージを持っているため、立ち回り方を間違えなければエンジニア以外の人から見たら信じられないほど怠けることができる。秘密にしてたんだけど、ここではしょうがないのでバラす。僕の元クライアント・元同僚の皆様、僕はあなたたちに気づかれないようにかなり怠けてきました、すみません。ところがソーシャルコーディングプラットフォームを使って可視化することによって、多少鼻の効く非技術者が混ざればこの辺りが圧倒的にやりにくくなる。非技術者が実装して欲しい機能を技術者側から「えー、それはやりたくない…」と言われても、開発の状況をなんとなく見つつもう一歩突っ込めそうなタイミングで突っ込んでみる、ということができるようになるわけだ。

そして最後に自分達の命運がかかっているプロダクトの本当の姿を知ってもらうためだ。営業、運用、みんな自分達のプロダクトがどういう状態なのか知っておくべきだ。問題がある部分やすごくうまくできてる部分。どれも知ってるべきだし、その状況に合わせておのおのの仕事の戦略を変えるべきだ。何もエンジニアはプロダクトをSGUPP(スーパー・グレート・ウルトラ・パーフェクト・プロダクト)レベルに常にしておく必要があるというわけではない。現実とのバランスを取りつつ「ここは手を抜く」「これは駄目駄目だけど、とりあえずの形で実装しておく」などの取捨選択をせざるを得ないだろうし、それが普通だ。でもその状況をチームは共有すべきだ。

PRs


もちろんこのような事を実現するためにわざわざGitHubのアカウントを取るのではなく、ミーティング等で共有する、というのはありだろう。だけど俺が共有のための報告を行う場合、相手が開発の状況を何も知らないのなら俺は絶対に話の内容を盛ります。面倒くさい追求を受けたくないから、実害のでない範囲で嘘もつきます。そしてなによりミーティングはみんなの時間と生産性を奪う。昔ならばこの辺りの情報共有をしたかったらレポートに色々まとめないといけなかったのだろうが、2015年である。GitHub等のツールが使える。パーフェクトなツールではなくとも、issueの報告もできればwikiも書ける。コードの統計情報も見えるし、テストが通っているかという状況も見えるし、実装についてのエンジニア同士の喧々囂々も読める。

要はこの手の情報共有をするためのコストが10年くらい前と比べると圧倒的に低くなっている。もはや少なくともGitHub等に参加することによってコードの状況を見る事がコスト増(=損)にはならない。見ない事はマイナスになりえる。

エンジニア達は非技術者達にもっと自分達のやってることを見せるべきだし、非技術者達は恐れずにもっとプロダクトの中身の光と闇に向かい合うべきだと思う。




おまけ。若干違う論点だけど、似たようなトピック:
    このエントリーをはてなブックマークに追加 mixiチェック

godepというツールをpecomigemogrepに便利に使わせてもらってたんだけど、このたびカスタムなgoスクリプト(goだとスクリプトじゃないと言われそうだけど、スクリプトとしか言い様が無い)を書いてgodepを卒業しました。

 なんでこうしたかというとgodepの-copy=falseというオプションが使えなくなり、基本的に依存関係のライブラリもこちらのレポジトリに入れないといけない形になったから。いや、入れても良いけどさ… う〜ん。毎日ビルドして出荷してるわけじゃないし、それなのにレポジトリをcloneした時に依存関係も全部落とすのはなああああ、ということで、もう全部自前で書きました。

別にシェルスクリプトでもよかったんだけど、goのプロジェクトだし…ってことで全部goで書いて、wercker.ymlからこんな感じで呼び出すようにした

それだけ。あとで「なんであんなことしてるの?」って聞かれた時用に書いておく。
    このエントリーをはてなブックマークに追加 mixiチェック

本当に手前味噌な話ですけど、STFさん。今回も「あー、俺いいソフトウェア書いた」と満足できたので、この記事を書きます。ちなみにSTFとはみんな大好きPerlで書かれた分散オブジェクトストレージです。(github)

tl;dr;

  • ああ、俺いいコード書いた
  • 8ヶ月間最初のスクリプトをキックする以外何もしてないけど、18億個のデータを無事格納しおえた
続きを読む
    このエントリーをはてなブックマークに追加 mixiチェック

先週 @k0kubunさんがpecoで複数キーの入力シーケンスに対してアクションを起こす(例:C-x, C-cで終了する、みたいなの)PRをしてくれたのでそれをマージした。pecoには楽しいお兄さんが色々コントリビュートしてくれているので、そのPRを見た瞬間にこんなコメントが

おお、いいですね、ということで実装してみようとしたところ… うっ… 設定ファイルから読み込んで動的に作る無名関数からレキシカルな変数へのスイッチングしてて、これをプログラム内部から他に作る方法がねぇ!w 設定ファイルからはできるのに!w むきー!

ということでその後、基本的な設計構造を変えないでその辺りを奇麗にできる方法は ないかと一日くらい費やした。が、やはりうまくいかない。薄々気づいていたけどこれFSMとかの出番だよな… 一から実装面倒くせぇなーと、つぶやいたらすぐ返信が:


うほ!goでahocorasickの実装があるwwww ありがとうございます!全部ぱくります!

コードを眺めているとトップレベルではstringに対しての実装で、 中身はruneに対してノードを返すみたいな事になってるので、これまぁ用はstring = []rune として考えられるので、キーシーケンス= []キー で代用できるね、って分かったのでガツガツ変更。といっても検索キーとか、ちょっと再起的に使うためにinterfaceを足した程度で、基本は何も変えていない。

そんなこんなで最初にpecoを書き始めてから一番大きいPRをマージして、キー入力周りがそれまでのコードと一変した。コードを提示してもらったおかげで任意の長さのキーシーケンスを特定のコマンドを高速かつ分かりやすい形で検索+ディスパッチできるようになった。

これも含めて先ほどpeco v0.2.0としてリリースした。このリリースはかなりの数の変更が入っているので、pecoヘビーユーザーには嬉しい機能が結構あると思う。是非お試し有れ!

本日の教訓:この一つ前の記事もパクリの話だったけど、こういう汎用的な方法論についての助言はどんどん受け入れるべきだし、コードもがんがん再利用してやればいいと思う。

プログラムを書く作業は孤独だけど、わからない事は「分からない!どこから始めるか教えて!」って聞けば誰でもヒントをくれるので人に頼る事を恐れないほうが良い(ただし、そこから先は自己責任でちゃんと勉強しましょうね)。そういえばgo-xslate書いた時もgfxに「これ、どこのサイト読むとxslateで使ってるVMのモデルの概要わかるの?」って聞いたな。

年を取れば取るほど経験値はたまっていくけど、それと同時に自分の知らない事が世界にはまだまだあるのがわかる。もちろんそれらを全部吸収できればベストなんだけど、脳にも限界があるので他人に聞く事によって自分の知らない事を素早く正しく補完できるのであればそれを活用できるようにつながりを作ったり、素直に質問できるようにしていくのが老いてゆくエンジニアの進む正しい道な気がする。おすすめです。
    このエントリーをはてなブックマークに追加 mixiチェック

pecoでは何個か前のリリースからバイナリビルドをリリースの成果物として登録するようにしている。これのおかげでpecoはそもそもの存在理由である「2014年だしこういうツールはバイナリ一個置いておくだけで動いてほしい!」というをより簡単に実現できている。


で、その実装方法。基本motemenさんのスクリプトにmattnさんがツッコミを入れたりしてるのを見ながら「よし!パクろう!」と思ってパクったんだけど、一つだけpecoでは意図的に変えたところがあって、それはboxの選定のところ。

motemenさんのgolang-goxc box自体に基本何も問題がないのだけど、pecoで色々やっているうちにgo1.3がリリースされたのにこのボックスを使っているといつまでもgo1.2.1だった(今はもう違うかもしれない)。まぁ当たり前ですよね。そこは他人の褌で相撲を取ろうとしている俺が文句言うところではない。

ただやっぱりバイナリのサイズが小さくなったり、多少パフォーマンス改善も見られている1.3系を使いたいと思いが募ったのと「これから先もきっとこういう事があるだろうし、そういうことがあるごとに文句を言わないといけないのか?」という思いがあり、pecoにはpeco専用のビルドボックスを作る事にした。それがこちら。もちろんgo1.3とgoxcを入れているところ以外はたいした事してない。

たいしたことはしてないんだけど、よくよく考えればライブラリとかではなくpecoのようにエンドユーザーに直接届くプログラムに関してはあまり自分が制御できていない環境に依存するのもどうかなーと思ったのでもうボックスから作る事にしてしまった。これなら自分がやりたいタイミングでgo1.4が出たらgo1.4にすることもできるし、goxcの特定のバージョンが欲しい、とかにも対応できる。

あとはmotemenさんの元記事と一緒。タグ打ってgit pushすれば勝手にファイルがあがってくる。おっさんは何もする必要がありません。大変すばらしい。また時間のある時にはhomebrewのレシピも自動的に作成しようとは思ってるけどそこまで至っていない。ともあれ、自動化はすばらしい。





ちなみに、drone.ioも一応登録はしてあって、こっちでもリリースとかできるかやってみたんだけど失敗して、ただただコンパイルして成果物を残しているだけ(基本前のやつは上書き)。あんまり必要じゃないけど、別の環境でコンパイルするとたまにバグが見つかったりもするので悪くはないと思ってる。まぁそのうち消すかも。
    このエントリーをはてなブックマークに追加 mixiチェック

tl;dr;
続きを読む
    このエントリーをはてなブックマークに追加 mixiチェック

これは笑ってしまった。The Open Source Report Cardという、githubのデータを持ってきて色々統計情報を見せてくれるサイトがあるんだけど、ここで今日とうとう「Exceptional Regexer」とか、そういうPerl Monger系の名称から「High Caliber Gopher」みたいな名称になって、さらによくみると「one of the 5% most active Go users」(6/18現在)だったのでツイートしたら、
GoプロジェクトにとてもゆかりのあるDave Cheneyさんからこんなツイートが…

よくみると彼は上位9%という位置だったw まぁGithubに対するコミット数とかだからそれ以外のところはカウントされないのでしょうがないw 彼がgithubにもっとコミットするようになったら一瞬で抜かされるだろうなー こういうのを"15 minutes of fame"とかいいますねw
    このエントリーをはてなブックマークに追加 mixiチェック

pecoそのものについてはここで読むよりREADMEを見た方が早いです

今月の初めくらいにpercolという便利なものがあるという話を聞き、「ほう、使おうかな」と思ったら普段あまり使い慣れていないpython製ツールでまるでcpanmを使うのがいやなPerlに慣れていない人のような反応で「まぁ必須アイテムじゃないし…」と思って諦めかけたところ


とか言われ「そこまでいいツールなのかなー」と思ったけど、使ったことないし、まずはツールがどういうものなのかをわかるためにGoで実装する事にした(はい、本当にこういう順番です)。
続きを読む
    このエントリーをはてなブックマークに追加 mixiチェック

(以下はgo 1.2.x時点での話です。将来的に仕様がかわるかどうかはわかりません)

これを読んでいて、こういうの気にしてない人多いんだろうなーと思って、書いてみます。元のポストはdeferの挙動について語っているように見受けられるけれども、これは要は複数スレッドで実行されるコードについて、プログラム終了時に同期とか取りたくない、という話だと思ったので、このポストのdeferを正しく動かすには…というところからどういう形でgoroutine同士で同期を取る方法があるのか、一例を書き出していきます。

TL;DR;

goでいくらgoroutineが気軽にかけるからと言って、複数スレッドで処理が行われているので同期はキチンとやらないとダメですよ。

続きを読む
    このエントリーをはてなブックマークに追加 mixiチェック

なんかごく一部に補足されているので、念のため軽く説明しておきます。


これ、ベストな方法だとは思っていないんだけど、最初にこれを書いた当時の考え方は以下の通り:

  1. これは自分の部署で初めて 本番に設置するgoアプリである
  2. 一次対応をする人は自分とは限らない
  3. 細かいコード内容の修正はともかく、明らかなバグっぽいものの修正(例:SQL文の変更)などを自分以外の人間が施した後にサーバーを簡単に再コンパイル+再起動するする方法がないと椅子が降ってくる事が容易に予想される
というところから、どうするのがベストか考えたのがきっかけ。以下、やった事の詳細。

続きを読む
    このエントリーをはてなブックマークに追加 mixiチェック

The Perl Foundation (TPF)の助成金プログラムの5月ラウンドの募集が始まりました。本文はこちらです

助成金の仕組みはPerlに関連する公共性の高いプロジェクトに対して金銭的サポートをするために作られました。採択されると平均的には数万円〜数十万円の助成金がプロジェクトのゴール完了とともに交付されます。本当に有益で実現性の高い物であれば、100万円程度の助成金まで交付される可能性があります。

助成金利用者にとっては助成金そのものがうれしいだけではなく、コミュニティに支持されたプロジェクトを牽引・実装したという実績になりますので、その後役立つはずです。是非応募の検討をお願いいたします。

なお前回日本からひとつの応募が採択され、助成金が交付される運びになりました。今回も日本からなにか応募されると大変うれしいので、もしなにかPerl関連のプロジェクト(Perlコミュニティを支援するなにか - ドキュメントやサポートプロジェクト・サイトなど、Perl利用者みんなが助かるツール・モジュールなど)のアイデアや、今すでに作業途中のものがあれば是非応募してみてください。参考までに、前回採択されたプロポーザルがこちらです

英文に自信がない方でも 私に連絡をいただければ清書等のお手伝いはできますので@lestrratまで是非ご相談ください。

ひとつ残念な事は募集開始から締め切りまでが10日ほどしかないことです。今回の応募締め切りは5/10です。ただし、前回(3月)のラウンドから始まった試みのひとつとして1年間に募集回数を増やすというのがあるので、今回もし準備が間に合わないようでもすぐ次のラウンドが始まる予定ですので、是非ご相談ください。

皆様のご応募をお待ちしております
    このエントリーをはてなブックマークに追加 mixiチェック

tl;dr: 別にPerl捨ててないです。Perl大好き。俺はLLはPerlでいい。でも別ドメインの事もやってもいいよね!

Rebuild.fmに限らず、公の場でYAPC/Perl以外の話をする事があるとは正直思っていなかったが、このたびRebuild.fm ep 42に置いて1時間Goについてしゃべりまくってきた。1時間ぶっつけ本番でしゃべりたい事はだいたいしゃべってきたのだけど、その後のフィードバック等もふまえてまとめておきたいと思ったのでこのエントリでまとめてみます

続きを読む
    このエントリーをはてなブックマークに追加 mixiチェック

このところ情熱を燃やしていた go-xslate プロジェクトですが、大分使えるようになってきたしかなりの処理速度も出るようになったしgo-nutsで宣伝もしたし、小さいプロジェクトで使い始めたし・・・ってことで 手軽に遊べる用に Go PlaygroundをぱくってGo-Xslate Playgroundってのを書いた。

外部テンプレートを使うWRAPPERやINCLUDEは使えないけど、それ以外の機能は一通り使えるはず。是非遊んでみて、問題がありそうだったら "Share"ボタンを押してpermalinkを作成の上、permalinkをissueにはりつけて教えてください。よろしくお願いいたします。

ちなみに書いたそばから mattnさんにぱくられたけど、自分もぱくってるし、ぱくられたのは良い物を書いたからなのでつまり全体的に大変よい。なおGo-Xslate Playground自体のソースはこちらにあります。なにか問題等ありましたら教えてくださいませ。
    このエントリーをはてなブックマークに追加 mixiチェック

golangでNgram処理をするためにgo-ngramを書きました。ngramによる類似文字列検索に関してはコードを読みながら逆算してこういうことか、という書き方をしたのでちょっと実装に自信はないのですが、まぁだいたい動くな、というところまでは確認しました。問題がありそうでしたら是非ご連絡ください。

使い方は以下の通り。まずただngramでトークナイズするならngram.NewTokenize()を使います。以下はいわゆるTrigramを使った例:

import (
"fmt"
"github.com/lestrrat/go-ngram"
)
func main() {
tok := ngram.NewTokenize(3, "ハローハローハロー") for _, token := range tok.Tokens() {
fmt.Printf("token = %s\n", token)
}

ちゃんと日本語も対応してます。

ユニークなトークンだけがほしい場合はTokenSet()を使ってください。
import (
"fmt"
"github.com/lestrrat/go-ngram"
)

func main () {
tok := ngram.NewTokenize(3, "ハローハローハロー")
set := tok.TokenSet() // see http://github.com/dackarep/golang-set
for x := range set.Iter() {
fmt.Printf("token = %s\n", x)
}
}

一応簡単なインメモリインデックスも作りました

import (
"fmt"
"github.com/lestrrat/go-ngram"
)

func main() {
index := ngram.NewIndex(3)
index.AddString(`....`) // 検索対象の文字列を登録しておく
....
matches := index.FindSimilarStrings(`ハロー`) // AddString()された物の中から`ハロー`に似ている文字列を持ってくる
for _, str := range matches {
fmt.Printf("matched %s\n", str)
}
}

これで登録されている文字列の中から似た単語を抽出できます。 デフォルト設定だと一個でもngramがマッチするとあたってしまいますが、SetMinScore()で閾値を設定することによって検索結果を絞り込めます。

さらに、一番良いマッチだけを持ってくる場合にはFindBestMatch()を使ってください。

あと自分で検索結果をフィルターする場合はIterateSimilar()を見てください。

ツッコミ、コメントお待ちしております。
    このエントリーをはてなブックマークに追加 mixiチェック

このページのトップヘ