分散関数呼び出し

30分プログラム、その111。どう書く?org via id:Gemmaさんより。

mixiで、次のようなメッセージを受けとったので。

javascriptならproc.toSourceもevalもあるから、本物の分散関数呼び出しができるんじゃない?
やらないか?

使い方

こんな感じで使います。ちゃんと分散関数になってますよね。

eval_remote('http://localhost/~mzp/rpc.cgi', // ホスト名
	    f, // 呼びたい関数
	    [2000,20], // 引数
	    function(x){ // 呼び終わったあとでやるやつ
	       $('result').innerHTML = x.responseText;
	    });

ソースコード

うまく日本語を渡すことができなかったので、メッセージを適当英語に直しました。あとで、ちゃんと時間を測ってどう書く.orgに投稿するかもしれません。


クライアント側。

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <script type="text/javascript" src="js/prototype.js"></script>
    <script type="text/javascript">
      function eval_remote(url,f,args,complete){
	 var ajax = new Ajax.Request(url,
				     {method: 'GET',
				      parameters: 
				        {'f': f.toSource() , 'args':'['+args.toString()+']'},
				     onComplete: complete});
      }

      function f(x,y){
	 return 'Prices: $' + x*(1-y/100.0) + ' ($' + x + ', ' + y+'%OFF)';
      }

      Event.observe(window,'load',function(){
	 eval_remote('http://localhost/~mzp/rpc.cgi',
		     f,[2000,20],
		     function(x){
			   $('result').innerHTML = x.responseText;
		     });
      });
    </script>
    <title>RPC</title>
  </head>
  <body>
    <div id="result"></div>
  </body>
</html>

サーバ側。

#!/usr/bin/java -classpath /opt/manual/rhino/js.jar org.mozilla.javascript.tools.shell.Main

function getEnv(name){
   return java.lang.System.getenv(name);
}

function parseGET(query){
   var hash = {};
   var querys = query.split('&');

   for(var i = 0 ; i < querys.length ; i++){
      var item = querys[i].split('=',2);
      hash[item[0]] = item[1];
   };
   return hash;
}

var GET = parseGET(getEnv('QUERY_STRING'));

eval('var f=' + decodeURIComponent(GET.f));
eval('var args ='+decodeURIComponent(GET.args));

print("Content-type: text/html\n\n");
print(f.apply(this,args));