JavaScriptのObject.keysを実装

投稿日:2019年04月14日 23時13分55秒

件のTinyJSについてずっと懸案だったObject.keysを実装する。

var hoge={
    "a":"abc",
    "b":"def"
};

このようなOjbectの一覧を取得するのがObject.keysである。まだTinyJSの仕様に疎いので既にあるコードを改造して出来ないかなと見ているとObject.dumpとArray.splitという関数が実装されていた。Object.dumpのコードからオブジェクトのキー一覧を取得しArray.splitと同じ方法で配列にして返せばいいんじゃない?という適当実装を進めることとする。
ついでにソースをよく見てみるとTRACEという関数があってたまに実行に失敗していることに気がついた。よく見ると#define TRACE printfってなってる。今回のサーバ仕様では標準出力へのリダイレクトではなくて、直接socketを引き回してそこへ読み書きするような仕様になってる。なのでTRACEも自前で出せるように改造する。バッファオーバーフローしないsprintfも作ってあるけど概ね固定長の文字列なのでそこまでする必要はないかと。

void TRACE( int socket, const char* format, ... )
{
    char work[1024];
    va_list ap;
    va_start(ap, format);
    vsprintf(work,format, ap);
    va_end(ap);
    send( socket, work, strlen(work),0);
}

次にキー一覧の取得だが今回作った文字列ライブラリでは\r\nで文字列を配列のように扱えるAnsiStringの仕様も盛りこんであるのでこれでぶん回す。

wString CScriptVar::trace2(void) {
wString str;
CScriptVarLink *link = firstChild;
while (link) {
    str.Add( link->name );
    link = link->nextSibling;
}
return str;
}

どうも配列もObjectもこの単純リストで管理しているようだ。普通のJavaScriptではここがHashになっていると聞く。いつの日か実装を変えよう。AddはAnsiStringでの擬似配列を作る関数で文字を返すだけで配列として使える。1時間くらい格闘して実装できた。環境変数の表示に使っている。foreach構文がないので面倒だが下記のenv.jssというサーバサイドのJavaScriptを実装できた。で囲まれた部分がJavaScriptだ。これでまた仕事が楽になった!
環境変数一覧

<?
   print( "_SERVER\n\n");
   var s = Object.keys(_SERVER);  
   for( var i=0 ; i<s.length ; i++ ){
         print( "["+s[i]+"] =>"+_SERVER[s[i]]+"\n" );
   } 
   print( "\n_GET<br/>\n\n" );
   s = Object.keys(_GET);  
   for( var i=0 ; i<s.length ; i++ ){
         print( "["+s[i]+"] =>"+_GET[s[i]]+"\n" );
   }
   print( "\n_POST<br/>\n\n" );
   s = Object.keys(_POST);  
   for( var i=0 ; i<s.length ; i++ ){
         print( "["+s[i]+"] =>"+_POST[s[i]]+"\n" );
   }
?>

[<< C,C++のインデントをPerlで]

[TinyJS(JavaScript)に正規表現を >>]