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だったら .
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 にエンコードして返してくれます。
今 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.
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を自分のプロジェクトに同梱しちゃいました。
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.
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.
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).
以前 「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 とかみて開発状況をチェックしていたんですが、 見覚えのある名前が見えたときはびっくりしました。
ちょっとしたコードでも公開しておくといいことがあるよ、というお話でした。 最近ここも全然更新してないので、もっとアウトプットしていかないと・・・。
高校生がスパコンを使って5x5の魔方陣の全解を求めたというニュースをきっかけに、 魔方陣の全解列挙が流行っているようです。
高校生がスーパーコンピュータを使って5×5魔方陣の全解を求めることに成功(筑波大プレスリリース) スパコンで約2時間36分かかったという、5×5の魔方陣の全解列挙を、パソコンで試す(C++) 「全解列挙」「数え上げ」「組み合わせ爆発」・・・そして整然とならんだこのマス目・・・ あのおねえさんを思い出しますね。
と、いうわけで、「おねえさんのコンピュータ」の魔方陣版を作ってみました。
おねえさんのコンピュータ(魔方陣編) 「全解列挙をパソコンで試す」の記事と同じような感じで、頭の悪いコードをずらずらと書いてあります。 以下の様な特徴があります。
マスを埋める順番はスパコンで求めたものをベース ただし、対称な位置にあるマスを優先(反転・回転の検索を早い段階で打ち切るため) asm.js による最適化! firefoxで特に高速に動作します わかってはいたけど、asm.jsは人間の書くものではない WebWorkerを使った並列計算 実はまだ5x5の計算結果を見てないのですが、 途中までの計算スピードから推測すると十数時間程度で計算が終わるかと・・・。 (Mac Book Air Mid 2012, 4並列)
コンパイルの手間が無いのでお手軽に試せます。 もっと速いマシンでやればすぐに結果がでてくると思うので、みなさんのレポートお待ちしています。
にゃんぱすー。 最近 C# のコードを見ることが多くなってきました。 開発はVSやMonoDevelop等のIDEを使っているのですが、 diffの確認程度ならgithub上で行っています。 しかし、github上の表示は崩れて非常に読みづらい・・・。
githubのコードプレビューはタブストップが8文字幅で表示されます。 しかし、有名ドコロのIDEはデフォルトがタブインデント、4文字幅で設定されているので、 どうしても表示が狂ってしまいます。 タブインデントではなくスペースインデントを使えば解決☆ なのですが、スペースインデントの中にタブインデントを混入する場合が多々あるので、僕は疲れました・・・。 混在したときのコードなんて、読めたものじゃないですよ。
そこで、githubのタブサイズを変更する Chrome拡張を作ってみました。 ユーザスタイルシートでもできるんですが、まあ、勉強を兼ねて。
GithubTabChange インストール後、github上のレポジトリを開くと≡みたいなマークがURLの横に表示されます。 それをクリックでタブサイズの設定変更が可能です。 githubのプレビューの一斉設定だけでなく、 レポジトリ単位でタブサイズを切り替えることができます。
アイコンとか設定画面のデザインとかちゃんとしたものを作る気力はなかったので、 皆さんのprをお待ちしております。
GithubTabChange on github (これ作ってるときに、githubのHTMLソースの中にtab-size-8というクラスを見つけたのですが、実はどこかに隠し機能としてあるんですかね?)