変数名に全角スペースは使えるのかという話

意外といろんな言語で日本語(というかUnicode全般)を変数名とかに使えるけど、全角スペースとか使えちゃうの?クールじゃね?配列の添え字に使ったらやばくね? という話をしていて、気になってぐぐったが見当たらなかったので試した。 $ perl 日本語.pl Unrecognized character \x{3000}; marked by チッつかえねえーな $ go run utf8.go # command-line-arguments .\utf8.go:7: invalid identifier character U+3000 .\utf8.go:9: invalid identifier character U+3000 どっちも普通の変数名は使えるのに、スペースは使えないとのこと。いや安全でいいんだけど。 どういうことかと思って調べてみる。 The Go Programming Language Specification In The Unicode Standard 6.3, Section 4.5 “General Category” defines a set of character categories. Go treats those characters in category Lu, Ll, Lt, Lm, or Lo as Unicode letters, and those in category Nd as Unicode digits. Goの場合はUnicodeのGeneral categoryというプロパティに従って文字として使えるかが決まっており、Lu, Ll, Lt, Lm, LoならUnicode characterとして使えると。へぇ。たぶんPerlも同じようなことになってるんだろう。 Unicodeの規格書? http://www.unicode.org/versions/Unicode7.0.0/ の4.5 General Category を読むと意味がわかる。文字ごとにgeneral categoryというのがあって、それぞれの文字の使い道が示してあるとのこと。 そこで全角スペース(U+3000)を調べると、 http://unicode.org/cldr/utility/character.jsp?a=3000 と出てきて、Space Separator (Zs)であることがわかる。SeparatorなのでGoでは(そしておそらくだいたいの言語でも)変数名に使えないようになっているんですね。へぇ。ちなみに、Separatorとされているからといって言語上の区切り文字として使えるというわけでもないらしい。不憫である。 ちなみにすべてのUnicodeのプロパティ一覧は扱いやすい感じのテキストで提供されている。便利そうだけど可能なら死ぬまで使いたくないですね?

Read more

頭の体操(を、頭を使わずにどうにかする)

おおにしさんが何やら面白そうなことをしていたので、perlでやってみた(他に方法を知らない)。 #!/usr/bin/perl -w use strict; for (1111 .. 9999){ my @can = split(//); next if ($can[0] > $can[1] || $can[2] > $can[3]); if (2 * $can[0] * $can[1] – $can[2] * $can[3] == 7){ print (“$can[0], $can[1], $can[2], $can[3]\n”); } } 組み合わせのチェックをする方法がよくわからなかったので、2カ所だけチェックしてるアレな感じ。rubyのsetみたいなのってperlでどうやるんですかね。 どうでもいいけどこのブログ、「よくわかんないけど」って書きすぎですね。

Read more

プロセスを監視する

GAのためにクライアントを何万回も走らせてるんだけど、数百回に1回、なぜかクライアントが死なない(暴走する)。原因もよくわからないし、再現を待ってるほど暇じゃないので、スマート(嫌味)に解決することにした。すなわち、n秒以上動いている特定のプロセスを殺すスクリプトをcronで回す。なんて美しい手法。orz use Proc::ProcessTable; $t = new Proc::ProcessTable; my $i = 0; foreach $p ( @{$t->table} ){ if ($p->cmndline =~ ‘program_name’){ if (time() – $p->start > 10){ system(‘pkill -9 program_name’); print “killed “, $p->cmndline, “\n”; } } } これで、10秒(6行目)以上動いてるprogram_nameというプロセスがあれば殺せる。これを1分ごとに回せば、たまに暴走してるプロセスがあっても無駄なく進められるだろう。GA回してるプログラム側からは、結果のファイルopenの例外を拾ってスコアを0にしてしまえば良い。さしずめ突然死というところか。結果にどの程度影響があるのかは知らん。 あと、数階層下まで一気にディレクトリを作りたいときは、mkdirじゃなくてmkpathを使うといいらしい。 use File::Path; if (!-d $dir){ mkpath($dir); } これで$dirが無いときは作れる。

Read more

twitter bot @genryo_bot のはなし

Syntax highlighterいれてみた。ので、コードを少し貼ってみる。 とりあえずこないだTwitterでフォロー返しに不具合があって、良く出力を見ていたらフォロワーが100人ぴったりだった。慌ててAPIとかNet::Twitterのドキュメントを見ると、1回に100ずつしか得られないとのこと。pagingかcursorを利用するかして何度かアクセスしろ(これってAPIアクセス数は増えるのかな?)とのことだったので、next_cursorに0が帰ってくるまで何度もアクセスして、followers()で得られたuserを1つの配列に突っ込むようにしといた。 my @followers; my $cursor = -1; while ($cursor) { my $f = $nt->followers({cursor => $cursor}) or die “error while getting followers $!\n”; $cursor = $f->{next_cursor}; foreach my $u (@{$f->{users}}) { push @followers, $u; } } これでたぶん数百フォロワーいても大丈夫。twitter先生のことなので、2回目だけアクセス失敗とか平気であるからちゃんとチェックしておきましょう。僕はこれ忘れて100人目より後のフォロワー全部を一度リムーブしましたorz あとはまってたのは、in_reply_to_status_idに渡すID。ステータスのIDを渡すものだと知らず、ひたすらユーザーIDを渡して、reply toが表示されないなぁおかしいなぁって思ってたorz で、このBOTはフォロー返しして、TLにある太りそうな発言にうっとうしいReplyを返すのが仕事。発言を全部MeCabに突っ込んで要素に分割して、あらかじめ指定した順番で太りそうな名詞と(助詞と)動詞の組み合わせが出てきてるかどうか見てるだけ。超単純なんだけど、MeCabのおかげで動詞を原形で指定できるから、けっこう幅広いパターンに引っかかっていい感じ。 文字列が太りそうか判断するパッケージ”Fat”を作ったんだけど、中身が上に書いたことくらいしかなくて100行くらいしかないしだいぶアレなのでソースは貼らないw

Read more

Net::TwitterでIncorrect signatureが止まらない(つづき)

どうせ忘れるだろうからメモ。 Net::OAuthだかNet::Twitterだかのバグで表題のエラーが出ていた件は、十分に新しいバージョン(3.14**以降?)では直っているはずだ。にもかかわらずこれが出るというのは、単にutf-8として適切ではないデータが渡されているだけのことらしい。orz BasicのときはいけたのにOAuthになったら通らなくなるのは不可解だが、TwitterのAPIなんて不可解なことだらけなので考えても仕方がない。まあもうBasic認証使えないしね。もしかしてあれか?OAuthになったついでに化けないようにutf-8のチェックをちゃんとしてくれてるとか? 結論から言うと、 use encoding(“utf-8”); を消したら直った。ふしぎだ。orz 御大の言うように、ソースは全てuse utf8;してutf-8で書く。encodingはもう使わない。 で、読み込んできた文字列は全部Encode::decode_utf8で処理する。(http://blog.livedoor.jp/dankogai/archives/51290188.html) そうすればソース中の文字列も外から入ってきた文字列も全部中身が正しいutf-8で(←これ大事)、かつutf-8フラグも立つ(←これも大事)ので化けない(少なくともNet::Twitterさんに怒られることはない)。もう文字コードでは悩まなくて済むはずだ・・・

Read more

ソケット通信をあーだこーだしてrcssserver3dにkick offさせる

GAを使ってrobocup 3D agentの動作を生成したい。評価のために、勝手にサーバを起動してクライアントを接続してエージェント走らせて評価値を書き出して死ぬクライアントを作る必要が生じている(もう長いことこの要求は放置されている)。 で、クライアント(C++)でとりあえずパラメータをテキストから読み込むようにして、GA部分はPerlのAI::Geneticに丸投げする。あとは、Perlからサーバを上げてクライアントを走らせて評価値をとってくるだけ(言うのは簡単だ)。 で、rcssserver3dにkick offの命令を出さないといけないのだが、rcssmonitor3dから出す以外に方法がよくわからなかった。サーバ側にコマンドからキックオフする機能は特に見あたらない(例によって調べるのがめんどい)のだが、いちいちモニタまで上げてたのではただでさえ遅いGAが耐え難い遅さになってしまう。 というわけで、rcssmonitor3dにキックオフ命令を出させた時に流れてるパケットをキャプチャして、同じように送ってやれば良いのではないかと思ったのでやってみた。 ソケットで送ってることはまぁわかっているので、tcpdumpでloをdumpする。この辺のがわからんってtwitterに言ってみたら何人かが教えてくれた。持つべきものはすごい友人達ですね。ありがとう。 tcpdump -i lo -w hoge -vvv -s0 とすると、loを通るパケットがhogeに吐き出される。いけてる。 これをwiresharkで開くといい感じにパケットの中身が見られるので、kickoffとかで検索をかけて、クライアント→サーバのパケットから目的のものを探す。 00 00 00 0e 28 6b  69 63 6b 4f 66 66 20 4c   ….(k ickOff L 65 66 74 29                                        eft) 目的のパケットのdata部はこんな感じだった。とりあえず (kickOff Left)という文字列を送ればいいものかと思い、適当にぐぐりつつPerlでport 3200に送りつけてみた。が、うまく動かない。 やはりdata部をそのままコピーするしかないと悟り、16進数で送るようにしてみた。 use IO::Socket::INET; my $c = IO::Socket::INET->new( PeerAddr => “localhost”, PeerPort => 3200, Proto    => “tcp” ) or die $!; my $msg = pack(“H*”, “0000000e286b69636b4f6666204c65667429”); $c->print($msg); $c->getline; $c->close; serverを立ち上げて、このスクリプトを走らせるとkickoffされるではないか。なんかひたすら蛇足でしかない気がするが、思うように動いたのでとてもうれしい。 0000  00 00 00 00 00 00 00 00  00 00 00 00 08 00 45 00   …….. ……E. 0010  00 46 7e 18 40 00 40 06  be 97 7f 00 00 01 7f 00   .F~.@.@. ……..

Read more

Net::TwitterでIncorrect signatureが止まらない

Net::Twitterを使って日本語をつぶやきたいが、OAuthを使うと日本語がつぶやけないという話。 普通にBASIC認証でIDとパスワードを渡すと英語・日本語(UTF-8)どっちでもツイートできるのに、OAuthを使うと日本語の時だけIncorrect signatureなどと意味不明な供述をしやがる。ちなみにPerlは5.10.1。 こうして、あとは $nt->update(‘hoge’); でつぶやける。但し英語のみ。 ぐぐってみると、同じ問題がNet::Twitter 3.13003+Net::OAuthで発生するという話がたくさん引っかかるのだが、どれもこれらを最新版にアップデートしたら直ったと書いてある。とっくに3.13006まで上げてるが、まったく直る気配がない。どうしてこうなった。現在は3.13007になっているが、変わらなかった。 英語ならツイートできるわけで、OAuth自体に問題があるとはどうしても思えない。ので、きっとどっかで何かがUTF-8あたりと喧嘩か何かしてるか何かなんだろうなぁ。なんもわからん。ソースを読みにいくという選択肢が無いへっぽこ学生。 一番安直な解決法としては、既にgem twitterをインストールし、OAuthでのあれやこれやの方法を確認できているRubyに移植することなんだが、今ひとつ踏み切れないところ。大したBOTでもないから1日あれば全部移植できるとは思うんだけど、んー。 てことで劇的なNet::TwitterのアップデートがtwitterのBasic認証廃止までにくることを夢見て、今日も寝て待つ俺なのであった。 →つづき:http://blog.naotaco.com/archives/101

Read more