Shogo's Blog

May 29, 2014 - 2 minute read - csharp

C#のconditional Attributeのコンパイル結果を見てみる

C#で「ある環境では関数の定義ごと消したい」みたいな要件があって、 そういう用途にconditinal attributeが使えるのかなーと話題のあがったので、実際に確認してみました。 結論から言えばできないのですが、せっかく調べたのでメモとして残しておきます。 conditional attribute 「デバッグ時のみにしか実行して欲しくない関数」みたいなものを定義するための機能です。 using System; using System.IO; using System.Diagnostics; namespace ConditionalAttributeTest { class MainClass { public static void Main (string[] args) { Log("fugu"); } [ConditionalAttribute("DEBUG")] public static void Log(string message) { Console.WriteLine(message); } } } こんなふうに書いておくと DEBUG シンボルが定義されている時にだけLogの呼び出しが行われます。 > mcs -d:DEBUG ConditionalAttributeTest.cs > mono ConditionalAttributeTest fugu > mcs ConditionalAttributeTest.cs > mono ConditionalAttributeTest 逆アセンブルしてみる DEBUG付きでコンパイルした結果を逆アセンブルしてみます。 // ...前略 // method line 2 .method public static hidebysig default void Main (string[] args) cil managed { // Method begins at RVA 0x2058 .

May 27, 2014 - 3 minute read - csharp

初期化なしのusing文ってOK?

C# の using ステートメント、普通は変数の初期化とか new とかをまとめてやるものだと思ってたんですが、 某プロジェクトでusing文をこんな感じで使っているのを見かけました。 var hoge = new Hoge(); using(hoge) { // using( var hoge = new Hoge() ) { ならよく見る ... } 見慣れない書き方だったので、本当にリソース解放が行われているのか不安・・・。 リソース解放が行われているのか調べてみました。 まずは結論 リソース解放自体は行われているので、ちゃんと書いてあれば問題なし しかしエラーをコンパイル時に見つけられない場合があるので非推奨 逆アセンブルして調べてみた コンパイル結果見ればちゃんとリソース解放されているかわかるよね! ってことでバイナリを逆アセンブルして調べてみました。 サンプルコード 検証に使ったのはこんなコード。 using System; using System.IO; namespace UsingTest { class MainClass { public static void Main (string[] args) { var sr = new StreamReader ("hoge.txt"); Console.WriteLine ("Hoge: {0}", sr.ReadLine ()); } } } 僕はMac使いに転向したので、Monoを使います。 mcsを使ってコンパイル、monodis ってのを使うとILを見れるらしいです。 Windowsだったら .

May 25, 2014 - 1 minute read - csharp unity messagepack

C# でお手軽にMessagePack解析!

MiniMessagePack.csってのを作った。 C#のプロジェクトにファイルひとつ導入するだけで、お手軽にMessagePackの解析ができます。 なんで作ったの? MiniJSON の置き換えが目的です。 とあるUnityプロジェクトでMB単位のJSONをパースする箇所があってですね・・・ パースにはMiniJSONを使っているのですが、さすがに対象がでかすぎて重たい。 そこでMessagePackへの置き換えを検討してみたわけです。 もちろん C# で動く MessagePack のパーサはすでにあって、 messagepack-cliとかmessagepack-unityとか見つけました。 しかし、Unityのちょっと古いMonoで動かすためにちょっとゴニョゴニョしないといけなかったり、 MiniJSON との互換性を取るためにもゴニョゴニョしないといけなかったり(実際やってみたらキャストが大量に失敗して辛かった・・・)、 今回の用途にはちょっと高機能かなーと思ったので作っちゃいました! つかいかた デコードする byteの配列を渡すとパースして返してくれます。 配列はList<object>で、マップはDictionary<string, object>になります。 using MiniMessagePack; // it means {"compact":true,"schema":0} in JSON var msgpack = new byte[] { 0x82, 0xa7, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0xc3, 0xa6, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x00 }; var packer = new MiniMessagePacker (); object unpacked_data = packer.Unpack (msgpack); /* unpacked_data = new Dictionary<string, object> { { "compact", true }, { "schema", 0}, }; */ エンコードする オブジェクトを渡すと MessagePack にエンコードして返してくれます。

May 22, 2014 - 1 minute read - c++ travis

travis-ciでC++11のテストをする

今 C++ を書くなら C++11 だよね!と言うわけでC++11の新機能を使ってコードを書いたので、 travis-cliでテストしたらFAIL。 $ g++ -std=gnu++0x hogehoge.cpp sorry, unimplemented: non-static data member initializers unimplemented・・・だと・・・。 頑張って動かしてみたのでメモ。 autoconf の設定をする autotoolsを使っていたので、 C++11 に対応しているかのチェックを追加しておきます。 ax_cxx_compile_stdcxx_11.m4をダウンロードし、 configure.ac でm4ファイルをダウンロードするようにしておきます。 m4_include([m4/ax_cxx_compile_stdcxx_11.m4]) AX_CXX_COMPILE_STDCXX_11 AC_LANG([C++]) travis.yaml を設定する ぐぐったらstackoverflowでやり方を見つけました。 標準でテストに使われるコンパイラは古いようなので、新しいバージョンのものをインストールするように設定します。 language: cpp compiler: - clang - gcc before_install: # g++4.8.1 - if [ "$CXX" == "g++" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi # clang 3.4 - if [ "$CXX" == "clang++" ]; then sudo add-apt-repository -y ppa:h-rayflood/llvm; fi - sudo apt-get update -qq install: # g++4.

May 18, 2014 - 1 minute read - c c++ google test

Google Test を使ってC++のテストしてみた

C++ なライブラリを書こうと思い、C++のテストってどうやるんだろうと調べたメモ。 テストフレームワークとして Google C++ Testing Framework を使用、 コンパイルにはautotoolを使ってtravis-ciでテストするところまでやってみました。 やってみた結果→ cpp-test Testを書く Google Test の入門ガイドに書いてあったテストをコピペしてきました。 #include "gtest/gtest.h" int Factorial(int n); TEST(FractionTest, hoge) { EXPECT_EQ(1, Factorial(1)); EXPECT_EQ(2, Factorial(2)); EXPECT_EQ(6, Factorial(3)); EXPECT_EQ(40320, Factorial(8)); } テストの対象となる関数はこちら。 // calculate 1 * 2 * 3 * ... * n int Factorial(int n) { if(n == 0) return 1; return n * Factorial(n - 1); } テスト用実行ファイルのビルドをする せっかくならしっかりしたものをつくろうと、Autotoolsを使ってビルドしてみました。 新しめの Autotools (Autoconf&Automake) を使ってみよう を参考に Makefileのひな形を書いていきます。 Google Test と Travice CI で、C言語で書いたライブラリの継続的インテグレーションをしてみた結果 ではGoogle Testをシステムにインストールしていますが、 システムへのインストールは推奨されていないのと、手元で動かすのが面倒だったので Fused Source File を作ってGoogle Testを自分のプロジェクトに同梱しちゃいました。

May 17, 2014 - 1 minute read - redis perl

Redis::Fast 0.07 をリリースしました!

Redis::Fast 0.07 をリリースしました。 現時点での最新バージョンである Redis.pm 1.974 とコンパチブルになります。 主な修正点は以下の通りです Redis Sentinel 対応 トランザクション内での再接続禁止 再接続にDB選択し直し Redis Sentinel 対応 Redis Sentinel というのは自動フェールオーバーの仕組みらしいです。 (ソースはコピペしたきただけで仕組みはあまり理解していない) どんなものかは本家ドキュメントや実際に検証してみた人の記事をご参照ください。 Redis Sentinel Documentation Redis 2.8 の Sentinel の動きを検証してみた Redis Sentinelを動かしてみた 前から移植作業は進めてたのですが、本家 Redis.pm でもテストがコケたりしてちょっと不安だったのでリリースを見送ってました。 今日 Redis.pm の安定版がリリースされたのでこっちも追従しますよ!! コネクションを作るときに sentinels を渡すと Redis Sentinel から接続情報を取ってきてくれます。 一緒に reconnect を設定しておいてあげると、Masterに何かあった時に接続情報を再取得→ 自動的に Slave へフェールオーバーしてくれます。 use Redis::Fast; my $redis = Redis::Fast->new( sentinels => [ '127.0.0.1:26379' ], service => 'mymaster', reconnect => 1, ); トランザクション内での再接続禁止 Redisにも簡単なトランザクション機能があって、 複数の命令を同時に実行することができます。 トランザクション中に再接続が発生するとトランザクションがリセットされてしまうので、 接続前の命令を再投入する必要があるのですが、Redis.

May 7, 2014 - 2 minute read - android go golang

Androidのバイナリファイルを解析するgoのライブラリ

Androidのアプリの実態はzipファイルなのでunzipすれば簡単に中身を見ることができるわけですが、 開いてもバイナリファイルが入っているだけでよくわかりません。 AndroidSDKに付属しているaaptというツールを使えば読めるんだけどインストールが大変で苦しんでいる人がいたので、 お手軽に解析できるgolangのライブラリを書いてみました。 使い方 go getしてくる githubのレポジトリ からダウンロードしてきます。 go get github.com/shogo82148/androidbinary AndroidManifest.xmlを解析する io.ReaderAtインターフェースを満たすオブジェクトをandroidbinary.NewXMLFileに渡すと解析してくれます。 f, _ := os.Open("AndroidManifest.xml") xmlFile, _ := androidbinary.NewXMLFile(f) reader := xmlFile.Reader() // reader を読むと普通のXMLファイルとして読める resources.arscを解析する アプリ名などの設定はAndroidManifest.xmlには直接書かれておらず、 リソースファイルに書いてあることがほとんどです(開発者がよほどものぐさでなければ)。 リソースの情報はapk内のresources.arscに書かれているので、 このファイルを読む機能もついてます。 f, _ := os.Open("resources.arsc") tableFile, _ := androidbinary.NewTableFile(f) // ID 0x7F040000 に対応するリソースを読む config := &androidbinary.ResTableConfig{} val, _ := tableFile.GetResource(androidbinary.ResId(0x7f040000), config) アプリ名はロケールによって変わったりするので、 configで設定できます。 例えば日本語の名前を取得したい場合はこんな感じ。 // ID 0x7F040000 に対応するリソース(日本語)を読む config := &androidbinary.ResTableConfig{} config.Language[0] = 'j' config.Language[1] = 'a' val, _ := tableFile.

Apr 27, 2014 - 1 minute read - python tweepy twitter

Tweepyの2.3.0が出ました

Tweepyの2.3.0が出ました。 「Tweepy が Application-only Authentication に対応します」僕のprも取り込まれていて、 Application-only Authentication が標準で使えるようになりました。 というわけで、早速遊んでみます。 Application-only Authenticationで遊ぶ 使い方は「tweepyでApplication-only Authenticationしてみた」のときとほぼ同じ。 Tweepy本体に取り込んでもらったので、名前空間がちょこっと変わったくらいです。 Consumer Key と Consumer Secretだけ設定すればいいので、簡単に使えます。 #!/usr/bin/env python # -*- coding: utf-8 -*- import tweepy import codecs import sys sys.stdin = codecs.getreader('utf-8')(sys.stdin) sys.stdout = codecs.getwriter('utf-8')(sys.stdout) CONSUMER_KEY = 'YOUR CONSUMER KEY' CONSUMER_SECRET = 'YOUR CONSUMER SECRET' def main(): user_id = "JO_RI" auth = tweepy.AppAuthHandler(CONSUMER_KEY, CONSUMER_SECRET) api = tweepy.API(auth) arg = {'id': user_id, 'include_rts': 1} user_statuses = tweepy.Cursor(api.user_timeline, **arg).

Apr 18, 2014 - 1 minute read - python twitter tweepy

Tweepy が Application-only authentication に対応します

以前 「tweepyでApplication-only Authenticationしてみた」で 書いたTweepyのAuthHandlerを本体に取り込んでもらいました。 リリースタイミングとかよくわかってないですが、次のリリースとかでApplication-only Authenticationを簡単に使えるようになります、たぶん。 (2014-04-27追記) このprを取り込んだTweepy 2.3.0がリリースされました。早速遊んでみたのでこちらもどうぞ>Tweepyの2.3.0が出ました 取り込まれるまでの経緯 「Application-only Authentication 対応しないの?」って質問は去年からあった(tweepy#318) 先日「ここに動くコード載ってるよ」と僕の記事が紹介される 昨日の夕方「コントリビュートしてみない?」とブログやgithub経由で頼まれる やるしか無い!と思って昨日のうちにpr作成 朝起きたら取り込まれてた 日本語なんてマイナーな言語で記事が書いてあっても、読んでくれる人は読んでくれるんですね。 Tweepy は僕も何度か使ったことがあるので Issue とかみて開発状況をチェックしていたんですが、 見覚えのある名前が見えたときはびっくりしました。 ちょっとしたコードでも公開しておくといいことがあるよ、というお話でした。 最近ここも全然更新してないので、もっとアウトプットしていかないと・・・。

Mar 19, 2014 - 1 minute read -

スパコンで約2時間36分かかったという、5×5の魔方陣の全解列挙を、おねえさんのコンピュータで試す

高校生がスパコンを使って5x5の魔方陣の全解を求めたというニュースをきっかけに、 魔方陣の全解列挙が流行っているようです。 高校生がスーパーコンピュータを使って5×5魔方陣の全解を求めることに成功(筑波大プレスリリース) スパコンで約2時間36分かかったという、5×5の魔方陣の全解列挙を、パソコンで試す(C++) 「全解列挙」「数え上げ」「組み合わせ爆発」・・・そして整然とならんだこのマス目・・・ あのおねえさんを思い出しますね。 と、いうわけで、「おねえさんのコンピュータ」の魔方陣版を作ってみました。 おねえさんのコンピュータ(魔方陣編) 「全解列挙をパソコンで試す」の記事と同じような感じで、頭の悪いコードをずらずらと書いてあります。 以下の様な特徴があります。 マスを埋める順番はスパコンで求めたものをベース ただし、対称な位置にあるマスを優先(反転・回転の検索を早い段階で打ち切るため) asm.js による最適化! firefoxで特に高速に動作します わかってはいたけど、asm.jsは人間の書くものではない WebWorkerを使った並列計算 実はまだ5x5の計算結果を見てないのですが、 途中までの計算スピードから推測すると十数時間程度で計算が終わるかと・・・。 (Mac Book Air Mid 2012, 4並列) コンパイルの手間が無いのでお手軽に試せます。 もっと速いマシンでやればすぐに結果がでてくると思うので、みなさんのレポートお待ちしています。