コミケ告知

サークル活動の詳細は circle タグの記事へ。
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#が混在することに全く問題なさそうだけれども、機能が潰されてる感じですね。普及段階なんだから、もうちょっとなんとかしてよ、と思います。
2013年2月23日土曜日

JRA公式Webのリンクに小細工するだけのChrome拡張

自作Chrome拡張は意外と難しくないことがわかったので、変な小物を色々と作っています。画像保存とか特定の文字列をコピペするとか、公開したくないようなものが多いですが。

今日は、JRA公式Webサイトのリンクの挙動を書き換えるものを作っていました。

目的


このWebサイト、官公庁なので仕方ないですが、少し古いつくりです。

通常のハイパーリンクと、JavaScriptで処理されるリンクが混在しています。通常のリンクは良いのですが、JavaScriptで処理されるリンクは、右クリックから「新しいタブで開く」を使おうとしても、新しいタブでは正常に開けず、エラーが発生します。さらに残念なことに、見た目ではこの2種類のリンクは区別がつきません。

関連する情報を並べることができないので、タブ一枚で進んだり戻ったりしながら閲覧するのに疲れたので、少し小細工するための拡張を作ることにしました。

構造

JavaScriptで処理されるリンクは、doActionという関数にパラメータが渡されるようになっています。中を見るとただのアンカーではなく、ページ内の隠しフォームにパラメータを入れて、GETではなくPOSTでデータをSubmitすることにより、次のページを開いているようです。

実装


Google先生に尋ねたところ、form.targetに開く先を指定できることがわかりました。リンクの開き方がわかれば、あとは通常動作と「新しいタブで開く」動作で分岐すればよさそうです。とりあえず、Ctrlキーを押しているかどうかを判定し、押されている場合は新しいタブで開くことにしました。

ついでに、あまり使わないけれども、shift同時押しでウィンドウが開くように。適当にターゲット名をでっちあげて、毎回違うウィンドウが増える仕様です。


Chromeの「拡張機能のパッケージ化」では、ディレクトリの中身をまるごと全部、つまりアイコン作成用の作業ディレクトリ&ファイルや、.gitまでまとめて固めてくれるみたいです。そのため、固めるように別ディレクトリを作り、必要なファイルだけそちらにコピーして固めるようにしています。

雑感

Chrome拡張、くだらないものが、それに見合った労力で作れるのが良いですね。ウェブストアに公開するような場合は、細かい作りこみが増えて大変なのかもしれませんが、自分用に作る分にはとても気楽です。
難点があるとすれば、JavaScriptは動的型付け言語のため、簡単なコードですらエラー箇所特定が大変なところです。Chromeのデバッグ環境はかなり強力ですが、それでもあまり大きなものは作りたくありません。
2013年2月20日水曜日

rvmのfirewall対策 (gitのプロトコル変更)

Ruby言語は自分では書かないし使うこともあまりないのですが、バージョンが依存があってめんどくさいので、複数のバージョンをひとつの環境内に共存させるのが割と定番みたいです。 そういった環境管理ツールのひとつがrvmなのですが、内部でgitを呼び出すときに、HTTPではない(ファイアウォールで閉じられていることの多々ある)ポート番号を使おうとする上にエラー処理が適当なので困ります。

debian# rvm install 1.9.3-head
Installing Ruby from source to: /usr/local/rvm/rubies/ruby-1.9.3-head, this may take a while depending on your cpu(s)...
Cloning from git://github.com/ruby/ruby.git, this may take a while depending on your connection...

タイムアウト処理が一切ないようで、接続できなければ永遠に待ちます。gitのプロトコルが使えないのに待っていても成功することはないので、どうにかします。 rvmの中をgit://という文字列で検索をかけたところ、rvmのディレクトリ/config/dbに設定があり、こいつの中身を置換すればいいようです。

git:/をhttps:/に一括置換したところ、うまくいきました。
2013年2月16日土曜日

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

今年も何か新しい言語に触ってみたいと思っていたところに、ちょうど入門コースのある勉強会があったので、参加してきました。
みんなで一斉に進めていきましょう形式ではなく、各自好きなことをやる集まりです。時間も夕方のLT以外は特に予定なく。

自分はF#の最初の一歩から始めたかったため、主催の七誌さんがビギナー向けとして用意してくださっていた資料を見ながら進めました。到着が17時、場所を閉めるのが20時、その間約3時間の参加でした。

環境のセットアップ (VS2012 ExpressでF# + Windowsフォームが遊べるまで)

無料のExpressでは、F#を使うまでに追加の作業が必要でした。F#を推進する気なら、最初から使えるようにしておけばいいのに…
  • Visual Studio 2012 for Webをインストール
  • Web Platform Installerを使って、追加コンポーネントとしてF#をインストール
    • 検索窓にF#と入れると、それっぽいものが出てくる
環境としてはここまで。チュートリアルでは、C#の入門編でやっているようにWindowsフォームを表示させて遊びたいのですが、Visual F#のプロジェクトはライブラリとチュートリアルしか選択肢がありません。実用的には、ライブラリの利用のみが提示されている状態。
そこで、「F#のチュートリアルプロジェクトを作成し、元から書いてあるコードを抹消する」という方法により、F#でWindowsフォームの使えるプロジェクト構成を安直に入手することが出来る、と教わりました。

はじめての えふしゃーぷ

リバーシ(オセロ)のサンプルをいじって、ネット上の文法のリファレンスを見ながら、途中パワーユーザーの方のLTを挟んで、実質90分ほどかけて、なんとか自分で関数が書ける程度にまで進みました。(いきなりリファクタリングっぽいところから入る性分もどうかと思いますが…)
以下がそのコードです…と丸ごと貼るには少々長かったのでリンクのみ。
→https://gist.github.com/moccos/4967078

  • 自作の関数を書いた
    • 関数の引数に型が指定した
  • enumっぽいもの(?)を使った
  • if式、match式を覚えた
  • for構文を使った
  • 配列を使い始めた  (まだよくわかっていない気がする)
こんな状態です。石をひっくり返すロジックがないので、まだリバーシではなく石置きですね。

間違えたところ

  • 関数の引数に型指定するとき、カッコをけちって失敗
  • 関数呼び出すときに、引数足りなくて失敗
後者、C言語やJavaならば「そんな関数/メソッドないよ」というコンパイルエラーが出るところですが、F#は部分適用が効くので、違った形でエラーが現れます。boolを返す関数 myfunc x y を用いて if (myfunc 1) then ... と書くと、「boolじゃなくてint->boolがあるので型がおかしいよ」と言われるわけです。
ここでmyfuncの返り値を真っ先に疑ってしまいました。関数型言語そこそこに使っているのに、これは恥ずかしい…(゚Д゚)

雑感

わりと無難な感じでF#の第一歩を踏み出せたような気がします。F#でいきなり何か作るのは難しくても、C#のプロジェクトの一部にF#のライブラリを混ぜ込むような感じで、徐々に浸食していけるように頑張ります。

言語自体については…mutableな変数が簡単に定義でき、クラスの概念があるので、Scalaと似たような立ち位置になるのでしょうか。JVMに対する.NET、Javaに対するC#、Scalaに対するF#、と。
ML系の言語が初めてなので、不慣れな文法や演算子にびっくりしながら進めてました。Erlangのときも、文法にはなかなか馴染めなかったので、新しい流儀に入るときはこんなものでしょうかね。全く抵抗を感じさせなかったScalaのすごさを改めて感じました。


2013年2月13日水曜日

PARTAKEのタイトルを書きなおすだけのChrome Extension

# はてなダイアリーから移動した記事です。あまり真面目に整形していません。

なぜかイベントページのタイトルが PARTAKE になってしまうpartake.in。何度かいらっとしたので、くだらないChrome拡張を作りました。

最初はgithubに置いてみましたが、これを続けて改良していくことはないだろうし、PARTAKEがまともになれば(あるいはサービス終了すれば)それで終了な一時的なネタなので、gistに移しました。
バイナリ(PartakeTitleCorrector.crx)をChrome拡張画面にドロップすればインストールできるはずです。

実体は、ほぼ定型のコンフィグレーションファイル(manifest.json)と、1行のjavascript。やる気のないアイコンを用意する時間の方が長かったくらいかもしれません。これくらいの分量で動くなら、くだらん自分専用の拡張機能を色々作る気になります。

document.title = "PARTAKE: " + document.body.getElementsByTagName("h1")[0].innerText;

そもそもの問題として、PARTAKEの中の人ならば、TITLEタグの修正はあっという間に終えられるはず。タイトルがおかしいなんて、顔色変えて即修正するレベルの問題では?いったいどうなっているのでしょうか。もはや改良する気はなくて、売却に夢中だったりして?

# 13/02/14追記 バージョン指定が間違っていて、開発版にしかインストールできないので修正しました