後悔というほどでもないけど、子供と雑談していて暦の説明をしたんですが、もっといい説明ができたかもしれないなと。 まず、暦というのは種をまく時期を決めたりするから非常に重要なものであったと。このへんは説明できた。 太陰暦というのは月の満ち欠けを数える暦で、だいたい1年に12回新月→満月(→新月)を繰り返すことから12ヶ月になった。だから太陰暦時代は毎月15日あたりが満月だった。なんで太陰暦になったかというと、月は形が変わるので太陽よりも観測しやすい。形を見ながら数えてればだいたい29〜30日くらいで1周するし、12回くらいで季節が元に戻るというのが昔の人にも分かったわけだ。このへんは説明できなかった。 しかし12回の月の満ち欠けでは1年とは誤差が大きすぎ、たまに1ヶ月追加したりしないと季節がズレていってしまい、不便が大きい。そこで太陽の角度とかを観測する技術が出て太陽暦になった。これだと太陰暦に比べてズレが少なく、だいたい4年に1回くらい2/29を追加することで1日以内のズレにできたわけだ。このへんは多少まともに説明できた。まあ時代によって観測精度が上がってきてうるう年の追加方法が変わったとかいうのは説明できなかったな。 単に「昔は太陰暦があったけど今は太陽暦なんでズレが少ないんだよね」という説明は上手くなくて、技術の推移で説明してけばもっと分かりやすかったな、と思ったんですね。実際に子供でも月の形の変化を知ってるわけだが、太陽の変化を知ることはできないでしょう? 大人でも多くの人は太陽の変化で暦を作るなんてできないだろう。月の形を見ながら日数を数えるくらいなら、子供でも日記をつければできるような気になれるんじゃないかと思う。 でも、なぜ昔は太陰暦だったかなんて、誰も教えてくれなかったな。Wikipediaにも書いてない。だから「太陽よりも月のほうが観測しやすかったから」が正解なのかは正直、自分にも分かってないのだが、そう考えるしかないよな、と思っている。まあ潮の満ち引きを知りたい云々…というのはあるんだろうけど、それって後付けだよね。 まあたぶん子供はしばらくしたら忘れてるんだろうけど。
久々に行ってきました昨日の等々力。その前には宮内の鎮守の森の春日神社の祭りがあって、神輿だの山車だの。山車は引いてお菓子をもらったりしてましたが、そんなこんなは置いといて。ハゲつるピッカーンな奴が子供3人連れて、ゴール裏でちょこまか動く子供をフォローしながら見てました。ナビスコ準決勝で、アウェイで1-3で負けて帰ってきたという状況。2-0で勝つか、3点差で勝てば上がり。 試合の出だしは快調で、後半途中までは行ける感じがしてました。サブに中村憲剛がいたから、1点取ればいいという状況になったら憲剛が全てを決してくれるだろうというね。でもあと2点。あと2点になってからが長かった。余計な失点が重くのしかかり、敗戦。憲剛の決まるところも相手DFの突き出された尻にブロックされて枠外へ。無失点で済むとは思えなかったから4点は最初から必要と見込まれてたよね。2失点したから5点が必要になった。 全体的には、もし森島が決めてれば、みんながハッピーだったろうと。もし決めてればね。仮定法過去完了? だっけ?? 2本ほど好機がありましたよね。 まあ小林悠(代表に呼ばれて不在)がいたら、5〜6本ばかり外すか、あるいは2本決めるかしてたろう。私としては久々の等々力で久々の勝利ということで気分は悪くないはず…だけど、目的を達成できなかった残念さが強かった。
一つ前の、droneでビルドできない問題は、.drone.ymlのscriptにcp -r ./ $GOPATH/src/github.com/wtnb75/xxxx/ みたいに書いておけばよいことを発明した! 手間かけさせやがって。
Go(golang)はかなりいろいろなことがよく考えられた良い言語だが、大きな欠陥がある。その欠陥はやはりimport。gitやmercurial等のリモートリポジトリを指定できてそれはそれで大層便利ではあるのだが、タグやブランチ、バージョン等を指定できない(常にmasterのHEADが使われる)ことがしばしば問題となる。 このimport問題の中でもとりわけ大きなものが、local importの問題だ。 リポジトリ上で開発していて、同じリポジトリのサブディレクトリを対象にimportしたいとする。
import "./subdir"
通常はこれで良いのだが、$GOPATH/src以下もgo getでcloneしてくるリポジトリになっていて、ここのソースに対して作業をしていると、相対パスによるimportがエラーになる。
can't load package: /path/to/go/src/github.com/wtnb75/xxxxx/yyyy.go:16:2: local import "./subdir" in non-local package
つまり、$GOPATHにのっとって開発する(実際golangではそれが推奨されている)場合は、こう書かなければならない。
コメント画面の「スパムをすべて削除」する操作が全く戻ってこない。しびれを切らしてリロードするとちょっとは消えてるけど大部分が残ったまま。 このサイトにはほとんどコメントは来ないのだが、普通の設定(akismetで自動判定されたspamが1ヶ月で自動消去)でも常時数千件のspamが溜まっている。それでたまに全件削除しようとボタンを押してみるが…スピードが遅すぎる。何をやっているのか? MySQLのDELETEが遅いのかも、と思って試しに以下のSQLを実行してみたら、瞬時に終わった。綺麗さっぱり。まあすぐに10件を越えてくるのだが。
DELETE FROM wp_comments WHERE comment_approved='spam'
WordPressは出しているSQL文がものすごく下品なものになっているに違いないな。どうせPHPで1件1件チマチマ消しているんだろう。自動削除というのもたぶんメチャクチャなSQLを発行していて無駄に重くなっていた可能性もあるな。
- Macでdockerを使うことができる
- boot2dockerを使う。VirtualBoxで上がるTinyCoreLinuxでdockerが動く
- droneはdockerを使えれば使えるはず
というわけで、Macでdroneを使ってみよう。dronedはLinuxでサーバを立ててgithub APIと連携させればいいとして、Macではcommit/push前のチェックとして、コマンドラインのdrone buildを使えるようにしたい、と私は考える。
- brew install boot2docker
- brew install docker
- boot2docker download
- boot2docker init
- boot2docker start
- eval $(boot2docker shellinit)
- もしどこかでパスワードを聞かれたら「tcuser」と答える
ここまででdockerを使える状態になる。
- brew install go
- export GOPATH=$HOME/go
- go get -d github.com/drone/drone/cmd/drone
- 現状だと少し変更が必要
- $GOPATH/src/github.com/drone/drone/pkg/build/docker/image.go
- github.com/dotcloud/docker/utils → github.com/dotcloud/docker/pkg/parsers
- utils → parsers
- $GOPATH/src/github.com/drone/drone/pkg/plugin/notify/irc.go
- func (i *IRC) Connect()の中身を削除
- $GOPATH/src/github.com/drone/drone/pkg/build/docker/image.go
- go build github.com/drone/drone/cmd/drone
- go install github.com/drone/drone/cmd/drone
- export PATH=$PATH:$GOPATH/bin
これでdroneを使える。試しにこんな.drone.ymlを置いて、、、
image: bradrydzewski/base
env:
- TZ=Asia/Tokyo
script:
- date
- drone build
まあ初回はイメージのpullに時間がかかりますが、2回目以降はなかなかいい感じになります。 ソースに修正が必要だったのはまあ困るよね。golangのimport文は読み込むモジュールのバージョンを指定できないから、常にmasterのHEADを使うことになる。そして使っているライブラリのバージョンが上がって互換性がなくなったときにコンパイルできなくなる。サードパーティでそれを解決するウェブサービスがあったような気もするが、広まってないし自分もそのサイトを忘れてしまった。 droneのソースはアレな面があって、作者のbradrydzewskiのイメージであればubuntuユーザで実行されるが、それ以外のイメージを使うとrootで実行される。この判定はハードコードされている。
SQLではカウンタのincrement/decrementは1つの文で済ますことになっている。
UPDATE table SET counter = counter + 1 WHERE ...
ActiveRecordのモデルにはincrementやdecrementの定義がある。そうか便利だなぁ…??
1.9.3-p545 :021 > Tbl.take.increment!(:counter, 2)
D, [2014-09-04T00:36:32.902849 #73566] DEBUG -- : Tbl Load (0.1ms) SELECT "tbls".* FROM "tbls" LIMIT 1
D, [2014-09-04T00:36:32.903201 #73566] DEBUG -- : (0.0ms) begin transaction
D, [2014-09-04T00:36:32.904809 #73566] DEBUG -- : SQL (0.4ms) UPDATE "tbls" SET "counter" = ?, "updated_at" = ? WHERE "tbls"."id" = 1 [["counter", 10], ["updated_at", 2014-09-03 15:36:32 UTC]]
D, [2014-09-04T00:36:32.914149 #73566] DEBUG -- : (9.1ms) commit transaction
=> true
SELECTで読んで、Rubyが足し算して、UPDATEで足した結果を書き出す…こんなのってないぞ。それをORマッパーがincrementと名乗るか普通? 正解は、モデルのクラスメソッドのupdate_countersを使う。これは複数のカウンタの操作が可能。第1引数のオブジェクトIDも複数書けるし、第2引数以降のカラム名も複数書ける。オブジェクトから呼べないのが使いにくいのを除けば、普通のSQLが発行される。まあ↓の例ではIDを求めるのにSELECTは発行されるが、UPDATE自体は普通にDB側で加算されてくれる。
join(1)の衝撃いまだ冷めやらぬ中…column(1), colrm(1)っていうコマンドもありますね。 まあこれらの使い方を覚えようとする前にawkを使うでしょうね。しかしもっと凄いのは、これらのコマンドを涼しい顔で使っている人が会社にいること…かな。なんであんたこれを当然のように使ってんだよ、っていうね。