Hatena::ブログ(Diary)

SiroKuro Page RSSフィード

2011-02-26

業務系のJavaプログラマーが知っておくべき10個のBad Partsとその対策 - 達人プログラマーを目指して

自分はよくこうする。

try {
    Writer out = new BufferedWriter(new FileWriter("ファイル名"));
    try {
        // なんやかんや
    } finally {
        out.close();
    }
} catch(IOException e) {
    e.printStackTrace();
}

まあ、これだと結構深刻な欠点があるんだけど。

2010-11-02

SIer に足りないものは

google なり apple なり、あるいは dwango なり gree なり、技術者を大事にしている*1会社と、昔ながらの老舗 SIer では、その構成員が大分異なるんじゃないかという考えに至った。前者は社員技術者として、個人の能力依存するが一騎当千の強者を大事にする。一方後者は社員を従業員として、凡人〜秀才を多数集めて集団を形成する。

SIer の構成員は普通のサラリーマンだ。たくさん寄り添い助け合い、知恵を絞りあって普通のシステムを作る。1年や2年、あるいはもっと長い時間をかけて。

遅いことなら誰でも出来る!

20年かければ馬鹿でも傑作小説が書ける!

つまり、日本の SIer に足りないものは明白だ。

お前に足りないのはッ!情熱思想理想思考気品優雅さ勤勉さ!

そして何より――

速 さ が 足 り な い ! 

と、ここまで思考を暴走させて、意外と的を射ているなぁと思った次第。

*1:ような雰囲気のある

2010-10-02

2010-10-01

DIコンテナを作っています。相談に乗ってくれる人を探しています。

http://code.google.com/p/freja/

できることは少ないが覚えるべきことも少ない。最低限動かすなら3つだけで十分。

  1. インタフェイスと、その実装クラスを用意する
  2. 実装クラスに @Component アノテーションを付ける
  3. インタフェイスClass オブジェクトで get する
public class FrejaSample {
    public void main(String[] args) {
        Animal animal = Freja.get(Animal.class);
        animal.bark();
    }

    private interface Animal {
        public void bark();
    }

    @Component
    private static class Cat implements Animal {
        public void bark() {
            System.out.println("meow meow");
        }
    }
}

これだけ。利点は幾つか。

  1. 既存のオブジェクトに後付で DI する方法もある。テストケースへの DI も、変なクラス継承など無しにメソッド1発
  2. コンポーネントスコープが意外と豊富。メソッド呼び出し1回の間だけ生存するコンポーネントも作成できる

残念ながら、懸念点も幾つか。

  1. アノテーションだけで出来ることは、コンポーネント登録と、フィールドインジェクションのみ
  2. マイクロベンチマーク取ってみたら、速度が S2 の十分の一程度
  3. 1個の jar だけで完結させようとしたら、外部の有意義なライブラリ*1が全く使えなくなった

早くも行き詰まり感を感じていたり……スランプなのかなぁ。今の自分だけでは先に進めそうにないので、こんな変なものの相談に乗ってくれる人をさりげなく募集していたりします。

*1javassist とか aopalliance とか

2010-08-22

文法を一日ででっち上げる

やっぱり yacc は書いてて楽しいね。LR だと LL よりも素直にかけてストレスが少ない。

微調整は必要だと思うけど、まあ追々直していこう。

%{

package caitsith.parser;
import java.io.*;

public class Parser {

%}

// 構造キーワード
%token      ACTOR, PROCEDURE, VAR, IS, END
// 制御構造キーワード
%token      IF, THEN, ELSE, FOR, WHILE, DO, TRY, CATCH, FINALLY, SWITCH, CASE, ASSERT
// 制御構文キーワード
%token      INC, DEC, BREAK, CONTINUE, THROW
// 演算子
%right      ASSIGN, ASSIGN_ADD, ASSIGN_SUB, ASSIGN_MUL, ASSIGN_DIV, ASSIGN_MOD
%right      QUESTION, COLON
%left       OR
%left       XOR
%left       AND
%nonassoc   EQ, NEQ
%nonassoc   LT, LTEQ, GT, GTEQ
%left       IFNULL
%left       PLUS, MINUS
%left       MUL, DIV, MOD
%right      NEG, NOT, NEW
%token      DOT, RIGHT_ARROW, RIGHT_DOUBLEARROW
// 記号
%token      LP, RP, LB, RB, LBT, RBT, LST_LBT, MAP_LBT, SET_LBT
%token      COMMA, SEMICOLON
// 変数
%token      NAME, SELF, FIELD, JAVANAME
// リテラル
%token      SYMBOL, NUMBER, STRING, CHAR, NULL, VOID, TRUE, FALSE
// その他
%token      EOF

%%

compilationUnit:
    defActorList EOF
    ;

// アクタの定義
defActorList:
    | defActor defActorList
    ;
defActor:
    ACTOR fullname defArgument IS defProcedureListOpt END
    ;
defArgument:
    | LP RP
    | LP fieldList RP
    ;
defProcedureListOpt:
    | defProcedureListOpt defProcedure
    ;
defProcedure:
    PROCEDURE patternList IS stmtListOpt END
    ;

// 文の定義
stmtListOpt:
    | stmtList
    ;
stmtList:
    stmt
    | stmtList stmt
    ;
stmt:
    name COLON stmt
    | SEMICOLON
    | expr SEMICOLON
    | exprAssign SEMICOLON
    | expr exprList SEMICOLON
    | INC variable SEMICOLON
    | DEC variable SEMICOLON
    | INC variable COMMA expr SEMICOLON
    | DEC variable COMMA expr SEMICOLON
    | BREAK SEMICOLON
    | BREAK name SEMICOLON
    | CONTINUE SEMICOLON
    | CONTINUE name SEMICOLON
    | THROW SEMICOLON
    | THROW expr SEMICOLON
    | IF expr THEN stmtList END
    | IF expr THEN stmtList ELSE stmtList END
    | FOR name ASSIGN expr DO stmtList END
    | FOR name ASSIGN expr DO stmtList ELSE stmtList END
    | WHILE expr DO stmtList END
    | WHILE expr DO stmtList ELSE stmtList END
    | TRY stmtList CATCH name DO stmtList END
    | TRY stmtList FINALLY stmtList END
    | TRY stmtList CATCH name DO stmtList FINALLY stmtList END
    | SWITCH expr caseList
    | ASSERT expr SEMICOLON
    | ASSERT expr ELSE stmtList END
    ;
caseList:
    caseBody
    | caseList caseBody
    ;
caseBody:
    CASE pattern THEN stmtList END
    ;

// 式の定義
exprAssign:
    variable ASSIGN expr
    | variable ASSIGN_ADD expr
    | variable ASSIGN_SUB expr
    | variable ASSIGN_MUL expr
    | variable ASSIGN_DIV expr
    | variable ASSIGN_MOD expr
    ;
exprList:
    expr
    | exprList expr
    ;
expr:
    term
    | NEG expr
    | NOT expr
    | expr MUL expr
    | expr DIV expr
    | expr MOD expr
    | expr PLUS expr
    | expr MINUS expr
    | expr IFNULL expr
    | expr EQ expr
    | expr NEQ expr
    | expr LT expr
    | expr LTEQ expr
    | expr GT expr
    | expr GTEQ expr
    | expr AND expr
    | expr XOR expr
    | expr OR expr
    | expr QUESTION expr COLON expr
    ;
term:
    variable
    | SELF
    | primitive
    | LP expr RP
    | LST_LBT listElementOpt RBT
    | MAP_LBT mapElementOpt RBT
    | SET_LBT listElementOpt RBT
    | term RIGHT_ARROW name
    | term DOT name LP listElementOpt RP
    | term LBT expr RBT
    | NEW fullname LP listElementOpt RP
    | NEW javafullname LP listElementOpt RP
    ;
listElementOpt:
    | listElement
    ;
mapElementOpt:
    | mapElement
    ;
listElement:
    expr
    | listElement COMMA expr
    ;
mapElement:
    expr RIGHT_DOUBLEARROW expr
    | mapElement COMMA expr RIGHT_DOUBLEARROW expr
    ;

// 変数の定義
variable:
    name
    | field
    | javaname
    ;
fullname:
    name
    | fullname DOT name
    ;
name:
    NAME
    ;
fieldList:
    field
    | fieldList field
    ;
field:
    FIELD
    ;
javafullname:
    javaname
    | javafullname DOT name
    ;
javaname:
    JAVANAME
    ;

// パターンの定義
patternList:
    pattern
    | patternList pattern
    ;
pattern:
    primitive
    | name
    | wildcard
    | LST_LBT patternListElementOpt RBT
    | MAP_LBT patternMapElementOpt RBT
    | SET_LBT patternListElementOpt RBT
    ;
patternListElementOpt:
    | patternListElement
    ;
patternMapElementOpt:
    | patternMapElement
    ;
patternListElement:
    pattern
    | patternListElement COMMA pattern
    ;
patternMapElement:
    pattern RIGHT_DOUBLEARROW pattern
    | patternMapElement COMMA pattern RIGHT_DOUBLEARROW pattern
    ;
wildcard:
    QUESTION
    ;

// プリミティブの定義
primitive:
    SYMBOL
    | NUMBER
    | STRING
    | CHAR
    | NULL
    | VOID
    | TRUE
    | FALSE
    ;


%%
    public static void main(String[] args) throws IOException {
        FileReader source = new FileReader(args[0] );
        Scanner scanner = new Scanner(source);
        Parser yyparser = new Parser();
        try {
            yyparser.yyparse(scanner);
        } catch (Parser.yyException ye) {
            System.out.println(ye);
        }
    }
}

78 terminals, 35 nonterminals

129 grammar rules, 263 states