panic: assignment to entry in nil map

原因

Go のプリミティブ型の一つ map は値型だと勘違いしていて、こんな runtime error と出会いました。

var m map[int]int // a map variable
m[0] = 1 // panic: assignment to entry in nil map

map は参照型でした。nil 値 (nil map) があります。実体は make か literal で作ります。

var a = make(map[int]int) // make an (initialized) map value
a[0] = 1
var b = map[int]int{} // a map literal value
b[0] = 1

注意点

Java 等の参照型主体の言語を使う人にはむしろ自然に見えるかもしれないが、次のような挙動は流石にきもいので気をつけて使ったほうが良さそう。

var m = *new(map[int]int)
println(m[0]) // 0
m[0] = 1 // panic: assignment to entry in nil map

new は non-nil な値を返しますが initialized value は作られず、nil map は empty map のように振る舞い、0で呼び出すと既定動作として初期値が返ります。そのあと代入して初めて落ちます。nil map は内部表現の実体が無く要素を追加することだけができず、挙動は似ていても nil map と empty map は区別されます。

var a = map[int]int(nil)
var b = map[int]int{}
println(a[0], a == nil) // 0 true
println(b[0], b == nil) // 0 false
// println(a == b) // invalid operation: a == b (map can only be compared to nil)
a[0] = 1
b[0] = 1 // panic: assignment to entry in nil map

なお、参照型なので普通に変数や引数にコピーを取ると実体は共有されます。

var a = map[int]int{}
a[0] = 1
var b = map[int]int(a)
b[0] = 2
println(a[0]) // 2

動作は仕様 Map types にさっくりと書いてあります。他には slice や channel も参照型で、それらも変数や new の初期値は nil で、当然 empty とも区別されます。

言い訳

なぜ勘違いしたかというと、多くの参照型を扱う言語と違って、Go にはポインタ型と強い型付けがあり C のように値とポインタを区別して扱うので、参照として扱いたい部分にはポインタを使うことで実現でき、特別な理由がない限り言語としては参照型は必要ないからです。ユーザ定義型 struct, interface だけでなく array も値型です (string, function は immutable)。

特別な理由とは例えば、slice は pointer と同じく本質的に他の値を参照する機能を持っているので参照型(逆に C 等のポインタと配列型がもつ配列を参照する機能は Go の pointer にはない)。channel は、通信は普通実体を共有し、実体の違うコピーが取れるのは直感に反するので、毎回ポインタを使うコストも掛かる uncopyable な型を作るよりは参照型の方が妥当。とかたぶんそんな感じです。

一方 map は、C++ ののように連想配列自体は値型で実現できます。Go にポインタ型がある以上それなりの理由がないと参照型ににはならないと思っていたので値型だと思い込んでいました。array が値型でも map は参照型の方が良いという人はいるんでしょうか。

macのTerminalでtmuxの罫線がズレる

症状:mac 標準の Terminal で tmux を使って切り分けたとき、水平の罫線が二行に渡る破線になり、また表示とカーソル位置が一部の画面でずれる。(バージョンとかは忘れた)

とりあえず設定から↓のチェックを外すと治りました。
□Unicode East Asian Ambiguous characters are wide

原因はおそらく Terminal が認識する全角文字セットの中に tmux が使う横罫線の半角文字が入ってなかったから。対して、この設定は東アジアのよく分からん文字をコードページの領域だけで判断(?)して全角文字扱いにしてしまうハックなので、tmux と Terminal の間で齟齬が生まれたっぽい。

emacs org-mode (beamer) -> latex -> pdf

No definition for class `beamer' in `org-export-latex-classes'

org-modeで書かれたファイルをpdf化しようとorg-export-as-latexするとこのエラーが出た。
2つのパッケージ org-mode latex-beamer を入れると幸せになった。

詳細は、emacsが変数org-export-latex-classesを参照してdocumentclassに応じたヘッダを挿入しようとするが、beamerは定義されていないということらしい。.emacsとかで定義してもいいが、org-modeを入れるとデフォルトでbeamerのテンプレも定義しておいてくれる。latex-beamerにはたぶんstyとか入ってるので、latex&dvipdfmxしてpdfできあがり。

org-export-as-pdfで一気にpdf化までしてくれた。やってる事はたぶん同じ。

log:virt-install

  • 大分昔にしたpythonのアップグレードができてなかった
  • Kernel Configuration弄るの忘れてた

gentooでvirt-installを実行しようとしたところ、

$ sudo virt-install --prompt
Traceback (most recent call last):
  File "/usr/bin/virt-install-2.7", line 33, in <module>
    import urlgrabber.progress as progress
ImportError: No module named urlgrabber.progress
$ qcheck urlgrabber
Checking dev-python/urlgrabber-3.9.1-r1 ...
  * 25 out of 25 files are good
$ qlist urlgrabber
/usr/bin/urlgrabber-2.6
/usr/bin/urlgrabber
/usr/lib/python2.6/site-packages/urlgrabber-3.9.1-py2.6.egg-info
/usr/lib/python2.6/site-packages/urlgrabber/mirror.py
/usr/lib/python2.6/site-packages/urlgrabber/progress.py
/usr/lib/python2.6/site-packages/urlgrabber/grabber.py
/usr/lib/python2.6/site-packages/urlgrabber/__init__.py
/usr/lib/python2.6/site-packages/urlgrabber/byterange.py
/usr/share/doc/urlgrabber-3.9.1/TODO
/usr/share/doc/urlgrabber-3.9.1/LICENSE
/usr/share/doc/urlgrabber-3.9.1/README
/usr/share/doc/urlgrabber-3.9.1/ChangeLog
/usr/share/doc/urlgrabber-3.9.1-r1/TODO.bz2
/usr/share/doc/urlgrabber-3.9.1-r1/README.bz2
/usr/share/doc/urlgrabber-3.9.1-r1/ChangeLog.bz2
$ head -n1 /usr/bin/virt-install-2.7
#!/usr/bin/python2.7 -tt
$ python -V
Python 2.7.2

モジュールが無いのかと思ったけど、python2.7を使ってるのに2.6にしか入ってないということらしい。
pythonのバージョン変えてからモジュールの更新とかしてなかったのかも(かなり昔だったような…)
名前的にそれらしいもの(python-updater)があったのでとりあえず実行してみる。

$ sudo emerge python-updater
...
$ sudo python-updater
... # 時間かかる
$ sudo virt-install --prompt
ERROR    Virtual network 'default' has not been started.
$ sudo virsh net-start default
エラー: ネットワーク default の起動に失敗しました
エラー: ブリッジ'virbr0' を作成できません: パッケージはインストールされていません
$ qcheck bridge-utils
Checking net-misc/bridge-utils-1.4 ...
  * 25 out of 25 files are good

python の問題は解決した。
続いて Kernel Configuration から Bridge を有効にして reboot したら動いたので終わり。

Symbol: BRIDGE
Type  : tristate
Prompt: 802.1d Ethernet Bridging
  Defined at net/bridge/Kconfig:5
  Depends on: NET [=y] && (IPV6 [=n] || IPV6 [=n]=n)
  Location:
    -> Networking support (NET [=y])
      -> Networking options
  Selects: LLC [=m] && STP [=m]

DebianにDropboxを入れる

検証環境:debian-squeeze(amd64), nautilus-dropbox_0.6.8_amd64.deb
予想対象:linux, nautilus-dropbox

公式dropboxクライアントのLinux版(GUIのみ)はUbuntu,Fedora,Archive版を配布してる。今使ってるDebianはGNOME仕様なのでUbuntu版をそのまま使えそうな気がする。ビルドするのも若干面倒なのでとりあえず試してみる。

$ sudo dpkg -i nautilus-dropbox_0.6.8_amd64.deb
...
dpkg: dependency problems prevent configuration of nautilus-dropbox:
 nautilus-dropbox depends on libnautilus-extension1 (>= 1:2.22.2); however:
  Version of libnautilus-extension1 on system is 2.30.1-2squeeze1.
...

libnautilus-extension1のバージョンが2.30.1-2squeeze1で1:2.22.2以上じゃないと言われるが、どう見ても2.30.1>=2.22.2で大丈夫そうに見える。頭の1:が悪さしてる気がするので消してみる。

# dropboxというディレクトリに展開して再アーカイブする
$ dpkg -x nautilus-dropbox_0.6.8_amd64.deb dropbox
$ dpkg -e nautilus-dropbox_0.6.8_amd64.deb dropbox/DEBIAN
$ nano dropbox/DEBIAN/control    # お好きなエディタで

# 次のように修正(libnautilus-extension1の"1:"を消す)
Depends: libatk1.0-0 (>= 1.20.0), libc6 (>= 2.4), libcairo2 (>= 1.6.0), libglib2.0-0 (>= 2.16.0), libgtk2.0-0 (>= 2.12.0), libnautilus-extension1 (>= 2.22.2), libpango1.0-0 (>= 1.20.1), python (>= 2.5), python-gtk2 (>= 2.12)

$ dpkg -b dropbox
# dropbox.debが作成される
$ sudo dpkg -i dropbox.deb

入った。

IE ESCを無効化可能にする

Windows Server 2008 R2, Internet Explorer 9

このPCは普段遣いしてるので、「Internet Explorerセキュリティ強化の構成(IE ESC)」を無効化(Usersで無効化可能に)している。普段IEを使わないから気にしてなかったけど、IE9に更新してからGUI上で無効化してもIEの設定項目が効かない問題が発生していた。そもそもActiveXを使うためにIEが必要になるケースが多いので、保護モードで動かすメリットはあまりない。

IE ESCの構成

保護モードの項目がグレーアウトしている

レジストリ弄ったらできそうだけど分かり易かったりしないかなと思って覗いてみると速攻で如何にもそれらしいものを見つけた。消してみると普通に解決した。

[HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap]
IEHarden=dward:00000001

コマンドでちょちょいと消す場合は↓を実行する。

reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap" /v IEHarden
保護モードの項目をアンチェック

MySQLのテーブルが壊れた

エラー: データベースに接続できません

WordPressのトップにたった一行でかでかと表示されてた。ブレーカーが落ちたせいだな。

WordPress側から復元とかできる仕組みがあるらしいけど、うまく動かなかった。エラーメッセージ的にMySQLの方の問題だろうと思って、コマンドラインで試してみるとデータベースには普通に繋がる。とりあえず片っぱしからアクセスしてみると、

mysql> select * from wp_options;
ERROR 145 (HY000): Table './wordpress/wp_options' is marked as crashed and should be repaired

初めて見たエラーだけどググったら速攻で出てきたので何とかなりそう。それにしてもエラーメッセージがおかしい。「テーブルを読み取れません」とまで分からなくても「データベースに問題があります」程度にしてくれないと原因究明し辛い。

mysql> check table wp_options;
+----------------------+-------+----------+-----------------------------------------------------------------------------------------+
| Table                | Op    | Msg_type | Msg_text                                                                                |
+----------------------+-------+----------+-----------------------------------------------------------------------------------------+
| wordpress.wp_options | check | error    | Table upgrade required. Please do "REPAIR TABLE `wp_options`" or dump/reload to fix it! |
+----------------------+-------+----------+-----------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> repair table wp_options;
+----------------------+--------+----------+------------------------------------------------------+
| Table                | Op     | Msg_type | Msg_text                                             |
+----------------------+--------+----------+------------------------------------------------------+
| wordpress.wp_options | repair | info     | Wrong bytesec:  58- 34- 34 at 296176; Skipped        |
| wordpress.wp_options | repair | info     | Found block that points outside data file at 7572    |
| wordpress.wp_options | repair | info     | Found block with too small length at 194732; Skipped |
| wordpress.wp_options | repair | info     | Found block that points outside data file at 194744  |
| wordpress.wp_options | repair | info     | Found block that points outside data file at 204696  |
| wordpress.wp_options | repair | info     | Found block that points outside data file at 207436  |
| wordpress.wp_options | repair | info     | Found block that points outside data file at 207532  |
| wordpress.wp_options | repair | info     | Found block that points outside data file at 217276  |
| wordpress.wp_options | repair | info     | Key 1 - Found wrong stored record at 244464          |
| wordpress.wp_options | repair | info     | Found block that points outside data file at 246936  |
| wordpress.wp_options | repair | info     | Found block that points outside data file at 297132  |
| wordpress.wp_options | repair | warning  | Number of rows changed from 161 to 150               |
| wordpress.wp_options | repair | status   | OK                                                   |
+----------------------+--------+----------+------------------------------------------------------+
13 rows in set (0.48 sec)

なんとかなった。

PowerCommands for Visual Studio 2010

PowerCommands_Preview

PowerCommands for Visual Studio 2010というプラグインの紹介。何気に便利です。ソリューションエクスプローラから右クリックでコンソールやエクスプローラ,パスのコピーが出来るようになります。他にも色々機能がありそうだけどまあそれだけで十分便利。VS2010でしか使えないのが不思議。

使用しているとなぜかエディタで文字列を選択(反転)したときにVS自体のフォーカスが高速にチカチカと明滅(?)する謎の問題が発生。ウィンドウを強調しているわけでなく本当にフォーカスが当たったり外れたりを高速に繰り返します。もちろんエディタにマトモに文字が打てなくなります。

結果的にForumの方に解決法が載っていましたが英語でしか書いてなくてうまく検索にヒットせずちょっと間面倒でした。オプションからExtract Constantのチェックを外すと治ります。

Visual Studio Options

emerge dos2unix unix2dos blocking

またかよ( ゚д゚)
別に普段使わんツールやから消しちゃってもいいんやけどなぁ・・・
因みにdos2unix,unix2dosはファイルの改行コードを変換するツールです。

$ emerge -pvuD world
...
[ebuild     U ] app-misc/realpath-1.15-r1 [1.15] USE="nls" 0 kB
[ebuild     U ] app-text/dos2unix-5.1 [3.1-r2] USE="nls%*" 66 kB
[blocks B     ] >=app-text/dos2unix-5 (">=app-text/dos2unix-5" is blocking app-text/unix2dos-2.2-r1)
[blocks B     ] app-text/unix2dos ("app-text/unix2dos" is blocking app-text/dos2unix-5.1)

Total: 2 packages (2 upgrades), Size of downloads: 66 kB
Conflict: 2 blocks (2 unsatisfied)
...
$ qlist dos2unix
/usr/bin/dos2unix
/usr/bin/mac2unix
/usr/share/man/man1/dos2unix.1.bz2
/usr/share/man/man1/mac2unix.1.bz2
$ qlist unix2dos
/usr/bin/unix2dos
/usr/share/man/man1/unix2dos.1.bz2
$ sudo emerge -C unix2dos
...
$ sudo emerge -avuD world
...y
$ qlist dos2unix|grep /usr/bin
/usr/bin/dos2unix
/usr/bin/unix2dos
/usr/bin/unix2mac
/usr/bin/mac2unix

まー多分dos2unixに統合されたとかそんなんでしょう。ってことでunix2dosを消して更新したら案の定。まあそうそう使う機会ないけどな。
楽だからsambaでやり取りしたファイルの都合合わせるとき一気に変換したりするのに欲しくなる。emacsとかviとかリッチな環境だと簡単に出来たりするけど、どうも一気にやろうとするとsedとかawkとかで意外と書きにくい。特に改行コード混ざってる時とかは意外と面倒だったりするw

鯖の状態を視覚化するツールmunin

グラフィカルな鯖缶ツールはあった方がいいなと思って探したらMuninってのが良さ気。正味使えりゃ何でも良かった。他に何があるかは知らない。

gentooでの記録なので違う方は適所読み替えればおk。emergeはyumとかaptみたいなもん。

$ sudo emerge munin
$ munin-check
  #各ファイルの権限とかをチェックしてくれる
$ sudo chown munin:munin /var/lib/munin/crontab
  #これだけで済んだ
$ /usr/sbin/munin-node-configure --shell --families auto,manual,contrib
  #使えるプラグイン一覧
$ sudoedit /etc/munin/munin-node.conf
#変更箇所
< user root
< group root
---
> user munin
> group munin
$ sudo crontab -u munin /var/lib/munin/crontab
$ sudo rc-config start munin-node
$ sudo rc-config add munin-node default
$ sudo htpasswd -c /etc/munin/munin-htpasswd sulume
  #デフォルトでBasic認証掛かる、不要なら.htaccess弄る

mysqlには皆rootばっかり使ってるけど、それは変だろう、ってことで、mysqlに監視用ユーザ作った。MySQLリファレンスのGRANTより権限はsuperだけでよさげ。

mysql> create user 'munin'@'localhost' identified by 'password';
mysql> grant super on *.* to 'munin'@'localhost';
#/etc/munin/plugin-conf.d/munin-node
[mysql*]
env.mysqlopts -u munin -ppassword

デフォのhtml生成先が/var/www/localhost/htdocs/munin/だったので適当に表示される様に調整。これで表示され・・・グラフ画像に文字が表示されない( ゚д゚)□だらけwwwそういえばフォントが必要なのか。読めればいいので適当にフォントを選んだ。念のため日本語対応のX用じゃない奴にした。

$ qsearch media-fonts
  #フォントっぽいパッケージ一覧、qsearchが無かったらemerge -s fontとかでも
$ sudo emerge fs-fonts

画像の更新を待ったらちゃんと文字が表示された。温度とファン回転数が見れたので、ついでにfancontrolの値を調整しといた。画像はこんな感じ。

munin image