From a542ec01f695ab89118da537ca7d4917340966e0 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 22 Apr 2015 12:15:15 -0600 Subject: [PATCH] Update method_missing support to reduce exceptions --- .../chaiscript/dispatchkit/dispatchkit.hpp | 55 ++++++++++++------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index c8fdd08..a1e8345 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -831,31 +831,46 @@ namespace chaiscript if (is_attribute_call(funs, params, t_has_params)) { return do_attribute_call(1, params, funs, m_conversions); } else { - try { - return dispatch::dispatch(funs, params, m_conversions); - } catch(chaiscript::exception::dispatch_error&) { - const auto functions = get_function("method_missing"); + std::exception_ptr except; - const bool is_no_param = [&]()->bool{ - for (const auto &f : functions) { - if (f->get_arity() != 2) { - return false; - } - } - return true; - }(); + if (!funs.empty()) { + try { + return dispatch::dispatch(funs, params, m_conversions); + } catch(chaiscript::exception::dispatch_error&) { + except = std::current_exception(); + } + } - if (!functions.empty()) { - std::vector tmp_params(params); - tmp_params.insert(tmp_params.begin() + 1, var(t_name)); - if (is_no_param) { - return do_attribute_call(2, tmp_params, functions, m_conversions); - } else { - return dispatch::dispatch(functions, tmp_params, m_conversions); + // If we get here we know that either there was no method with that name, + // or there was no matching method + + const auto functions = get_function("method_missing"); + + const bool is_no_param = [&]()->bool{ + for (const auto &f : functions) { + if (f->get_arity() != 2) { + return false; } } + return true; + }(); - throw; + if (!functions.empty()) { + std::vector tmp_params(params); + tmp_params.insert(tmp_params.begin() + 1, var(t_name)); + if (is_no_param) { + return do_attribute_call(2, tmp_params, functions, m_conversions); + } else { + return dispatch::dispatch(functions, tmp_params, m_conversions); + } + } + + // If we get all the way down here we know there was no "method_missing" + // method at all. + if (except) { + std::rethrow_exception(except); + } else { + throw chaiscript::exception::dispatch_error(params, std::vector(funs.begin(), funs.end())); } } }