nDiki : Java

2005年6月17日 (金)

後輩と一緒にプログラミング

後輩が開発中の Java プログラムを添削しつつ、二人で書き直す作業。 今回はほとんど自分がコードの書き直し方を説明するという流れだったし、ペアプログラミングとは言えないかな。

……英語キーボードじゃないPCでのプログラミングは辛い。

[ 6月17日全て ]

2005年8月1日 (月)

Java をやっておけばしばらくは食いっぱぐれない?

開発者不足なので派遣とかを検討。

リクエストとして「Java でプログラムが書けること」と伝えたら、どこも不足気味で売り手市場だとのこと。 とりあえず Java の経験積んでおけば、最悪派遣登録でやっていけるってことか(もちろんその他のスキルも身につけておく必要があるだろうけど)。

[ 8月1日全て ]

2005年8月24日 (水)

Module::Buildソースパッケージング

ExtUtils::MakeMaker

私が Perl が好きな理由の一つに、標準でExtUtils::MakeMakerという Makefile ジェネレータがついているところである。これを使って Makefile.PL を書くと

 perl Makefile.PL
 make manifest
 make
 make test
 make dist

で <pacakge>-<versionno>.tar.gz というソースパッケージを作ることができ、

 tar zxvf <pacakge>-<versionno>.tar.gz
 cd <pacakge>-<versionno>
 perl Makefile.PL
 make
 make test
 make install

という手順でインストールする事ができるようになる。 パッケージの作り方が確立されているので、容易に新しいパッケージを開発しはじめられる。

逆に Java でプログラムを書くのが億劫なのは、このあたりの準備が面倒だからである。 Ant を使っても結局ここら辺自分でやらなければならないし。

ちょっとしたアーカイブの作成

ちょっとしたパッケージを作りたいと思うことは良くある。 例えばいくつかのデータファイルと、READMEファイルなんかをひとまとめにしてアーカイブにするとか。

本当にちょっとしたであれば、手動でアーカイブすれば良いのだが、

  • アーカイブしたいファイル群がバージョン管理下にあって、CVS ディレクトリや .svn ディレクトリがある (除外してアーカイブする必要がある)
  • 同じディレクトリにある、作業用のファイルはアーカイブしたくない (除外してアーカイブする必要がある)
  • アーカイブする前に、チェック用のリグレッションテスト一式を走らせたい (リグレッションテストをかけられるようにする)
  • UNIX でも Windows でもアーカイブ化できるようにしたい。

あたりを考慮しなければならない時は面倒くさくなってくる。

自動化としては

あたりがぱっと思い浮かぶ。 しかし、最初の2つは毎回同じようなものを書くのが面倒だし保守もしにくい。 GNU Autotools はちょっとごっつすぎだし、Windows での環境構築も面倒。

ExtUtils::MakeMaker の欠点

ということで最初は ExtUtils::MakeMaker を使うという線で考えてみた。 もともと Perl モジュール用で汎用用途にはちょっと邪魔な振舞いもあるが、使えないことはないと思う。 しかし make (GNU Make あるいは nmake など) に依存しているという欠点がある。

Module::Build

ということで ExtUtils::MakeMaker の代替である Module::Build ベースで汎用用途に使えないか検討してみた。こちらは pure Perl で make を必要としない。

Module::BuildPerl モジュールビルドにあわせた振舞いがあるものの、ちょっとカスタマイズすれば使えそうだ。 で、いろいろいじった結果、次のような感じにすると使いやすそうだ。

 use Module::Build;
 my $class = Module::Build
   ->subclass(class => 'NonmoduleBuilder',
              code => q{
                        # Don't make blib
                        sub ACTION_code {};
                        # Don't make blib
                        sub ACTION_docs {};
                        # Don't make META.yml
                        sub ACTION_distmeta {
                          # no warning on ACTION_distdir
                          $_[0]->{metafile} = 'MANIFEST';
                        };
                        # Don't add MEATA.yml to MANIFEST
                        sub ACTION_manifest {
                          $_[0]->{metafile} = 'MANIFEST',
                          $_[0]->SUPER::ACTION_manifest(@_);
                        };
                       });

 # Set your archive name and version.
 $class->new(dist_name => 'mypackage',
             dist_version => '1.0.2',
             )->create_build_script;

カスタマイズした部分は以下(Module::Build 0.26 で動作確認)。

  • Perl モジュールビルドに特有の blib ディレクトリを作らないようにする。
  • META.yml を生成しないようにし、アーカイブに含まれないようにする。

上記のようなファイルを Build.PL という名前で作っておけば

 perl Build.PL
 ./Build manifest
 ./Build
 ./Build test
 ./Build dist

等として、アーカイブ作成が容易にできるようになる。

しばらくこの方法でいろいろ試してみることにしてみよう。

[ 8月24日全て ]

2005年9月9日 (金)

J2SE 5.0 の総称と拡張 for ループをはじめて使う

ここしばらく Java であまりコードを書いていなかったし、書いたとしても 1.4 用で書いていたのでずっと新しい言語機能を使っていなかった。

コレクション関係のサンプルコードを書いて人に渡す必要があったので、generics、for-each 構造をやっと使ってみた。 なるほど楽ちん。

[ 9月9日全て ]

2005年9月22日 (木)

skkinput がよく落ちるので uim-skk に乗り換え

メインのノート PC (Debian GNU/Linux sid)では XIMサーバとして skkinput を使っているのだが Firefox で入力をしていると、Firefox を道連れによく落ちてしまう。 何かの登録のためにフォーム入力していたり、WikiPage の編集をしているときに落ちてしまうとかなり辛い。

ということで遅ればせながら uim を試してみることにした。

インストール

ほぼ「Japanese - Debian GNU/Linux スレッドテンプレ」の通りに設定。

SKK用の辞書などは既にはいっているので

 apt-get install uim uim-skk

として uim 関連のファイルをインストール

~/.xinitrc の skkinput 関連の部分をコメントアウトして、

 if type uim-xim &> /dev/null ; then
   uim-xim &
 fi
 XMODIFIERS=@im=uim ; export XMODIFIERS
 GTK_IM_MODULE=uim ; export GTK_IM_MODULE
 UIM_IM_ENGINE=skk ; export UIM_IM_ENGINE

を追記。

これで Firefox でも問題なく uim-skk日本語入力ができた。

ツールバー

Window Manager 用システムトレイとして docker を使っているので、uim-toolbar-gtk-systray を使う。

 uim-toolbar-gtk-systray &

Emacs 用に設定を変更

初期状態だと C-j でも uim-skk がオンになる。 これだと Emacs を使っている時によろしくない。

uim-skk の方は Shift-space でトグルすればよいので、uim-pref-gtk 上の 「SKKキー設定1」の「モード遷移 - [SKK]オン」から Control-j を外しておいた。

追記

Java アプリケーションでの入力。

J2SE (1.5.0_04) 上で日本語入力ができないのに気がつく。

~/.Xdefaults に

 *inputMethod: uim

を追加して入力できるように対応 (2005年9月24日追記)

[ 9月22日全て ]

2005年11月14日 (月)

久しぶりに build.xml を書く

ソフトウェアレビュー日。 最近ミーティングの調整やドキュメントの作成などばかりで、ソースコードに触れる機会がほとんどなかったので Eclipse なんか入れちゃったりしてウキウキ。

……あれ? ビルドまだ自動化してないの? いや、普通まず最初にビルド自動化しておくでしょ。configure.ac とか Makefile.am とか Makefile とか Makefile.PL とか Build.PL とか書いちゃうでしょ。 Java ならまあ build.xml とか書いとくでしょ。 make dist (相当が)できるようなターゲット書いておくでしょ。

……無いのね。Eclipse でぬくぬく書いてるのね。コード書いている間はいいよ。 でもね、節目のビルドはね、そういうのでやってね。ビルドファイルの含めているソースアーカイブもコマンド一発で作れるようにしておいてね。

はい。では、書きますよ。今回は私が。 次はちゃんと書いてね。

[ 11月14日全て ]

2007年12月24日 (月)

今日のさえずり - スーツに着た回数を記録する仕組みが欲しい

naney:2140302022

[ 12月24日全て ]

2007年12月29日 (土)

Twitter ベイジアンフィルタプロキシ

Twitter で following が増えてくるにつれて、タイムラインに目を通すのが大変になってきた(という程きちんと見ている訳ではないが)。 さっとタイムラインをなめて面白そうな情報をピックアップしたい時は、「おはよう」とか「風呂入った」とか「トイレ」とかは除外して読みたい(そういう書き込み自体は嫌いじゃないのだが、人生はあまりにも短い)。

Twit や P3:PeraPeraPrv では NG ワード指定ができて、それらを含むステータスは表示しないようにできるのだが、Twitter の書き込みは揺らぎが激しすぎて指定しきれないという弱点がる。

ということでベイジアンフィルタでフィルタリングしてみることにした。

自前で Twitter クライアントを作る気はないので、proxy の形でさっと実装してみた。

 #!/usr/bin/perl

 use strict;
 use warnings;

 use HTTP::Proxy;
 use HTTP::Proxy::BodyFilter::complete;

 my $proxy = HTTP::Proxy->new(port => 8088);
 $proxy->push_filter(response => HTTP::Proxy::BodyFilter::complete->new,
                     mime     => 'application/xml');
 $proxy->push_filter(response => Bsfilter->new,
                     mime     => 'application/xml');
 $proxy->start;

 {

   package Bsfilter;

   use File::Temp qw/tempfile/;
   use XML::XPath;
   use base qw(HTTP::Proxy::BodyFilter);

   sub filter {
     my ($self, $dataref, $message, $protocol, $buffer) = @_;
     return unless defined($$dataref) && $$dataref ne '';
     eval {
       my $xml = XML::XPath->new(xml => $$dataref);
       my @nodes = $xml->findnodes('/statuses/status/text/text()');
       return unless @nodes;
       for my $node (@nodes) {
         my $text = $node->getNodeValue;
         if (is_NG($text)) {
           $node->setNodeValue("[NG] $text");
         }
       }
       $$dataref = qq(<?xml version="1.0" encoding="UTF-8"?>\n);
       $$dataref .= $xml->get_context->toString;
       utf8::encode($$dataref);
     };
     if ($@) {
       warn $@;
     }
   }

   sub will_modify { 1 }

   sub is_NG {
     my ($text) = @_;

     my ($fh, $filename) = tempfile();
     utf8::encode($text);
     print $fh $text;
     close($fh);
     my $result
       = system(
       "bsfilter --homedir ~/.twitter-bsfilter --ignore-header --auto-update $filename"
       );
     unlink($filename);

     return !$result;
   }
 }

HTTP proxy の作成

PerlHTTP proxy を作ろうとして真っ先に思い浮かんだのは POE だけれど、ちょっとヘビーなので今回は HTTP::Proxy をチョイス。 もともとフィルタリング HTTP proxy を作ることを念頭に置いた Perl モジュールなので今回の目的にぴったり。

1つはまった点といえば、filter の呼び出しがレスポンス全てを取得してからではなく一部分ずつの呼び出しになるところ。その仕様に気がつくのにちょっと時間がかかってしまった。 例えば XML 形式のレスポンスをフィルタしようとしても、普通に HTTP::Proxy を使うと XML の一部ずつがフィルタに渡されるため、XML のパースがうまくいかない。

これについては HTTP::Proxy::BodyFilter::complete を使うことで、まとめてフィルタに渡せるようになった。

レスポンスの処理

Twitter のタイムライン取得については P3:PeraPeraPrvXML 形式で取得しているので、そのタイプのレスポンスをフィルタするようにした。

XML::XPath でステータス部分を抜き出して NG 判定し、NG であれば先頭に [NG] を追加する。 これで Twitter クライアント側で [NG] を NG ワード指定すれば、表示されないようにすることができる。

bsfilter による NG 判定

NG 判定は普段メールspam フィルタとして使っている bsfilter を使った。 単純に system 関数で呼び出して結果を取得するだけ。

今回は対象がメールではないので --ignore-header を指定。また自動的に学習するように --auto-update を指定。 それと普段メールのフィルタリングに使っているのとは bsfilterデータベースを別にしたいので、--homedir も指定しておく。

NG と非 NG の学習。

NG ワードを twitter-NG.txt に、非 NG ワードを twitter-clean.txt に書いて以下のコマンドを実行。

 bsfilter --add-clean --ignore-header --homedir ~/.twitter-bsfilter twitter-clean.txt
 bsfilter --add-spam --ignore-header --homedir ~/.twitter-bsfilter twitter-NG.txt
 bsfilter --update --homedir ~/.twitter-bsfilter

自分の環境 (Debian GNU/Linux sid)では、UTF-8 で書いておいて問題なかった。

フィルタリングしてみる

あとは先の proxy を起動し、P3:PeraPeraPrv でプロキシとして localhost:8088 を指定すれば OK。

タイムラインを取得するたびに bsfilter が動いて NG なステータスには [NG] が挿入される。

フィルタリングの精度

これについては、まだまだチューンの必要ありかな。

  • 事前の学習データが少ない。
  • --auto-update していることもあり、最初に NG 判定が多いとそちら側に強化されすぎる。
  • 毎回 bsfilter を呼んでいるため、同じステータスが何度も学習される。

まだ使える精度まで上がってないけれど、教師データを増やせばそれなりにいけるかもしれない。

proxy の枠組ができたので、(@~は抜いてから bsfilter に渡すとか、前後の文脈も含めるとか)いろいろ試して遊べそうではある。 別に bsfilter にこだわらず、正規表現による判定などをしてもよいし。

この辺り P3 は Java で書かれているので、プラグインを書いて拡張できるよう将来になると面白いなと思ってみたり。

[ 12月29日全て ]

2008年6月23日 (月)

サブプロジェクトが使える GTD ツール ThinkingRock 2.0.1

naney:2603837839

Task CoachGTD しているうちに、もっとスマートにできるツールがないかなと探して出会ったのがこれ。

  • Java で書かれており、Linux でも使える。
  • サブプロジェクトを作ってブレイクダウンしていける。

というのがイケてる。Web ベースの GTD ツールも多いが、ThinkingRock は普通のアプリケーションなのでインストールも簡単。RDBMS 等のセットアップも不要であり、すぐに使える。

GTD の流れを知っていればマニュアルをほとんど見なくても自然に使うことできる。 今日ダウンロードして使い始めたのだが、すぐに ThinkingRock ベースで GTD のプロセスをまわせるようになって驚いた。

GTD をしていて欲しいと思っていたプロジェクトテンプレートも作っておける。 チェックリスト的なプロジェクトを登録しておいて、必要な時にプロジェクトにコピーして使うような運用ができるようだ。

これホントいいんじゃない?

今後は

  • 仕事 -> ThinkingRock
  • リピートするアクション -> RTM (ThinkingRock にはリピートがない)
  • 外出先でチェックするアクション(買い物など) -> RTM (ThinkingRockケータイで見られない)
  • プライベート -> 手帳 (PC とは離れたプロジェクトが多い。一部は ThinkingRock にのせてもいいかもしれない。)

という形でまわしてみようと思う。

[ 6月23日全て ]

2009年3月13日 (金)

久しぶりの C++GNU Automake + CppUnit

ちょっとした文字列構文解析関係の C++ コードを書き始めた。 C++ は随分触ってなかったので「C++ で書き直すのを考慮してそれっぽく Perl で書くから後で書き直して」と最初は言っておいたのだが、それもあんまりだと思って C++ で書くことにした。

Debian GNU/Linux 上で書くので GNU Automake + CppUnit で。 「Perl + Test::Harness」や「Java + Eclipse + JUnit」や「C# + Visual C# + NUnit」などと比べるとやっぱりタルいな。

1つメソッド書くのに、

  • テストメソッドの宣言
  • テストメソッドの登録 (CPPUNIT_TEST())
  • テストメソッドの実装
  • メソッドの宣言
  • メソッドの実装

と 4ファイル5カ所編集しなければならない。 クラス追加時には Makefile.am にヘッダファイルとソースファイルをテストケース用のと含めて4ファイル書き加える必要があるし。

あー面倒。

でも C++ で書き始めると楽しいんだよなあ。

[ 3月13日全て ]

About Me

Naney Naney (なにい)です。株式会社ミクシィで SNS 事業の部長をしています。

nDiki1999年1月に始めたコンピュータ日誌を前身とする NaneyWeb 日記(兼パーソナルナレッジベース)です。ちょっとしたノートは nNote にあります。

※内容は個人的見解であり所属組織とは関係ありません。

月別インデックス
Process Time: 0.083397s / load averages: 0.30, 0.33, 0.44
nDiki by WATANABE Yoshimasa (Naney)
Powered by DiKicker