The Crystal Programming Language Forum

Wow, the inner function's raise exception is caught from the outer function

Okay I was just about to ask a question on how to get this to work. But I figured it out on my own! I’m so happy :D. I could have sworn I tried this last year, but anyway:

def use_skill(t)
  
  if t == "Melee"
  	# bunch of code here
  	assert_weapon_required()
  	# bunch of code here, etc, etc
  	# code here, blah blah more asserts and checks, etc
  
  	puts "Ready to use the skill!"
  	
  end

rescue e
pp "Error using a skill: #{e.message}"
end


def assert_weapon_required()
	raise "Weapon not found"
end


use_skill("Melee")

This works perfectly. Instead of returning false within assert_weapon_required, I can just call a raise. And assuming if that raise is rescued, it acts just like an inline assert that stops the execution of code. For example, I don’t want any code below assert_weapon_required() to execute (if it fails).

This helps so much, because instead of having 5-7 extra lines of code from assert_weapon_required, I can just use 1 line (assert_weapon_required), and keep going. Makes the control flow and readability so much nicer, I love it.

It will help so much, because there are going to be a lot of asserts that have to be done. Here is a real world example and it’s already looking much nicer:

Gosh I love crystal

Note that raising exceptions is pretty slow process, so don’t use it for control flow in performance-critical code.

My gameserver code is littered with raises. I love exceptions. But I don’t know if it’s “performance-critical” lol