#contents
*特徴などの紹介 [#t848d4e7]
DOSのコマンドでディレクトリの情報を表示するコマンドといえば、
-DIR
ですが、私のつくったPrototypeをインポートすれば、
 "DIR".exe
と書くだけでコマンドラインで実行するようなことがきるようになりますし、さらに工夫したメソッドも用意してあります。

**メリット [#e0a2df5e]
-jarファイルで圧縮していないので、自分でメソッドを増やしていくことが簡単
-Javaの標準のRuntimeメソッドではInputStreamを自動的に閉じないが、このメソッドは閉じるなど堅牢な作りにしてある。
-通常dirコマンドは "cmd /c dir"と記述しければならないが、その文字を補完するようにしている
-プロセス処理に必要なクラスのimport等を完全にカプセル化したので簡単になった。

**JavaScriptのPrototype.jsにインスパイアされて、名前をつけました。 [#e52f7ec6]


*使用例 [#u98179b9]
**ProcessMain.scala [#y0cebec9]
 package test
 object ProcessMain {
    def main(args: Array[String]): Unit = {
        //Prototype.scalaを用意した後、次の一行で呼び出す。
        import Prototype._
        println("--例1 直接こんな感じでシェルを呼び出せます。--")
        "dir ".exe //ディレクトリの情報が表示される
        
        println("--例2 値を文字列変数で取得可能です。--")
        println("dir /w".exeresult)
 
        println("--使い方3--")
        "dir /w".exe_eachLine{line =>
          	println(line)
        }
        
        "使い方4".p
        "文字列の表示はprintlnと同じ意味のpを用意しました。違いは値を返します。".p
        
        "2回表示して実行する例".p
        "echo aaaa".p.p.exe
        
        "実行ごとにプロセスが生成されるので、ディレクトリの移動は意味がありません".p
        "echo zzzz".exe
        "cd c:\\".exe
        "dir".exe
        
        println(currentdir)
        
    }
 }


**Prototype.scala [#v5fd454b]
 package test
 import java.io._
 import scala.util.DynamicVariable
 import java.lang.Process
 
 //--------------------------------
 //   Object記述部分
 //--------------------------------
  
 object Prototype {
    var currentdir = ""
	if (currentdir == ""){
 	    
	} 
    implicit def wrapBufferedReader(src: BufferedReader) = {
	    new WrapBufferedReader(src)
    }
    
    implicit def wrapString(src: String) = {
	    new WrapText(src)
    }     
 }
  
 //--------------------------------
 //   class記述部分
 //--------------------------------
  
 //BufferedReaderにeachLineメソッドを拡張する
 class WrapBufferedReader(src: BufferedReader) {
    def eachLine(f: String => Unit) {
	  var line:String = null
      while({line = src.readLine ; line != null}){
        f(line)
      }
	}
 }
  
 //Stringを拡張するメソッド
 class WrapText(string : => String){
    def gsub(pat : String,afterstring :String) :String = {
    	string.replaceAll(pat,afterstring)
    }
    
    //プロセスを実行し結果の文字列を返す。
    def exeresult() :String = {
        var p:ProcessScala =  new ProcessScala
        p.exeresult(string)
    }
    
    //実行して結果を出力する
    def exe() = {
        println(exeresult)
    }
    
    implicit def wrapArray_String(array: Array[String]) = {
	    new WrapArray_String(array)
    }  
    
    //実行して結果を出力する
    def exe_eachLine(f: String => Unit) {
      val lines = exeresult.split("\n")
      lines.each{line=>
        f(line)
      }
    }
    
    //表示println
    def p() :String = {
        println(string)
        string
    }
 }
 
 //Array[String]を拡張するクラス
 class WrapArray_String(array : Array[String]){
	def each(f: String => Unit){
	   for (item <- array){
	     f(item)
	   }
	}
 }
 
 
 class ProcessScala(charset :String) {
	val dynamicvariable= new DynamicVariable[Process](null)
 
	var stdout :BufferedReader = null;
    var stderr :BufferedReader = null;
	//var stdin :BufferedWriter = null;
  
	//デフォルトのキャラクタコードを使う
	def this() = this("")
  
	//自動的にDestroyするProcess
	def exec(cmd:String)(block : => Unit){
       var process :Process = null
	   try {
	     process = Runtime.getRuntime.exec(cmd)
	  	 stdout = getBufferdReader(process.getInputStream(),"")
	     stderr = getBufferdReader(process.getErrorStream(),"")
      
         dynamicvariable.withValue(process){block}
	   } catch {
	      //dir とか 普通に実行させたい
	      case e:java.io.IOException =>{
	        try {
		        if (cmd.length < 7 || !(cmd.substring(0,6) == "cmd /c")){
		           //cmd /cを追加してみる
		           process = Runtime.getRuntime.exec("cmd /c " + cmd)
		           stdout = getBufferdReader(process.getInputStream(),"")
		           stderr = getBufferdReader(process.getErrorStream(),"")
				   dynamicvariable.withValue(process){block}
		           //process.waitFor
		        }
	        } catch { 
	          case e =>println (cmd + " is exsits?")
	            throw e
            }
          }
	   } finally {
	     //子プロセス呼び出し後は,必ず,ストリームを閉じる
	     	if (process != null) {
		        process.getErrorStream().close();
		        process.getInputStream().close();
		        process.getOutputStream().close();
		        process.destroy();
	        }
            if (stdout != null) {
            	try {stdout.close} catch {case e:IOException => }
            }
            if (stderr != null) {
            	try {stderr.close} catch {case e:IOException => }
            }
	   }
	}
 
	//実行結果の戻り値を返します。
	def exeresult(command :String) = {
		var result = ""
		exec(command){
	      var line:String = null
	      while({line = stdout.readLine ; line != null}){
	        result = result + line + "\n"
	      }
	   }
       result
	}
 
 
    //get dynamic variable's value
    def $_()={
        dynamicvariable.value
    } 
    
    def getBufferdReader(is:InputStream, charset :String):BufferedReader = {
        if (charset == "") {
        	new BufferedReader(new InputStreamReader(is));
        } else {
			try {
				new BufferedReader(new InputStreamReader(is, charset));
			} catch {
				case e: UnsupportedEncodingException => {
					throw new RuntimeException(e);
				}
			}   
        }
    }
 }

*今後の方針 [#l7bfc640]
-問題99での回答で作成したメソッドを標準的に呼び出せるようにしておきたい。
-利用者側に極力負担がかからないようにしたい
トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS