2012年7月24日火曜日

あ、300件超えてた

いつの間にやら投稿件数が300件を超えていました。

あと65件で1年分か…

長いような、短いような…

とにかく、
マイナー路線一直線で400件目も目指します。

Eclipse BIRT vs Jasper Report

レポーティングツールはいくつかありますが、
Javaですぐに使えそうなのは表題の2つではないでしょうか?

今まではJasper Reportを使っていたのですが、
最近はBIRTの方がいいじゃないかと思っています。

理由はいくつかありますが、

まずは必要なライブラリが少なくて分かりやすい点です。
Jasper Reportは最小限ってだけでも結構なjarファイルを要求されます。

そしてレポートテンプレートの開発ツールです。

どっちもeclipseのプラグインが提供されていますが、
eclipseと仲がいいのは断然BIRTです。

基本的に経験の有無はそれほど加点対象には含めないので、
BIRTかな~っと思うわけなんです。



…なんてあれこれ言ってますが、
仕事場ではそれを扱うであろう部署のレベルの関係で使われないだろうという皮肉。


同ブラウザで挙動が違うのはやめてケロ

対象ブラウザがIE8のWebサイト構築を仕事で行いました。

普段はlocalhostで試験をしていて、
終盤になってIPアドレスのURLに切り替えたときです。

レイアウトが崩れている!?

ブラウザが違うなら分かりますが、
同じブラウザで!?

調査を進めた結果、
ドキュメント互換性の定義
ということでlocalhostだとレンダリングエンジンに違いがあるということです。

とりあえず時間も無いので、
metaタグ使って同じレンダリングエンジンを使うように指定しました。

この仕様は…どうなんでしょう?

引っかかる人結構居るのでは?

それともWebデザイナーにとっては常識?

う~む…


2012年7月12日木曜日

標準出力をJUnitでテストするには

久しぶりにソースを公開してみます。

標準出力に結果を出すプログラムをJUnit 4.1でテストする方法とかで解説されていますが、
それを汎用的にしてみました。

名付けて、StandardOutputSnatcherクラスです。
略してSOS!

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

/**
 * 標準出力・標準エラー出力の出力先を奪うクラスです.
 * テストなどでコンソール出力の内容を知りたい場合に使います.
 * このクラスはスレッドセーフではありません。
 * マルチスレッド環境では利用しないでください。
 */
public final class StandardOutputSnatcher  {

    /** シングルトンパターンのためのインスタンス. */
    private static final StandardOutputSnatcher INSTANCE =
        new StandardOutputSnatcher();

    /** 元の標準出力. */
    private PrintStream nativeOut = null;

    /** 元の標準エラー出力. */
    private PrintStream nativeErr = null;

    /** 変更後の標準出力. */
    private ByteArrayOutputStream snatchedOut = new ByteArrayOutputStream();

    /** 変更後の標準エラー出力. */
    private ByteArrayOutputStream snatchedErr = new ByteArrayOutputStream();

    /** 奪取済みフラグ. */
    private boolean stealFlag = false;

    /** デフォルトコンストラクタの禁止. */
    private StandardOutputSnatcher() { }

    /**
     * このクラスのインスタンスを取得します.
     * このクラスはスレッドセーフ化しにくい形で標準出力に干渉するので、
     * シングルトンパターンを採用しました.
     * @return インスタンス
     */
    public static StandardOutputSnatcher getInstance() {
        return INSTANCE;
    }

    /**
     * 出力先を奪い、
     * コンソールからこのクラスへ出力するように設定します.
     */
    public void snatch() {
        // ダブルスティールの禁止
        if (!stealFlag) {
            nativeOut = System.out;
            nativeErr = System.err;
            System.setOut(new PrintStream(new BufferedOutputStream(snatchedOut)));
            System.setErr(new PrintStream(new BufferedOutputStream(snatchedErr)));
            stealFlag = true;
        }
    }

    /** 標準出力をクリアします. */
    public void clearOutput() {
        changedOut.reset();
    }

    /** 標準エラー出力をクリアします. */
    public void clearErrorOutput() {
        changedErr.reset();
    }

    /**
     * 標準出力の出力内容を取得します.
     * @return 標準出力の出力内容
     */
    public String getOutput() {
        System.out.flush();
        return snatchedOut.toString();
    }

    /**
     * 標準エラー出力の出力内容を取得します.
     * @return 標準エラー出力の出力内容
     */
    public String getErrorOutput() {
        System.err.flush();
        return snatchedErr.toString();
    }

    /**
     * 奪取した標準出力先を取得します.
     * @return 奪取した標準出力先
     */
    public PrintStream getNativeOutputStream() {
        return nativeOut;
    }

    /**
     * 奪取した標準エラー出力先を取得します.
     * @return 奪取した標準エラー出力先
     */
    public PrintStream getNativeErrorOutputStream() {
        return nativeErr;
    }

    /**
     * 出力先を元に戻します.
     * このメソッドの呼び忘れにご注意ください.
     */
    public void release() {
        // ダブルリリースの禁止
        if (stealFlag) {
            clearOutput();
            clearErrorOutput();
            System.setOut(nativeOut);
            System.setErr(nativeErr);
            stealFlag = false;
        }
    }

}

JUnitではないですが、
使い方はこんな感じです。

StandardOutputSnatcher sos = StandardOutputSnatcher.getInstance();
System.out.println("開始");
sos.snatch();

// 標準出力
System.out.print("標準出力テスト");
if (sos.getOutput().equals("標準出力テスト")) {
    sos.getNativeOutputStream().println("標準出力テスト成功!");
}

// 出力内容のクリア
sos.clearOutput();

// 標準出力(2回目)
System.out.print("標準出力テスト2");
if (sos.getOutput().equals("標準出力テスト2")) {
    sos.getNativeOutputStream().println("標準出力テスト2成功!");
}

// 標準エラー出力
io.clearErrorOutput();
System.err.print("標準エラー出力テスト");
if (sos.getErrorOutput().equals("標準エラー出力テスト")) {
    sos.getNativeOutputStream().println("標準エラー出力テスト成功!");
}

// 出力内容のクリア
sos.clearErrorOutput();

// 標準エラー出力(2回目)
System.err.print("標準エラー出力テスト2");
if (sos.getErrorOutput().equals("標準エラー出力テスト2")) {
    sos.getNativeOutputStream().println("標準エラー出力テスト2成功!");
}

sos.release();
System.out.println("終了");

ちなみにLog4jの出力テストにも使えることにお気づきでしょうか?
そうです、ConsoleAppenderで出力すれば、
Log4jで出力した内容をStringで取得できるのです。

適当にコピー&ペーストでお試しあれ。
…ちゃんと意味を理解したうえでね。

2012/07/08追記:微妙に修正

初心者税を踏み倒しているかい?

ハッカーに伝わる格言として、
「技術さえあればタダ」
というのが隠れて存在しているような気がします。

技術を磨けば磨くほど、
少ないコストで何かを為せる可能性が高まるということです。

そして技術が無い者は、
お金を支払うことでその差分を埋めます。

自分はこれを初心者税(Beginner's Tax)と呼んでいます。

技術の無い企業が大金を支払ってソフトウェアを作ってもらうのは、
この初心者税がとんでもなく高いからです。
追記:なぜか作っているSIerも初心者税を払っているので、その分上乗せされて(ry

大規模だからだと言っていますが、
本当に大規模な開発にする必要があるのでしょうか?

関わっている人達が全員バカなだけで、
効率の良い方法に気がついていないだけなのでは?

初心者税の割合を計算することができれば、
どれだけボッタクリなのか説明することができるのですが…

コミュニケーション能力がうんぬんって言う人達は、
これの踏み倒し方が上手いからなぁ…


2012年7月5日木曜日

意外と紙は手放せない

最近は電子書籍が色々と騒がれていますが、
自分は今のところ食わず嫌いでどうにも好きになれていません。

いや、可搬性の高さは疑いようもありません。
魔術師本やドラゴンブックなんて電車の中で読むのは不可能です。

本棚もよくこれほど買ったものだと感心してしまいます。
ああ、認めます。
そのうちの大半は再読する可能性が極めて低いです。

でも、
それでも、
自分は紙が好きなんです。

あのページをめくる感触が、
インクの眼への優しさが、
読み終えた後の本の重みが…

とにかく読んだという実感が!

まだ電子書籍では再現できないのです。


普段はインターネットで何でも調べられると息巻いてますが、
重要な情報はその実感を得る為に紙へ戻ります。
(つまり読み切りなら電子書籍の方が良いですな。)

IT系って呼ばれる人達には、
同じ考えの人が多い気がしませんか?(自分の幻覚?)

ヒートアップしているのは、
非IT系の方が多かったりしませんか?


最も紙から遠くあるべき人種が、
最も紙のありがたみを知ってたりして…






という妄想。



2012年7月4日水曜日

ビジュアルプログラミング言語はやっぱりダメだ

仕事でビジュアルプログラミング言語を使っているのですが、
効率よく開発するにはどうしたら良いか試行錯誤したわけです。

それでこの前完成形の設計ができたのですが、
処理の大半をJavaScriptで書くことで効率化を図るという形になったのです。

GUI操作だとどうしても生産性が下がるため、
生産性を上げるためにはGUIの比率を下げるのが一番効果的なのです。

でもそれは、
ビジュアルプログラミング言語=効率が悪い
という図式を認めることにも等しいわけです。

趣味でやる分には一向に構いませんが、
仕事で使うには疑問を持たずにはいられません。


経営者たちは、
生産性を下げてでも、
初心者が使えることを重視しているということなんでしょうか?


人件費が増える要因なのは明らかなんですが…


本当に経営者は分かってないのでしょうか?

2012年7月3日火曜日

何よりも近く、限りなく遠い世界

こんな記事を見つけました。
IT企業の東京進出とブラック化

んで、その話題となった企業の返答記事がこちら。
リスクばかりを並べても、何も実らない。

ふたつの記事を読んで、
よく考えてみてください。

お互いの主張はどちらも正しく見えます。

しかしふたつを衝突させると、
水と油のように反発し、
矛盾となってあふれています。

自分はJavaBlackさんの主張がすごく身近に感じられますが、
だからと言ってtomoyaさんが嘘を言っているようには見えないのです。


…もしかして、全く別の世界について話していませんか?


この業界、同じに見えて平行世界レベルで食い違う5つの世界が存在するからです。


カテゴリーで表現すれば、
JavaBlackさんはインターナル界の話をしています。
tomoyaさんはパッケージ界の話をしています。


世界が違うから、
根本となる前提から食い違っていたのではないでしょうか?




そして自分もインターナル界の住人です。


人月システムによって、
スキルが上がるほど評価が下がる世界です。


自分個人としては、
パッケージ界へ移転するための準備を少しずつ進めている最中です。

既に移転した人もいます。

以下の記事などはその良い例です。
アマゾンにおけるソフトウェア開発の仕事について感じたこと

パッケージ界は甘くはないですが、
少なくともスキルの上昇によって評価が下がるようなことはありません。

SIerの上位1~2割のプログラマーは、
パッケージ界へ移転できるのではないでしょうか?
(自分が上位1~2割に入っているかは微妙ですけどね…)

そして上位陣が消えたインターナル界を、
滅ぼすことも可能なのではないでしょうか?
(新人が誤ってインターナル界に入らないようサポートする必要はありますけど。)

インターナル界の未来を嘆くのであれば、
インターナル界を捨ててしまいましょう。



…そういえば、元は移転の話でしたっけ。

自分なら京都に移転できないか考えると思います。

京都には京都大学があります。

京都大学にはSICPが講義として存在する(日本では)数少ない大学です。

京都大学の成績優秀者をインターンシップに誘い、
継続的な人材の確保を狙うわけです。

単純に人口密度が高さだけを考えるよりかは良いと思うのですが…
皮算用なんでしょうかね?


2012年7月2日月曜日

iKnowを始めてみた

ちょっとキッカケがあったので、
iKnowを初めてみることにしました。

まだ一番簡単なコースの序盤なので、
知らない単語は全く登場していません。

中学英語の復習をしている気分で、
少しだけ気持ちが弾みます。

英文を読むためにはず~っと先のレッスンまで攻略する必要がありますが、
千里の道も一歩からです。

これで年6000円はお買い得だと思います。
※キャンペーンは今日までらしいので、明日からは割引がないですよ。

英語の必要性を痛感している方がいれば、
一緒に勉強してみませんか?


2012年7月1日日曜日

これだけで満腹なスイーツ(笑)

難易度が低くてちょうど良い…ん?

混ぜるだけのスイーツの方がもっと楽だろうに。

フルー○ェとか…

何で火を使う手間をかけてまで作ってしまうのか…

満腹で動けなくなるし…

ぐ…寝ては、いけない。