スポンサーサイト

 --------
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
カテゴリ :スポンサー広告 トラックバック(-) コメント(-)

第17回 なぜ?F12リセットでエラーが!!

 2008-11-13
今回は、F12リセットの謎を解き明かしますw

※ 11月20日 一部の説明を書き直しました。


F12でゲームをリセットすると、
SystemStackError - stack level too deep
という例外が発生したことはありませんか?

これは、メソッドの呼び出しすぎなどが原因で発生しますが、
スクリプトを見直しても原因がわからない方もいると思います。

結論から言うと、alias が原因で起こっているわけですが、どういうことか?


まず、F12リセットは現在の状態からスクリプトを
セクションの最初から読み直しているわけです。
つまり、再定義を行っているわけです。

例えば、
def method
 p "空っぽ"
end
というメソッドがあります。
そのメソッドを別名定義してあげましょう。
alias _method_ method
def method
 _method_
 p "新メソッド"
end

まぁ、大抵の場合は別名定義した後、
新しいメソッドに古いほうのメソッドの処理を加えると思います。
ちょっと、図解・・・画像にして説明すると、
SS0811124501.jpg
みなさんお気づきですか?エラーが出ませんでした。
そうです。普通は、alias を使用してもエラーは出ません。

では、どんな時にエラーがでるのか。
それは、スクリプトエディタ外で定義されたメソッドを alias した場合などです。
エディタ外定義されているものとは、Window や Sprite クラスのことです。
エディタ外のスクリプトは、読み直さないようです。
では、図解・・・いえいえ、画像にしただけの説明を見てください。
SS0811122462.jpg

他にも次のような場合にエラーが出ます。
class Hoge
 def method
 end
end
class Bar < Hoge
 alias _method_ method
 def method
  _method_
 end
end
これも上と同じ原理です。
Bar クラスのメソッドを読み込むとき、初めは、Bar クラスに method メソッドが定義されていないため
継承元である Hoge クラスの method メソッドを読み込んで別名定義しますが、
リセット後からは、Bar クラスに method メソッドが定義されてあるためそれを別名定義します。
その結果、メソッド呼び出しの無限ループが発生してしまいます。


それでは、対策方法を。
コンピュータ上には、必要なメソッドが読み込まれていますので
わざわざ2度目の定義をする必要はありません。
そこで、条件分岐して2度目の読み込みの際には、
alias を実行しないという処理をしてあげます。

alias _method_ method unless $!
という風にしてあげます。
$! というのは、組み込み変数です。
この変数には、最近起こった例外が格納されています。
また、$@ も同じようなものですので、こちらを使用しても同様の効果が得られます。

最初にスクリプトを読み込む時には、もちろん例外など起こっていません。
つまり変数の中には、nil が入っていることになります。
そこで、上記の処理にすると nil つまり false ですので、alias の処理が実行されます。

ここで、F12リセットを行うと、例外 Reset が発生します。
例外が発生すると、$! にその例外が代入されます。
Rubyでは、nil と false 以外は全て true ですので、
unless の条件を満たさず、alias の処理が実行されません。
つまり、2度目以降は別名定義しないという処理なわけです。

えっと、以上がF12リセットの真相でした。
コメント




 

 ※ コメント内にURLを含めるには、バッククォート(`)をURLの直前に付け加えてください。


管理人のみ閲覧許可 [?]

トラックバック
トラックバックURL:
http://cacaosoft.blog42.fc2.com/tb.php/121-8496cd3b
≪ トップページへこのページの先頭へ  ≫
カレンダー
03 << 2017/04 >> 05
- - - - - - 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 - - - - - -

カテゴリー
最近の記事
02/28 お返事
02/14 お返事
01/21 お返事
01/12 更新情報
11/28 お返事

最近のコメント
03/16 お返事
01/21 お返事
11/30 z座標
11/20 z座標
08/03 お返事

タグクラウド

リンク
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。