木曜日, 11月 25, 2010

IBM developerWorks Japan 最優秀www大賞受賞感想

IBM Web Award 2010:「最優秀www大賞」を受賞だそうです。

この記事を紹介するツイートがあったので、
真面目な賞なんだろうけど何故か小馬鹿にしている感じがする。本文はまだ読んでない “@dW_Japan: 編集長ブログ更新:『IBM Web Award 2010:「最優秀www大賞」を受賞』 http://bit.ly/giJJ5W

http://twitter.com/#!/kameturu/status/7671097809969152

こんな茶々を入れたら、
本文をお読みになって是非ご感想をお寄せください(dW Japan編集長より) @kameturu: 真面目な賞なんだろうけど何故か小馬鹿にしている感じがする。本文はまだ読んでない

http://twitter.com/#!/dW_Japan/status/7673367763091456

こんな返答が。
すみません。どっちが小馬鹿にしているんだって話ですよね。

というわけで読みましたので、その感想。
まずはおめでとうございます。

さて、他のノミネートサイトが分からないので、他のサイトとの比較は出来ないのですが、外から見た場合この賞をdwが取ったというのは順当なように思います。むしろ他に思いつくサイト、ページが無い。
僕のWeb生活上、他のIBMのページは検索にひっかかったついでに見る程度だけど、dwについてはfeedを購読しているし、後で読もうと思ってブックマークだけしているページは数知れず。
たしかdwを定期的に更新されるサイトとして認知したのは、Pythonを覚え始めた頃で、David Mertzさんの記事をむさぼる様に読んでいた記憶があります。

編集長さんの今回の記事に『優秀な翻訳ベンダーとの協業により Contents Quality を高く維持できていること。』とあるのだけど、確かに古い記事は自動翻訳のような不自然な訳が目立っていたけど、段々と普通の訳になっていったように思います。しかも、何年か前までは、翻訳されるスピードが遅くて「これなら英語版を直接読んだ方が速いなあ」と思っていたけど、一年ぐらい(?)前から、物凄い速さで訳されるようになって、英語版を後で読もうと思っていたら、次の週には日本語訳が出来ていたりなんてザラにあったり。
本当に優秀でありがたいです。

一方で『ソーシャル化』ってのはちょっとピンと来なかったり。サインイン出来ることは知っているけど、その利点が今一つかめなかったり。とはいえ、これはネガティブな点ではなくソーシャル機能なんてなくても「読むサイト」としてのクオリティが高いという証左なのだと思います。

感想からどんどん離れていってしまいますが、dw「Japan」に対する要望としては、「Japan」独自の記事をもっと読みたいなあと、いつも思っています。具体例が思い浮かばないのですが、日本発の情報というものもきっといろいろあるんじゃないかと。英語サイトも平行して読んでいると、あの記事の翻訳だなという事がほとんどで、驚きがあまりなかったり。テクニカルナイトの報告記事だけでもあると楽しいのにと思います。

なんのかんの言っても、毎週金曜の更新を楽しみにしている人は、多いはず。
dw編集長、担当の皆さん、今後も楽しい記事を楽しみにしています。



おまけ

毎週チェックしているわけじゃないけど、僕がIBMのサイトで他に良く見ているところ
Design @ IBM

土曜日, 11月 20, 2010

gofmtをvimで簡単に使うためのスクリプト

Go言語は、推奨コーディングスタイルがあります。
とはいえ、実際に書くときにはあまり細かく気にする必要はなく、gofmtというGo言語をインストールするとついてくるフォーマッタを通してやれば、推奨スタイル通りに整形してくれます。
これを随時実行したいので、vimスクリプトを書いてみました。
都合上、フォーマットをかける前に、ファイルを保存します。

function! Gofmt()
:w
python << EOF
import vim
import subprocess

cb = vim.current.buffer
cursor = vim.current.window.cursor
p=subprocess.Popen(
['gofmt', cb.name],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
close_fds=True)
returncode=p.poll()
if not returncode:
err = p.stderr.read()
if err != None and err == '':
del cb[:]
cb.append(p.stdout.readlines(), 0)
else:
print(err)
vim.current.window.cursor = cursor
EOF
endfunction

月曜日, 11月 15, 2010

子供が生まれた

11月15日の七五三の日の朝に誕生。
病院の方針なのか、夫が立ち会う事は前提になっていたので、生まれた直後の子供を見ることが出来た。

病院に行ったのは、金曜日の朝なので、だいたい72時間で生まれたことに。
10分間隔で痛くなったら来いとの指示だったそうだけど、今思えば早すぎた感はあり。
初めてのことなので、痛いのレベルが分からなかったというのが大きいけど、とりあえず「痛い、痛い」言っているレベルではまだ先は長いです。
最終的には基本的に痛くてしゃべれないし、言えたとしても絞り出すようにしかしゃべれない。
(中の人を含めて)個人差も大きいだろうから、一概には言えないのだろうけど。
外から見る限りでは、分娩前の陣痛の方が分娩中より痛そうでした。もしかしたら分娩中は痛みどころでは無いのかな。

立ち会うとはいえ、何か出来るわけでもなく、汗を拭いて、うちわで扇ぐだけ。基本的に夫は何も出来ないわけです。
それでも、Twitterでリアルタイムで実況出来るほど余裕があるわけでもなく、途中途中の空き時間に友人、知人に向けて短くツイートする程度。他にも実家にメールとかもしてたしね。
分娩中にTwitterで実況したい人は、妻、助産師、看護師、医師、(もしかしたら子供も)からの白い目に耐えるだけの精神力を鍛えてください。

それにしても、赤ちゃんは文句無しにかわいい。
病院内で他の赤ちゃんを見かける機会は時々あって、かわいいなとは思っていたけど、自分の子はそれとは別の感覚としてかわいいと感じる。
客観的に見れば、生まれたての赤ちゃんは基本的にほわほわしていて、大人以上に個人差がないはずなのに。

今日は出てくるのに疲れたのか、あまり泣いたりしなかったけど(鼻から羊水を吸い出すためにチューブを突っ込まれると流石に泣いてた)、明日からは元気に泣くんだろうな。

水曜日, 11月 10, 2010

gocode入れてみた

VimでGoがautocomplete出来るgocodeがいい感じ」を見て、gocodeを入れてみた。

ビルドやインストールについては、gocodeのサイトに書いてあって、特に引っかかるところはない。
ただ、その説明だけでは、gvimでは動作しなかったので、gvimrcに以下の行を追加した。

let $GOBIN="$HOME/bin/go/"
let $GOROOT="$HOME/src/go/"
let $PATH="$PATH:$HOME/bin/go"

火曜日, 11月 09, 2010

Gordonさまがマウスカーソルにくっつく

多少書き直してみた。ついでに分身の術ではなく、マウスカーソルにくっつくように動くようにした。
コールバックな部分は若干やっつけだけど、基本的にはこんな感じだと思う。
event.goは綺麗というかすっきりして、ここまで来たらファイルを分離する意味が無い。
その分、main.goのhandleMouseEventがやたら汚い。
interface{}を具体的な型に落とす方法はswitchしかないのかな。

(一度投降後、何度かコードを綺麗にしてます)

main.go

package main

import (
"fmt"
"exp/draw"
"exp/draw/x11"
"image"

"./event"
"./gordon"
)

func handleMouseEvent(event interface{}, args ...interface{}) {
switch e := event.(type) {
case draw.MouseEvent:
{
me := draw.MouseEvent(e)
switch win := args[0].(type) {
case draw.Window:
{
win = draw.Window(win)
switch char := args[1].(type) {
case gordon.Character:
{
char = gordon.Character(char)
fmt.Printf(
"MouseEvent: Button= %d, Loc= %v\n",
me.Buttons, me.Loc)

draw.Draw(win.Screen(), char.Canon(), char.Mask(), image.ZP)
char.Position(me.Loc.X, me.Loc.Y)
draw.Draw(win.Screen(), char.Canon(), char, image.ZP)
win.FlushImage()
}
}
}
}
}
}
}

func main() {
gordon1, e := gordon.NewGordon(image.Point{X: 0, Y: 0})
if e != nil {
fmt.Printf("Error %v\n", e)
return
}

win, e := x11.NewWindow()
if e != nil {
fmt.Printf("Error %v\n", e)
return
}

eventChan := win.EventChan()
mouseCallBack := event.CallBack(handleMouseEvent)
sync := make(<-chan bool)
go event.HandleCallBack(eventChan, mouseCallBack, win, gordon1)
<-sync
}

event.go

package event

type CallBack func(event interface{}, args ...interface{})

func HandleCallBack(eventChan <-chan interface{}, fun CallBack, args ...interface{}) {
for {
event := <-eventChan
go fun(event, args...)
}
}

gordon.go

package gordon

import (
"bufio"
"image"
"image/png"
"os"
)
os.DevNull

type Character interface {
image.Image
Canon() image.Rectangle
Mask() image.Image
Position(x, y int)
}

type Gordon struct {
image.Image
Rect image.Rectangle
maskImage image.Image
}

func (g *Gordon) Position(x, y int) {
r := g.Bounds()
g.Rect = image.Rect(
x, y,
x+r.Max.X, y+r.Max.Y)
}

func (g *Gordon) Canon() image.Rectangle {
return g.Rect.Canon()
}

func (g *Gordon) Mask() image.Image {
return g.maskImage
}

func NewGordon(point image.Point) (gordon *Gordon, e os.Error) {
gordon = new(Gordon)
img, e := loadGordon()
if e != nil {
return nil, e
}
gordon.Image = img
gordon.Position(point.X, point.Y)
gordon.maskImage = image.NewGray(img.Bounds().Max.X, img.Bounds().Max.Y)
return gordon, e
}

func loadGordon() (image.Image, os.Error) {
file, e := os.Open("./Gordon.png", os.O_RDONLY, 0666)
if e != nil {
return nil, e
}

read := bufio.NewReader(file)
icon, e := png.Decode(read)
if e != nil {
return nil, e
}
return icon, nil
}

月曜日, 11月 08, 2010

Gordonさまと遊んでみて

とりあえず、自分で見ても滅茶苦茶なソースだと思う。
Interfaceなんて使ってみたかっただけで、無理やり過ぎる。
そもそも書いてある場所がどう考えてもおかしい。
コールバック的なものは関数型を渡してやればいいんだろうけど、何故かうまくいかなかった。
基本的な文法で間違っている可能性大。

そんな適当ながらも、書いてみてのGoの感想。

1. interfaceにFieldを宣言出来ないのは若干不便
Javaで言えばpublicなFieldの値を取りたいだけなのに、関数が必要になるのは不便。
要するにsetter/getterもインターフェースに書く必要があるわけで。
とはいえinterfaceてのはそういうものなのかも

2. ifの括弧が無いのは楽
慣れると他の言語で括弧を書くのを忘れる。

3. 型の後置は慣れると気にならない。
たまに間違うけど

4. 出来上がるバイナリがでかい
パソコンで動かしていると大して気にならないけど。もっと貧弱な環境だと大変かも。

CにもPythonにも似ていないけど、慣れれば便利な予感。

日曜日, 11月 07, 2010

GoでGordonさまと遊ぶ

Go言語のマスコットのGordonさまは、みんなから気持ち悪いと言われていますが、じっと見ていると、かわいいところが無く無くない気がしてきました。

なので、ちょっとコードが整理されていませんが、GoでGordonさまをいっぱい並べられるものを作ってみました。
コールバックな関数はどう書けばいいんだろう。

main.go

package main

import (
"fmt"
"exp/draw/x11"
"image"

"./event"
"./gordon"
)


func main() {
gordon1, e := gordon.NewGordon(image.Point{X: 0, Y: 0})
if e != nil {
fmt.Printf("Error %v\n", e)
return
}

win, e := x11.NewWindow()
if e != nil {
fmt.Printf("Error %v\n", e)
return
}

eventChan := win.EventChan()
sync := make(<-chan bool)
go event.Handle(eventChan, win, gordon1)
<-sync

}


gordon.go

package gordon

import (
"bufio"
"image"
"image/png"
"os"
)

type Gordon struct {
image.Image
Rect image.Rectangle
}

func (g *Gordon) Position(x, y int) {
r := g.Bounds()
g.Rect = image.Rect(
x, y,
x+r.Max.X, y+r.Max.Y)
}

func (g *Gordon) Canon() image.Rectangle {
return g.Rect.Canon()
}

func NewGordon(point image.Point) (gordon *Gordon, e os.Error) {
gordon = new(Gordon)
img, e := loadGordon()
if e != nil {
return nil, e
}
gordon.Image = img
gordon.Position(point.X, point.Y)
return gordon, e
}

func loadGordon() (image.Image, os.Error) {
file, e := os.Open("./Gordon.png", os.O_RDONLY, 0666)
if e != nil {
return nil, e
}

read := bufio.NewReader(file)
icon, e := png.Decode(read)
if e != nil {
return nil, e
}
return icon, nil
}


event.go

package event

import (
"exp/draw"
"fmt"
"image"
)

type Character interface {
image.Image
Canon() image.Rectangle
Position(x, y int)
}

func Handle(eventChan <-chan interface{}, win draw.Window, char Character) {
for {
event := <-eventChan
switch e := event.(type) {
case draw.MouseEvent:
{
me := MouseEvent(e)
go me.handleMouseEvent(win.Screen(), char)
}
case draw.KeyEvent:
{
ke := KeyEvent(e)
go ke.handleKeyEvent(win.Screen(), char)
}
}
win.FlushImage()
}
}


type MouseEvent draw.MouseEvent
type KeyEvent draw.KeyEvent

func (me *MouseEvent) handleMouseEvent(screen draw.Image, char Character) {
fmt.Printf("MouseEvent: Button= %d, Loc= %v : %v\n", me.Buttons, me.Loc, char)
char.Position(me.Loc.X, me.Loc.Y)
draw.Draw(screen, char.Canon(), char, image.ZP)
}

func (ke *KeyEvent) handleKeyEvent(screen draw.Image, char Character) {
fmt.Printf("KeyEvent: Key= %d\n", ke.Key)
}


実行結果