2011-10-18

Dartの興味深い機能

named parameterとnamed argument

void f( int x, [ int y = 0, int z = 0 ] ) { }

void main()
{
    f( 0 ) ; // f( 0, 0, 0 )
    f( 0, 1 ) ; // f( 0, 1, 0 ) 
    f( 0, z : 1 ) ; // f( 0, 0, 1 ) 
}

まあ、コードを読めば一目瞭然の機能だろう。省略可能なのは、named parameterだけである。名前を指定できるのも、named parameterだけである。normalFormalParameterは省略も名前指定もできない。

noSuchMethod

class X
{
    void noSuchMethod( String function_name, List args )
    {
        print("$function_name") ;
        for ( var elem in args )
        { print("$elem") ; }
    }
}

void main()
{
    X x = new X() ;
    // 関数名と実引数が表示される
    x.f() ; 
    x.hoge(1,2,3,4,5) ;
    x.fuga("All base is belong to us.")
}

これは解説が必要だろう。もし、クラスからメソッド名のlookupに失敗した場合、そのクラスからnoSuchMethodという名前のインスタンスメソッドが探され、第一引数としてメソッド名を、第二引数として、実引数のリストを渡し、呼び出されるのだ。もし、noSuchMethodという名前のインスタンスメソッドがなければ、NoSuchMethodExceptionが投げられる。

ということはだ、noSuchMethodというインスタンスメソッドを定義していれば、あたかもoperator .を定義したかのように振る舞うのだ。もちろん、実際にはoperator .はないし、メソッド呼び出しにしか適用できないが、DSLオタクは歓喜するだろう。

typedef

typedef int func_type(int) ;

void f( func_type func )
{
    int x = func( 0 ) ;
}
main()
{
    f( (int x) => x + 1 ) ;
}

typedefは、静的型の別名を定義するための構文である。現在のところ、関数の静的型の別名を定義することしかできない。

これはなぜかというと、関数は、具体的な静的型を直接に指定するのは面倒なのだ。こんなふうになってしまう。

void f( int func(int) ) { }

インターフェースFunctionはあるが、あまりにアバウトすぎる。だから、厳密な静的型を意味する識別子を定義するために、このtypedefが存在する。

べつに、これを使う必要はない。たとえば、varで受けても問題ない。DartはOptional Typeを採用しているからだ。静的型は実行時には、ほとんど意味がない。

No comments: