irpg Community
วิธีการแก้ไขเวลาสคริปต์ Error ตอนกด F12 - Printable Version

+- irpg Community (https://irpg.in.th)
+-- Forum: irpg Fabella RPG Maker Academia (https://irpg.in.th/forum-4.html)
+--- Forum: The Great RPG Maker Library (https://irpg.in.th/forum-5.html)
+--- Thread: วิธีการแก้ไขเวลาสคริปต์ Error ตอนกด F12 (/thread-674.html)



วิธีการแก้ไขเวลาสคริปต์ Error ตอนกด F12 - hengmana - 10-17-2012

บทความทั้งหมดเขียนโดย วอราม่อน
ที่มา http://community.thaiware.com/index.php/topic/331713-thaiware-rgss-scripts-library-aaneaouiaeaacai-o/page__view__findpost__p__2075141

วิธีการแก้ไขเวลาสคริปต์ Error ตอนกด F12
หลายคนอาจเคยเป็นกันน้อ ตอนที่พอกด F12 ในเกมแล้วเออเร่อ ขึ้นว่า Stack Level too deep
[Image: 8651c371ce.jpg]
ปัญหานี้ปกติเกิดขึ้นจาก การลูปสคริปต์ไม่มีที่สิ้นสุด หรือการ alias ซ้ำโดยชื่อเมธอทใหม่ที่ใช้เป็นชื่อ method ที่มีอยู่แล้ว~

การลูปสคริปต์ไม่มีที่สิ้นสุด เช่น...
[shcode=rails]def test
test
end[/shcode]
แบบนี้มันจะรันตัวเองซ้ำไปเรื่อย ๆ ทำให้สคริปต์แฮงค์ในที่สุด

การ Alias ซ้ำ
[shcode=rails]def test
p 'test'
end

def test_two
p 'test 2'
end

alias test test_two[/shcode]
ซึ่งชื่อใหม่ที่ใช้ตอนประกาศในสคริปต์ด้านบน คือ test ซึ่งเป็นเมธอทที่มีอยู่แล้ว ทำให้สคริปต์แฮงค์นั่นเอง
แต่ปกติคงไม่มีใครทำผิดพลาดจนใช้ชื่อใหม่ในการ Alias ซ้ำกับเมธอทที่มีอยู่แล้ว -___-" เพราะปกติเค้าจะใช้ชื่อ Alias แบบเฉพาะตัวกัน เพื่อป้องกันการซ้ำกับที่สคริปต์เตอร์คนอื่น Alias
เช่น...
[shcode=rails]alias old_test test[/shcode]
แบบนี้ไม่ดี เพราะอาจมีสคริปต์เตอร์อีกคน Alias ใช้ชื่อ old_test เหมือนกันแล้วสคริปต์ขึ้น Stack level too deep ได้~
รูปแบบที่ดี ควรมี ชื่อสคริปต์เตอร์ + ชื่อสคริปต์ที่กำลังเขียน + คลาสที่ alias + เมธอทที่ alias
ซึ่งไม่จำเป็นต้องตามแบบนี้ แต่แบบนี้จะป้องกันการใช้ชื่อซ้ำได้ดีครับ~^^ เช่น...
[shcode=rails]def Game_System
alias wora_abs_gamsys_ini initialize
def initialize
# Do something...
wora_abs_gamsys_ini
end
end[/shcode]
ชื่อที่ผมใช้ alias คือ wora_abs_gamsys_ini
wora คือ ชื่อผม (woratana)
abs คือ สคริปต์ที่ผมเขียนอยู่ (Action Battle System)
gamsys คือ คลาสที่ alias (Game_System)
ini คือ เมธอทที่ alias (Initialize) บางคนก็ใช้ init ครับ แล้วแต่ถนัดเลย~^^


กลับเข้าหัวข้อ... ต่อให้ป้องกันดีแล้ว ทำไมยังมีปัญหา Stack Level too deep เกิดขึ้นอีก?
นั่นก็เพราะตอนที่เรา Alias โมดูล หรือคลาสที่เรามองไม่เห็น ตอนเรากด F12 เพื่อรันสคริปต์มันจะ Alias ทับส่วนที่เรา Alias ไปแล้วครับ~
ซึ่งการ Alias โมดูลมันก็ไม่เหมือนกับการ Alias ปกติด้วยครับ แทนที่เราจะใช้แบบนี้
[shcode=rails]module RPG[/shcode]
ต้องใช้เป็น...
[shcode=rails]class << RPG[/shcode]
ตัวอย่างการ Alias (สมมตินะฮะ)
[shcode=rails]class << Audio
alias wora_audiosys_audio_seplay se_play
def se_play(*args)
p args[0] # ปรินท์ชื่อไฟล์ SE
wora_audiosys_audio_seplay(*args)
end
end[/shcode]
ถ้าทำแบบในตัวอย่างนี้ ตอนเข้าเกมครั้งแรกจะปกติดี แต่ถ้ากด F12 แล้วจะแฮงค์ทันทีฮะ
วิธีแก้ คือ ตั้งเช็คว่า method ชื่อนี้ถูกประกาศไว้หรือยัง ดังนี้...
Quote:class << Audio
alias wora_audiosys_audio_seplay se_play unless method_defined?('wora_audiosys_audio_seplay')
def se_play(*args)
p args[0] # ปรินท์ชื่อไฟล์ SE
wora_audiosys_audio_seplay(*args)
end
end
ส่วนตัวหนาคือจุดที่ผมเพิ่มเข้าไปนั่นเองครับ
method_defined?(ชื่อเมธอท ต้องเป็น String นะ) จะคืนค่ามาว่าเมธอทชื่อนั้นถูกประกาศไปหรือยัง?

ทว่า... ถ้าเกิดกรณีที่ Alias เมธอทนอกคลาสหรือโมดูล เช่น~
[shcode=rails]alias wora_preload_loaddata load_data
def load_data(*args)
p args
wora_preload_loaddata(*args)
end[/shcode]

load_data นี่เป็นเมธอทที่อยู่ในคลาสไหนไม่รู้ - -" แต่ตอนเราเรียกใช้ แค่พิมพ์ load_data ไปธรรมดาครับ~

วิธีการ Alias คลาสประเภทนี้ไม่ให้แฮงค์ก็คือ...
เติม unless $@ เข้าไปหลังบรรทัดนั้นครับ เราใช้ method_defined? ไม่ได้เพราะมันอยู่นอกคลาส TwT

$@ ถ้าจำไม่ผิดมันคือ Error Position หรืออะไรประมาณนั้นน่ะครับ ยอมรับว่าไม่รู้เหมือนกันว่ามันคืออะไรกันแน่ แต่มันจะคืนค่า true แค่ตอนที่รันเกมครั้งแรกเท่านั้นครับผม~^^

------------------------------------------
จบล่ะ -___________-/ บทความครั้งนี้ออกจะเป็นสคริปต์ขั้นสูงไปนิด แต่หลาย ๆ ท่านที่เกมพอกด F12 แล้วค้างก็คงรู้กันแล้วนะฮะว่าปัญหามาจากอะไร


RE: วิธีการแก้ไขเวลาสคริปต์ Error ตอนกด F12 - Neoz Kaho - 10-20-2012

ภาพแรกเจ๊งนะฮะ ฝากแก้ด้วย