« 2009年06月 | メイン | 2009年08月 »

2009年07月 アーカイブ

2009年07月02日

CSV Mailer バージョン0.3.1公開

CSV Mailer バージョン0.3.1を公開しました。
今回のバージョンアップでは、ご要望の多かった「宛先(To)の複数登録」をできるように変更しました。

公開しているファイルは実行ファイル(exeファイル)だけです。
バージョン0.3.0(ベータ版)をインストール後、実行ファイルを差し替えて下さい。

後日、ヘルプファイル等を更新して、バージョン0.3.2として公開する予定です。

皆様のご意見ご感想をお待ちしています。

C++Builderの自動変数

C++Builderの自動変数について。

C++の自動変数は、自動的にコンストラクタとデストラクタが呼ばれます。

{
  TTest test; //コンストラクタが呼ばれる
} //スコープを抜けるとデストラクタが呼ばれる

一方、newで生成したオブジェクトは、deleteしなければなりません。

{
  TTest* test = new TTest(); //コンストラクタが呼ばれる
} //スコープを抜けてもデストラクタは呼ばれない。deleteしないとメモリリーク。

C++Builderでは、TObjectを継承しているクラスは、自動変数として使用できません。

TStringList list; //コンパイルエラー
TStringList* list = new TStringList(); //OK

std::unique_ptrを使えば、TObjectを継承しているクラスも自動変数のように扱うことができます。
(古いC++Builderにはstd::unique_ptrはありませんので、std::auto_ptrを使います。)

#include <memory>
{
  std::unique_ptr<TStringList> list(new TStringList());  //コンストラクタが呼ばれる
} //スコープを抜けるとデストラクタが呼ばれる

ゼピール サーキュレーター ブラック DKS-20

扇風機の代わりとして「ゼピール サーキュレーター ブラック DKS-20」を買いました。

扇風機ではありませんので、タイマー機能も首振り機能もありません。
機能は、本当にただ風を送るだけ。

サーキュレーターついて調べると、音の問題をよく目にします。
その点、ゼピール サーキュレーター ブラック DKS-20はとても静か。
でも、パワーは十分です。

扇風機は使わない期間も場所をとります。
このサーキュレーターはコンパクトで場所をとらないところも嬉しいです。

お値段を考えると、お買い得だと思いました。

2009年07月04日

CSV Mailer バージョン0.3.2公開

CSV Mailer バージョン0.3.2を公開しました。

今回のバージョンアップでは、ヘルプファイルを更新しました。
実行ファイルはCSV Mailer バージョン0.3.1とほとんど同じです。
(画面周りの微調整を行いました。)

皆様のご意見ご感想をお待ちしています。

お知らせいただいた不具合については、現象を確認できていないため、対応できていません。
申し訳ございません。

追記
お知らせいただいた不具合に対処した新しいバージョンを7月5日にリリースします。
修正できているかわかりませんが、関係のある箇所を見直します。

できるかなV3

できるかなV3

できるかなV3』を読みました。
とても読みにくい漫画ですが、脱税編だけでも読む価値あり。

ごねると税金は安くなる。

領収書に書かれている人が実在しないと税務署員に問い詰められると、
「ゴーストライター。だから実名は出せないの」

などなど。

最終的に、1億円の税金が1,500万円まで安くなっています。
正直に税金を払うことが、ばからしく思えてきます。

この漫画に出てくる税理士さんもすごい。

「けっこうするどい領収証も通りましたからねえ。
かなりやり込めたと思いますよ。
このコクヨの一番安い紙の300万円とかねえ。
おせっかいですけど印紙くらいははりなさいよ。」

そんなとんでもない領収書が通るのか。

「本税を払えば利息に利息はつけられないので、」
「つけられないので?」
「西原さんちにずーっと督促が送られてきます。それがおイヤでなければ」
「なければ?」
払わない。」

すばらしい。

2009年07月05日

CSV Mailer バージョン0.3.3公開

CSV Mailer バージョン0.3.3を公開しました。
連日のバージョンアップになりました。

お知らせいただいた不具合が直っているといいのですが。

D2 バージョン2.2.4を公開しました

D2 バージョン2.2.4を公開しました。

実行プログラムはバージョン 2.2.3a(ベータ版)と同じです。

バージョン 2.2.2からの変更点

  • パラメータ入力画面の高度タブに「パラメータ文字も値に含める」を追加しました。

今回の機能追加によって、より複雑な条件にも対応できるようになりました。

皆様のご意見・ご感想をいただけると喜びます。
よろしくお願いします。

図書館蔵書検索ソフト SearchLibrary バージョン 0.3.6公開

図書館蔵書検索ソフト SearchLibraryのバージョン 0.3.6を公開しました。

今回のバージョンアップでは、Amazonの「Product Advertising API」の電子署名に対応しました。

バージョン0.3.5以前のものは、Amazonの「Product Advertising API」の電子署名に対応していません。
そのため、2009年8月15日以降、Amazonの検索ができなくなります。
ご注意ください。

世界を股にかける数十億ドル規模の巨大航空会社をストップさせたバグ

Release It! 本番用ソフトウェア製品の設計とデプロイのために』で紹介されていた話。

数百の旅客機と数万人の社員を擁し、世界を股にかける数十億ドル規模の巨大航空会社をストップさせたのが次のコード。
さて、どこに問題があったかわかるだろうか。

package com.example.cf.flightsearch;
…
public class FlightSearch implements SessionBean {
  private MonitoredDataSource connectionPool;
  private List lookupByCity(…) throws SQLException RemoteException {
    Connection conn = null;
    Statement stmt = null;
    try {
      conn = connectionPool.getConnection();
      stmt = conn.createStatement();
      // 検索のロジックを実行して、
      // 結果のリストを返す
    } finally {
      if (stmt != null) {
        stmt.close();
      }
      if (conn != null) {
        conn.close();
      }
    }
  }
}

ヒントを一つ。
問題があるのは「finally { … }」の部分だ。

追記
アジャイルプラクティス 達人プログラマに学ぶ現場開発者の習慣』にも、おそらくこの事件と思われる話が紹介されていました。

つい先日も、大規模な航空座席予約システムでの重大な障害がニュースで報じられた。 システムがクラッシュして飛行機が空港に足止めされて、何千人もの乗客が立ち往生することになった。 航空輸送システム全体の混乱は数日間にもわたって続いたそうだ。 原因は何だったのかって? アプリケーションサーバで起きた、たった1つのSQLの非チェック例外だったんだ。

2009年07月07日

CSV Mailerバージョン0.3.4公開

CSV Mailerバージョン0.3.4を公開しました。

今回のバージョンアップの変更は、機能変更が2つとバグ修正が2つです。

機能変更

  • 差し込みタグを適用した結果としてメールアドレスが空になった場合は、エラーではなく設定しないようにしました。
  • メールプレビュー画面で宛先にメールアドレスが一つも設定されていない場合は、エラーを表示するようにしました。

バグ修正

  • 「一行目は列名」をチェックした場合に、プレビューや送信処理でエラーメッセージが示す行番号とCSVファイルの行番号がずれていた問題を修正しました。
  • プレビュー画面で、ToのメールアドレスにエラーがあるときにCCにエラーがあると表示される問題を修正しました。

バグ報告は本当に助かっています。
ありがとうございます。

nextCSV バージョン 1.1.7公開

nextCSV バージョン1.1.7を公開しました。

条件列のCSVファイルへのエクスポート機能を実装しました。

nextCSVは、CSVファイルを利用するソフトにあわせた形式に変換するソフトです。
顧客管理ソフトや基幹ソフトで作られたCSVファイルを、宛名ソフトや宅急便伝票印刷ソフトなどCSVファイルを利用する側が要求する形式にあわせて加工します。

詳しくは「nextCSV CSVファイル編集ソフト」をご覧ください。

ご意見ご要望をお待ちしています。

図書館の24時間の図書貸し出しサービス

こんな図書館が近所にほしい。

インターネットや携帯電話で貸し出しを予約すると、スタッフが外のロッカーに図書を納入。 利用者にロッカーの番号と暗証番号を通知する。 ビジネスパーソンなど、平日の開館時間に図書館を訪れることができない人でも図書を借りられるようになったのである。

すべての蔵書にICタグ装着 同規模都市で全国1位の図書館に

24時間の図書貸し出しサービス。
図書館のスタッフが図書館の外にあるロッカーに予約した図書を入れてくれる。
開館時間に図書館に行かなくても、図書を借りることができる。

これはいい。本当にすばらしい。
近所の図書館にも今すぐ欲しい。

2009年07月08日

C++テンプレートテクニック

C++テンプレートテクニック』を読みました。

C++テンプレートテクニック』は今までありそうでなかったC++のテンプレートの入門書です。
Modern C++ Design』のような高度な内容の本はありましたが、テンプレートの入門書というのはこの本が初めてではないでしょうか。

目次
Chapter 1 テンプレート前史
Chapter 2 テンプレートの基礎
Chapter 3 Generic Programmingの基礎
Chapter 4 テンプレートメタプログラミング
Chapter 5 SFINAE
Chapter 6 ポリシー
Chapter 7 Type Erasure
Chapter 8 CRTP
Chapter 9 テンプレート型変換演算子
Chapter 10 Expression Template
Chapter 11 Extension Member Function
Chapter 12 C++0xにおけるテンプレート
Appendix 参考資料

Chapter 1~Chapter 3までがテンプレートの入門編。
Chapter 4以降からテンプレートを使ったテクニックを紹介。

テンプレートの基礎知識を体系的にまとめたものを見た記憶がありませんので、 Chapter 1~Chapter 3の入門編はテンプレート初心者にとっては貴重な情報だと思いました。

私がおもしろいと感じたのはChapter 4以降。
プロパティや戻り値の型によるオーバーロード、拡張メンバ(既存クラスにメンバ関数を追加)など、今まで不可能と思っていたことを実現するテクニックなど。

テンプレートの入門書としてはもちろん、復習と知識の更新にもお薦めの一冊です。

C++テンプレートテクニック』を読んだら次は『Modern C++ Design』に挑戦ですね。

2009年07月09日

携帯電話利用者のページビューとビジネスの成否は別問題

リクルートは、20代から30代前半の男性(M1層)をメインターゲットとした携帯電話向けサイト「R25式モバイル」を7月30日に終了する。「モバイルよりPCサイトに出稿を希望する広告主が多いため、PCサイトに資源を集中した方が効果が高い」(同社広報部)と判断したという。

「R25式モバイル」終了 月間1億3000万PVも「広告主はモバイルよりPC」

ページビュー至上主義に一石を投じる興味深い記事。

月間のページビューが1億3000万程度と好調だった携帯電話向けサイトを終了するという。
理由は「モバイルよりPCサイトに出稿を希望する広告主が多いため」。
ということは、広告主としてはPCサイトの方が広告効果が高いということかな。

サイト運営者はユーザー数やページビューとビジネスの成否は別問題ということを認識する必要がある、と思った。

2009年07月12日

Boost C++ Librariesプログラミング

Boost C++ Librariesプログラミング

図書館で借りて読みました。
良い本でしたので購入する予定です。

C++ Builder 2009にはBoost C++ Librariesのバージョン1.35が入っています。
Boost C++ Librariesプログラミング 第2版』ではBoost C++ Libraries バージョン1.35に対応しました。
C++ Builder 2009をきっかけに本格的にBoostを学ぼうと思ったら、まさにぴったりの本です。

この本ではライブラリの説明に説明文に加えて、動作可能なソースコードがついているので、理解しやすいと感じました。
Boostが初めての人にはBoostの学習書として、すでにBoostを使っている人には日本語のリファレンスマニュアルとして使える優れた本だと思います。

2009年07月13日

Monostateパターン

もし全部のメソッドをクラスメソッドにしてしまえば、インスタンス間の区別がなくなります。つまり、インスタンスが1個しかないのと同じです。

Singletonパターン (2) - ぜ~んぶクラスメソッド

それはSingletonパターンではなくて、Monostateパターンですね。

Monostateパターンは『アジャイルソフトウェア開発の奥義』を読んで知りました。

オブジェクト指向における再利用のためのデザインパターン』に掲載されているGoFによる23のデザインパターン以外にも、デザインパターンはたくさんあります。

デザインパターン紹介のページがよくまとまっていて、勉強になります。

C++Builder2009で文字コードを変換する

C++Builder2009で簡単に文字コードを変換する方法はないかと調べてみると、「MECSUtils」が見つかりました。

Unicode文字列をAnsi文字列へ変換するConvertUnicodeToMultiByte関数と、Ansi文字列を他のコードページのAnsi文字列へ変換するConvertString関数を使ってみたところ、C++Builder2009でも問題なく使用することができました。

C++Builder2009での使い方を簡単にまとめました。

このような便利なライブラリを公開してくださったDEKO様に感謝申し上げます。

2009年07月19日

文字列から正規表現にマッチするすべての文字列を取得する

String#scanを使うと、文字列から正規表現にマッチするすべての文字列を取得することができます。

irb(main):020:0> '1a2b3c4d5e6f7e8h9'.scan(/\d/)
=> ["1", "2", "3", "4", "5", "6", "7", "8", "9"]

NetBeans 6.7でRuby on Railsの開発をして気がついたこと

NetBeans 6.7でRuby on Railsの開発をして気がついたこと

UnitTestのテスト結果のウィンドウが豪華になっていた。
エラーがあると、テスト結果のバーがアニメーション表示する。
# RSpecを使っていたので気がつかなかったが、もしかすると昔からかもしれない。
人の目は敵を素早く見つけるために、動いているもにに視点が移動する。
したがって、アニメーション表示するテスト結果のバーに視点が移動してしまい、
集中してソースコードを見ることができない。
アニメーション表示は見た目はいいが使い勝手は悪い。

愛用していたプラグインが動作しない。
NetBeansのRuby用プラグインで紹介したタブ文字をハイライト表示する「Tabs」プラグインと、行末のホワイトスペース(半角空白、全角空白、タブ文字)をハイライト表示して削除してくれる「Trailing Whitespace」プラグインが動作しない。
このプラグインの機能は多くのエディタに搭載されている機能だ。
NetBeansにも標準で搭載してもらいたい。

2009年07月20日

エラーメールから宛先不明のメールアドレスを取り出したい

メールマガジンを発行していると、宛先不明のエラーメールがたくさん返ってくるようになります。

そのようなメールアドレスにはメールを送らないようにするには、エラーメールからメールアドレスを取り出して、メールマガジンを解除する必要があります。

エラーメールが多くなると、手作業でメールアドレスを取り出すのは、とても面倒な作業です。

D2 メール自動データベース変換ソフト」を使うと、メールからメールアドレスを取り出す作業を自動化することができます。

具体的な設定方法は、「メールの本文中にあるメールアドレスを抽出する方法」で紹介していますので、参考にしてください。

C++Builder Tipsに「C++Builder2009とIndy10でメール送信」を追加しました

C++Builder Tipsに「C++Builder2009とIndy10でメール送信」を追加しました。

このTipsは以下のページを参考にさせていただきました。

間違い等がありましたら、教えていただけると喜びます。

2009年07月21日

HashとActiveSupport::OrderedHashのmergeの挙動が異なる

HashとActiveSupport::OrderedHashのmergeの挙動が異なる。
使用しているRuby on Railsのバージョンは2.3.2。

Hash#mergeの場合

>> ha = {1 => 2, 2 => 4}
=> {1=>2, 2=>4}
>> hb = {2 => 1, 3 => 1}
=> {2=>1, 3=>1}
>> hc = ha.merge(hb) {|key, s_val, o_val| s_val + o_val}
=> {1=>2, 2=>5, 3=>1}

ActiveSupport::OrderedHash#mergeの場合

>> h1
=> #<OrderedHash {1=>2, 2=>4}>
>> h2
=> #<OrderedHash {2=>1, 3=>1}>
>> h3 = h1.merge(h2) {|key, s_val, o_val| s_val + o_val}
=> #<OrderedHash {1=>2, 2=>1, 3=>1}>

ActiveSupport::OrderedHashの場合、mergeの引数のブロックが無視されているようだ。
HashのつもりでOrderedHashを使っていたので、問題に気づくのに時間がかかった。
まさかこんな基本的なところに問題があろうとは。

2009年07月22日

Railsの思想

“Railsという現象”とコミュニティの性質」で、Rails開発者がRailsの思想について語っている部分が興味深い。

以前に書いた記事「Rubyの後方互換性の低さは、Rubyの良さである。」と同じようなものだけど。

「枯れたバージョンのRailsというものはない。昨日のバージョンより今日のバージョンのほうがいいし、今日のものより明日のRailsがいい。だから常に“今”のRailsがベスト」

“Railsという現象”とコミュニティの性質

とか、

「Railsでは新機能が未完成のまま出てくることが多い。攻めのプロダクト。完成していなければ、自分が完成させながら使えばいいじゃんという認識がコミュニティ側にある」

“Railsという現象”とコミュニティの性質

など。

こういう思想を理解せずに使うと、後で痛い目に遭うかもしれない。

2009年07月23日

EurekaLog導入後

約3ヶ月前に「EurekaLog導入レポート」の記事を書いてから、その後について。

最近1週間で立て続けに3件のバグ報告をいただきました。
それで、あらためてEurekaLogの偉大さを確認しました。

EurekaLogのエラーログには、問題の発生したソースコードの場所が記録されています。
おかげで問題の解決がとてもスムーズにできました。

しかもバージョン管理の機能があるのか、ソフトウェアをリリースした時点のソースコードを見ることができます。
リリース後にソースコードを修正していても、ちゃんと問題の箇所を確認することができます。

ということで、近日中に「D2 メール自動データベース変換ソフト」の修正版を公開します。
皆様のご意見やご要望・バグ方向をお待ちしています。

2009年07月24日

GitとMercurial、どちらを使うべきか

GitとMercurialのどちらを使えばいいかを考えるときに、参考になる記事。

というわけで、gitを運用するのは諦めることにしました。んで、どういう人がgitを使ってはいけないか、独断と偏見でまとめてみると・・・

GitとMercurial、どちらを使うべきか

GitをやめてMercurialを使うことにした著者の体験から、Gitの欠点を指摘している。
とても参考になった。

それから『入門Mercurial』はとてもわかりやすくていい本だった。
このような優れた入門書があることも、Mercurialを選ぶ理由になると思う。

2009年07月26日

D2 バージョン2.2.5をリリースしました

D2 バージョン2.2.5をリリースしました。

今回のバージョンアップでは次の2つの不具合を修正しました。

  • ファイルサイズの大きいUnix mbox形式のファイルを開いたときにエラーが発生する問題を修正しました。
  • Outlookが起動できないときに「Outlookのフォルダ選択」画面が表示される問題を修正しました。

バグ報告ありがとうございました。

2009年07月27日

Mail Export Tool バージョン0.7.8をリリースしました

Mail Export Tool バージョン0.7.8をリリースしました。

今回のバージョンアップでは、不具合を1つ修正しました。
先日のD2のバージョンアップで修正した不具合と同じものです。

  • 変更点
    • ファイルサイズの大きいUnix mbox形式のファイルを開いたときにエラーが発生する問題を修正しました。

皆様のご意見、ご要望、バグ報告をお待ちしています。

2009年07月29日

Django 1.1 released

Django 1.1がリリースされた模様。

Django 1.0系のコードはDjango 1.1でもそのまま動くはずですが、変更点には目を通しておいた方がいいかもしれません。

ダウンロードはダウンロードのページからどうぞ。

2009年07月30日

mlang.dllのConvertINetString関数を使った文字コードの変換

mlang.dllのConvertINetString関数を使った文字コードを変換するサンプル

C++ Builder 2009を使いました。
_TCHARのマップ先は「wchar_t」に設定しています。

本題に入る前に前準備として、DLLのリソース管理クラス(RAII)を用意します。
このクラスTDllはデストラクタでFreeLibraryを行うので、DLLのハンドルの解放のし忘れを防ぐことができます。

/**
 * DLLのリソース管理(RAII)
 */
class TDll
{
public:
  TDll(const UnicodeString& DllName)
  {
    FDll = LoadLibrary(DllName.c_str());
  }
  ~TDll()
  {
    if (!FDll) FreeLibrary(FDll);
  }
  operator bool() const
  {
    return FDll;
  }
  operator HMODULE() const
  {
    return FDll;
  }
private:
  HMODULE FDll;
};

ConvertINetStringのtypedefを定義します。
なくてもいいのですが、あるとソースコートが読みやすくなります。

typedef HRESULT WINAPI (*TConvertINetString)(LPDWORD lpdwMode, DWORD dwSrcEncoding, DWORD dwDstEncoding, LPCSTR lpSrcStr, LPINT lpnSrcSize, LPBYTE lpDstStr, LPINT lpnDstSize);

mlang.dllを読み込みます。
読み込みに失敗したときはエラーメッセージを表示します。

TDll dll("mlang.dll");
if (!dll)
{
  std::puts("DLLの読み込みに失敗しました。");
  return 0;
}

ConvertINetString関数のアドレスを取得します。
失敗したときはエラーメッセージを表示します。

//関数のアドレスの取得
FARPROC proc = GetProcAddress(dll, "ConvertINetString");
if (!proc)
{
  std::puts("関数のアドレスの取得に失敗しました。");
  return 0;
}
TConvertINetString ConvertINetString = reinterpret_cast<TConvertINetString>(proc);

ConvertINetString関数に渡す変数を用意します。
今回のサンプルではShift_JISをEUC-JPに変換します。

DWORD mode = 0;
AnsiStringT<932> sjis = "あいうえおかきくけこさしすせそたちつてと";
int sjisLen = sjis.Length();
int eucLen = sjisLen * 2 + 1;
boost::scoped_array<char> euc(new char[eucLen]);
ZeroMemory(euc.get(), eucLen);

ConvertINetString関数を呼び出して変換します。
変換に失敗したときはエラーメッセージを表示します。

//変換
HRESULT result = ConvertINetString(&mode, 932, 51932, sjis.c_str(), &sjisLen, euc.get(), &eucLen);
//変換結果の検証
if (result != S_OK || eucLen == 0)
{
  std::puts("変換に失敗しました。");
  return 0;
}

というのが一連の流れになります。

以下のコードはShift_JIS(コードページ932)の文字列をEUC-JP(コードページ51932)に変換します。

#include <tchar.h>
#include <iostream>
#include <memory>
#include <boost/scoped_array.hpp>

int _tmain(int argc, _TCHAR* argv[])
{
  typedef HRESULT WINAPI (*TConvertINetString)(LPDWORD lpdwMode, DWORD dwSrcEncoding, DWORD dwDstEncoding, LPCSTR lpSrcStr, LPINT lpnSrcSize, LPBYTE lpDstStr, LPINT lpnDstSize);

  //DLLの読み込み
  TDll dll("mlang.dll");
  if (!dll)
  {
    std::puts("DLLの読み込みに失敗しました。");
    return 0;
  }
  //関数のアドレスの取得
  FARPROC proc = GetProcAddress(dll, "ConvertINetString");
  if (!proc)
  {
    std::puts("関数のアドレスの取得に失敗しました。");
    return 0;
  }
  TConvertINetString ConvertINetString = reinterpret_cast<TConvertINetString>(proc);

  //変換準備
  DWORD mode = 0;
  AnsiStringT<932> sjis = "あいうえおかきくけこさしすせそたちつてと";
  int sjisLen = sjis.Length();
  int eucLen = sjisLen * 2 + 1;
  boost::scoped_array<char> euc(new char[eucLen]);
  ZeroMemory(euc.get(), eucLen);

  //変換
  HRESULT result = ConvertINetString(&mode, 932, 51932, sjis.c_str(), &sjisLen, euc.get(), &eucLen);
  //変換結果の検証
  if (result != S_OK || eucLen == 0)
  {
    std::puts("変換に失敗しました。");
    return 0;
  }
  //ファイルに保存
  std::unique_ptr<TFileStream> fs(new TFileStream("C:\\test.txt", fmCreate));
  fs->WriteBuffer(euc.get(), eucLen);

  return 0;
}

About 2009年07月

2009年07月にブログ「山本隆の開発日誌」に投稿されたすべてのエントリーです。過去のものから新しいものへ順番に並んでいます。

前のアーカイブは2009年06月です。

次のアーカイブは2009年08月です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。

Powered by
Movable Type 3.35