コミケ告知

サークル活動の詳細は circle タグの記事へ。
2013年4月20日土曜日

F#談話室 (4) に参加してきた

前回咳が止まらなくて病欠してしまったF#談話会、今回は無事参加できました。


自分の作業 (VS2012 for Web単体でF#ライブラリ プロジェクトを動かす)

15時頃着いて、まず馬券を買ったのちに作業開始…しようと思ったら、なんとVisual Studio 2012のWindows DesktopをノートPCに入れていなかったことが判明。C#からF#のライブラリを呼ぶものを今日は作ろうと思っていたのに、これは誤算です。
ただ、ライブラリ部分をC#から呼ぶだけならば、C#単体テストプロジェクトがfor Webでも作れるので、これでいけそうです。ビルド依存性の設定で、C#単体テストプロジェクトがF#ライブラリ プロジェクトに依存するように設定。

F#ライブラリ プロジェクトにはScript.fsxが入っているので、これが実行できればプロジェクト単体でいくつかテストも出来ると思うのですが、いまいち使用法がわかりません。普通に実行しようとすると、出力がライブラリなので実行できませんという、ライブラリプロジェクトに対してはごく普通のエラーメッセージが出るのみです。

F# Interactive を立ち上げて #load してみましたが、カレントディレクトリがWindowsのTempディレクトリになっているようで、使い勝手がイマイチですね。

作りたいものも決めていったのですが、実装作業の進みはいまいちでした。APIを調べながらの作業はノートPCで行うには不向き、かつどちらかというと設計段階でメモ帳に手書きみたいなフェイズであり、これ家でやった方がいいなあ…という感じでした。ノートPCで作業しても問題ないフェイズにしておくことを、次回以降は考えておきます。


LT

ヘヴィなトークが2時間くらいありました。16時→18時がLTだったので、結局参加時間のほとんどLT聴講に…!F#という言語をどう使うか?どういう利点があるか?というのは自分の謎でも、世間の謎でもあります。ヘビーユーザーの使いかた、というのは参考になりますね。
コンピュテーション式を使えるくらいになると、楽しくなるのかなあ。
2013年4月15日月曜日

Cygwin+SBTでEnterキーが効かない場合の対処

現象

Cygwin上でsbtを起動は出来るが、Enterキーが効かないので何もできない。


原因

ターミナルの設定とSBT側の処理が合っていないのが原因。sbt-launch.jarを実行するときに、-Djline.terminal=jline.UnixTerminal を引数に渡せばよい。

Windows用のsbt…すなわち、msiでセットアップされるsbtや、アーカイブ中のwin-sbtには、$TERMがxtermのときだけ前述のオプションを渡すという中途半端な処理が書いてあるのだが、少しでも違うとそちらの分岐に行かない。(たとえばminttyのxterm-256color)


対処

  • sbt.batをいじって、必ず引数が渡るようにする
    •  if [ "_$TERM" = "_xterm" ]; の判定文をいじるとか
    • "$JAVA_CMD"のあとに直接書いちゃうとか (cmd.exeから呼んだときに大丈夫かどうか知らないが)
  • あるいは、環境変数 $JAVA_OPTS に指定する

2013年3月31日日曜日

Fluentdの出力をWebSocketに流すoutput pluginを書いた

Fluentdの出力をWebSocketに流すだけのoutput pluginを書いてみました。Rubyが全然わからないので、使い方をぐぐりながら。
普通はモニタリングしたければログなり標準出力なりに出せばいいので、広く一般に使えるものではないでしょう。リモートで動いているFluentdが吐くデータを、ちょっと手元のブラウザに出してみたかったんじゃよ。

いわゆる自分用プラグインです。インストールは「pluginディレクトリに置いてくれ」「em-websocketに依存してるからあれ入れてね」というバルクな仕様。他に使う人がいれば、Gemにした方が良いのかもしれません。

はじめてのRuby雑感

何かの勉強会でサンプルがRubyだったため、1回書いたことがあるような気がしますが、何も覚えていませんでした。変数の種類とかifの書き方とかを検索するレベル。
Rubyでは、変数に関数を直接代入は出来ないという理解であってますかね?検索したら proc というのが出てきたので、とりあえずそれを使ってみました。変数に直接関数入れられる言語と比べると、めんどくせーなーという印象です。

はじめてのWebSocket (クライアント側) 雑感

WebSocketってきっと面倒で、専用のライブラリがあってそれを使うのかな…と想像していましたが、生のWebScoketオブジェクトを使ってちょろっと送受信するだけなら簡単でした。
websocket.orgにechoのサンプルがあるので見ると、WebSocketのオブジェクトをnewして、あとはハンドラ(onXXX)に必要なものをセットするだけです。サンプルをここに書きおこす必要は感じられない程度に、シンプル。
最初はサーバーを自前で立てなくても、サンプルで使っているws://echo.websocket.orgで試せるのも有難いです。サーバーの動作を疑わなくてもよい点で。

はじめてのWebSocket (サーバー側) 雑感

FluentdのプラグインはRubyである必要があるため、em-websocketを使いました。作者が作者だけにrev-websocketで…とまず思ったけど、3年間更新されてませんね。動きませんでした。
exampleの中にあるmulticastのサンプルを見ながら動かしたら、意外とあっさり複数接続も出来ているようです。

FluentdはMessagePackフォーマットで出すのも簡単なため、受信側にmsgpack.jsを組み込んで、バイナリ送信にも対応しました。その際、いつものsendメソッドで送ろうとしたら接続が切れてしまうので何かと思ったら、どうやらsend_binaryという別のメソッドがあったようです。pull requestの履歴の中にありました。READMEの範囲では、そんなのわからなかったよ…
2013年3月19日火曜日

g++ -std=c++11で色々と"not declared"が発生する場合

状況

  • g++でコンパイル
  • -stdの指定をしなければ万事うまくいく
  • -std=c++11を指定すると、not declaredになる関数がたくさん出る
    • snprintf, strdup, fileno等 
例:
hoge.cpp:20:21: error: ‘strdup’ was not declared in this scope

解決方法

-std=c++11ではなく、-std=gnu++11を使用する。

参考にしたのは、2年ほど前のstackoverflowの記事でした。
acceptされた解答にあるように、厳密に標準のC++の関数ではなくてGNU拡張であるため、こういうことが起きるようです。

使用したg++はCygwin上の4.7.2でした。
2013年3月12日火曜日

BOOST_FOREACHは参照で受けないとコピーされる

C++でループを回てコレクションを巡回するときに時折役に立つ、BOOST_FOREACH。(boost/foreach.hpp)
便利なんですが、巡回先のコレクションから受け側の変数に代入されるだけなので、参照で受けないとコピーされます。

以下のような、テスト用にコンストラクタ・デストラクタでprintfするだけの適当なクラスがあるとして。
class Hoge {
  public:
    Hoge() { printf("ctor %p\n", this); }
    Hoge(const Hoge& h) { printf("copy %p\n", this); }
    ~Hoge() { printf("dtor %p\n", this); }
};
気を使わずに単に変数で受けて巡回すると…
vector<hoge> hoge_vector(3);
BOOST_FOREACH(Hoge x, hoge_vector) { ; }
ctor 0x20010210
ctor 0x20010211
ctor 0x20010212
copy 0x28ac26
dtor 0x28ac26
copy 0x28ac26
dtor 0x28ac26
copy 0x28ac26
dtor 0x28ac26
dtor 0x20010210
dtor 0x20010211
dtor 0x20010212
ですよねー。参照(&x)で受けないと、スタック上にコピーして破棄してを繰り返しています。関数の引数でオブジェクトを値渡し、みたいな話でちょっと恥ずかしい。 boost.org公式のドキュメントにも、"Iterate over a sequence by reference, and modify the underlying sequence" という例が書いてあります。

参考:公式ドキュメント

参照で受ければ、もちろんコピーされずに済みます。
BOOST_FOREACH(Hoge &x, hoge_vector) { ; }
ctor 0x20010210
ctor 0x20010210
ctor 0x20010211
ctor 0x20010212
dtor 0x20010210
dtor 0x20010211
dtor 0x20010212
こんなくだらない話ですが、autoを使おうとするときって、型に対する意識が散漫になりませんか?
BOOST_FOREACH(auto x, hoge_vector) { ; }  // コピーされるよ
BOOST_FOREACH(auto &x, hoge_vector) { ; }
このループで変更を加えようとしている場合には、一時的に複製されたものを触っても何もおきなくて気づきます。しかし、読むだけの場合にはロジック上の不都合は起きないので、うっかりこのようなコードを埋め込んでしまうかも。
# boost 1.48.0にて確認
2013年3月9日土曜日

Chrome「プロフィールを開くことができませんでした」の解消

症状

起動時に「プロフィールを開くことができませんでした」というポップアップが毎回出る。

解決方法

C:\Users\ログインユーザー名\AppData\Local\Google\Chrome
の下の、Web Dataから始まる名前のファイルを削除。

雑感


こんな事をしようとした原因は、Chromeの開発版を最近アップデートしたら、アドレスバーの右に出るタイプの拡張機能が全滅したことでした。はてなブックマーク拡張とか、Adblockとか、クリックしてもpopupが出なくなってしまって、快適なWeb徘徊に支障をきたしていました。
どうしてこんな重大なバグを含むリリースがされてしまったのか…。とりあえず直ったので良かったですが。

開発版を使いたい場合、Google Chrome Canaryをインストールするべきですね。今回困ってあちこち検索するまで、存在を知りませんでした。通常のChromeとは別物として、同じ環境に同時にインストールできます。
2013年2月28日木曜日

C# (VS2012)のプロジェクトからF#のライブラリを呼ぶための初歩

Visual Studio 2012 Express Editionを使って、C#のWindowsアプリからF#のライブラリを呼ぶ。…ということをやりたかっただけなのに。VS2012では、F#はVisual Studio Express for Web、C#のデスクトップアプリケーションは、Visual Stidio Express for Window Desktopの担当に分けられていて、無用にめんどくさかったです。

手順


Windows DesktopのWPFアプリのソリューション内に、F#のライブラリプロジェクトを作成!ができれば簡単だったのですが、どうも上手くいかず、現在のところ以下の手順でなんとかしています。

  1. for Webを使って、F#ライブラリプロジェクトを作成
  2. そのプロジェクトで出来たdllを、for Windows DesktopのC#プロジェクト内「参照設定」に追加
    • 参照設定→参照の追加で開いたダイアログ中の「参照」を押すとファイル選択ダイアログが出るので、選ぶ
      • ライブラリプロジェクト名のdllがDebugとかReleaseとかの下にあるはず
    • 同様にFSharp.core.dllも追加
 

fow Webの画面でF#をいじりつつ、for Windows Desktopの画面でWindowsアプリケーションをいじっています。どうにか1つに出来ないものかね…。

for WebでF#を動かすまでの話は少し前のポストの序盤に書いたので、あちらを参照で。
あれ?DebugとReleaseどっちを追加すればいいんだ?切り替えるには、プロジェクトファイルに手を入れないといけないようです。F#で遊んでいる段階では常時Debugビルドでもいいんですが。


プロジェクトを参照出来れば、こんなことをする必要はなく楽なのに。F#プロジェクトを含むソリューションを開こうとすると「このEditionではダメ」と言われてしまいました。出来る方法があったら知りたい。

  • (2013/02/24追記) F#ライブラリは、--standalone をコンパイラに渡すと、F#関係もバンドルされたdllを生成できる (C#側でFSharp.dllを別に読まなくても良い)

デバッグ

プロジェクトは分かれていても、for Windows Desktopの側からステップ実行したり、F#のソースにブレークポイントを張ったりできます。


F#で定義したところにステップインすると…

F#のソースがそのまま見えます。ブレークポイントも設置できます。普通にファイルを開いているだけなので編集もできますが、for Web上のF#ライブラリプロジェクトでビルドしないと反映されません。両側で編集しちゃうと危険。

技術的にはF#が混在することに全く問題なさそうだけれども、機能が潰されてる感じですね。普及段階なんだから、もうちょっとなんとかしてよ、と思います。