yonet77的な雑記帳

日々思いついたネタなどを書き留めておきます

Schema Namespace について

そろそろForce.comのバージョンもWinter' 14になる季節となりました。(あぁ!更新試験....)
それに先立って、ApexのリファレンスもVersion 29.0 となってますね。それにしても、v29.0になってリファレンスの構成も大幅に見直した模様で、v28.0までに慣れていると、欲しい情報がどこにあったかなーとすぐに見つけられません。。(まぁ、そのうち慣れるでしょう、ということで。)


さて、Reference Guideの章をみると、やたらと

〜 Namespace

とネームスペース名がついて説明されるようになってます。いよいよネームスペースを定義できるようになる日が近いのかな?と期待させるような展開ですねw
とにかくApexクラスファイルをフラットに管理するのをなんとかして欲しい

この中で、Schema NamespaceというNamespaceがありますが、先日、ココに書かれてない内容を知る機会がありました。


Account という名のApexクラス

Force.com では、Apexクラスの名前に標準オブジェクト名を付けることも可能ですし、その他標準で用意されているクラスの名前(SelectOptionとか)も可能です。そんなわけで、例えば"Account"という名前のApexクラスも作ることができます。

そういったApexクラスを作ったときに何が困るの?というハナシですが、こんなところで困るハメになります。

public class Account {
    public Account(){

    }
}

//----------------------------
// Execute Anonymous..
//----------------------------
Account acc = new Account();
insert acc;
// -> line 2, column 1: DML requires SObject or SObject list type: Account

Account acc = new Account(Name='Test Account');
insert acc;
// -> line 1, column 15: Invalid constructor syntax, name=value pairs can only be used for SObjects

Account acc = [Select Name From Account limit 1];
// -> line 1, column 1: Illegal assignment from LIST to Account

なんとッ....!自前で作ったAccountクラスを参照してしまい、標準オブジェクトのDMLやSOQL文がエラーとなってしまうのです。。
思わず

なっ!何をするだァーーーッ!ゆるさんッ!

ジョナサン・ジョースターばりに怒りを爆発させてしまいそうです。


Schema Namespace...だと!

そんなところに救世主が。

S...Schema Namespaceがそんなところにも使えるとは!
というわけで、試してみると...

Schema.Account accs = [Select Name From Account limit 1];
System.debug(accs.Name);
// -> 00:44:05:031 USER_DEBUG [2]|DEBUG|University of Arizona

Schema.Account acc = new Schema.Account(Name='TestAccount');
insert acc;
System.debug(acc);
// -> 00:47:37:613 USER_DEBUG [3]|DEBUG|Account:{Name=TestAccount, Id=0011000000cmMVvAAM}

ブラボー!おお・・・ブラボー!!

公開しているApexリファレンスには記載されていないのですが、確かにSchema Namespaceを使えば、上記の問題は解決されるというワケです!
これ、リファレンスにもちゃんと記載するべきなのでは・・?と思う今日この頃


良い子はマネしない

しかしそれでも完璧....ではないのが世の常。

【注意!!】URLは危険なパッケージのインストールURLですので、開く際には捨てても良いDev環境を準備してから、でお願いします

相変わらずデストロイヤーな @mino0123 さんの危険なパッケージをインストールすると、

public class Schema {
    private Schema(){}
    @isTest
    private static void test() {
        Schema instance = new Schema();
    }
}

という危険なクラスが定義されていて、こうなると前述した"Schema.Account"も役に立たない。
見事なまでに破壊してくれます。そんなステキなパッケージ名は

BreakApex


というわけで、 @mino0123 先生の次回作に期待しつつ、Schema namespace の意外な使い方をおしまいにしたいと思います。


補足 (2013/10/07 追記)

@mino0123 先生からのコメントです。

try{
    Integer a = 10;
    Integer b = 0;
    System.debug(a/b);
}catch(MathException ex){
    System.debug('--- This is Test---');
}
// ->
//15:35:11.036 (36980000)|EXCEPTION_THROWN|[4]|System.MathException: Divide by 0
//15:35:11.037 (37168000)|HEAP_ALLOCATE|[4]|Bytes:15
//15:35:11.040 (40311000)|FATAL_ERROR|System.MathException: Divide by 0

確かにCatchされないッ...!
(MathException -> Exceptionにすれば、さすがにCatchしてくれるけど...いい感じの破壊っぷりでした。)