ActionScript3.0でファイル名、行番号を取得
なんか見つからない
あるぇー?おかしいな。余裕ですぐ見つかる気がしたのに。検索の仕方が悪かったかな。それとも、用意されてないということは、使う必要がないということかな?
諦めて回避策
考えても仕方がないので、自力で書くことにした。
getStackTrace
なんか意図的にスタックトレースが取れるみたい。*1
ただし、DebugバージョンのFlashPlayer限定。つまり、デバッグ目的以外には使えませんよ。と。
trace(new Error().getStackTrace());
これの出力って例えばこうなってる。
Error at test::test()[C:\Projects\AS3\ActionScriptTest\test\test\as:17] at ActionScriptTest()[C:\Projects\AS3\ActionScriptTest\ActionScriptTest.as:9]
0行目はエラーの名前とか。
1行目にErrorをnewした関数の情報。(at メソッド名[ファイル名:行番号])
2行目にその関数を呼び出した関数の情報。
3行目にさらにその関数を…と続く。
で、こいつを分解すればファイル名、メソッド名、行番号がとれる。
正規表現とか使ってこんな感じ。
// エラーを作成 var er:Error = new Error; // スタックトレースを取得 var st:String = er.getStackTrace(); // 改行コードで分割 var sts:Array = st.split("\n"); // 2番目の行(3行目)を取得(呼び出し元) var cl:String = sts[2]; // 行番号を取得するパターンを作成 var rg:RegExp = /at .+\[.+[\.|\\]as\:(\d+)\]/; // 作成したパターンをマッチ var mc:Array = cl.match(rg); // 1番目のグループの値を取得 var mcl:String = mc[1]; // intにキャスト var line:int = int(mcl); // 行番号を返す return line;
長ったらしいのでワンライナーにして、クラス化。
package lib { /// ここ!クラス public class Hear { /// ファイル名 static public function file(): String { return new Error().getStackTrace().split("\n")[2].match( /at .+\[(.+?[\.|\\]as)\:\d+\]/)[1].replace(/([\.|\\]as$)/, ".as"); } /// 短い(パスを含まない)ファイル名 static public function sfile(): String { return new Error().getStackTrace().split("\n")[2].match( /at .+\[(?:.+\\)(.+?[\.|\\]as)\:\d+\]/)[1].replace(/([\.|\\]as$)/, ".as"); } /// メソッド名 static public function method(): String { return String(new Error().getStackTrace().split("\n")[2].match( /at (.+)\[.+[\.|\\]as\:\d+\]/)[1]).replace("/", "."); } /// 行番号 static public function line(): int { return int(new Error().getStackTrace().split("\n")[2].match( /at .+\[.+[\.|\\]as\:(\d+)\]/)[1]); } } }
使うときはこうする。
package hoge { import lib.Hear; public class foo { public function bar(): void { trace(lib.Hear.sfile() + "っていうファイルの" + lib.Hear.method() + "っていうメソッド(" + lib.Hear.line() + "行目)で呼ばれたよ!"); } } }
表示はこんな感じ。
foo.asっていうファイルのhoge::foo.bar()っていうメソッド(8行目)で呼ばれたよ!
うーん。車輪の再発明のにおいがプンプンする。もっとスマートにできないものかな。