From 9ab0b1108ae3734ce40b5e2ef149a57737ebaa7b Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 23 Apr 2015 15:03:08 -0600 Subject: [PATCH] Wrap up method_missing docs and tests --- cheatsheet.md | 37 +++++++++++++++++++ .../chaiscript/dispatchkit/dispatchkit.hpp | 21 +++++++++-- unittests/dynamic_object_dynamic_attrs.chai | 6 --- unittests/method_missing.chai | 7 ++++ 4 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 unittests/method_missing.chai diff --git a/cheatsheet.md b/cheatsheet.md index 25e8806..027b91e 100644 --- a/cheatsheet.md +++ b/cheatsheet.md @@ -256,6 +256,43 @@ print(m.get_value()); // prints "Value Is: a" print(get_value(m)); // prints "Value Is: a" ``` +## Dynamic Objects + +All ChaiScript defined types and generic Dynamic_Object support dynamic parameters + +``` +var o = Dynamic_Object(); +o.f = fun(x) { print(x); } +o.f(3); // prints "3" +``` + +Implicit 'this' is allowed: + +``` +var o = Dynamic_Object(); +o.x = 3; +o.f = fun(y) { print(this.x + y); } +o.f(10); // prints 13 +``` + +## method_missing + +A function of the signature `method_missing(object, name, param1, param2, param3)` will be called if an appropriate +method cannot be found + +``` +def method_missing(int i, string name, Vector v) { + print("method_missing(${i}, ${name}), ${v.size()} params"); +} + +5.bob(1,2,3); // prints "method_missing(5, bob, 3 params)" +``` + +`method_missing` signature can be either 2 parameters or 3 parameters. If the signature contains two parameters +it is treated as a property. If the property contains a function then additional parameters are passed to +the contained function. + +If both a 2 parameter and a 3 parameter signature match, the 3 parameter function always wins. # Built In Functions diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index a1e8345..755db33 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -844,7 +844,20 @@ namespace chaiscript // 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 auto functions = [&]()->std::vector { + std::vector fs; + + for (const auto &f : get_function("method_missing")) + { + if(f->compare_first_type(params[0], m_conversions)) { + fs.push_back(f); + } + } + + return fs; + }(); + + const bool is_no_param = [&]()->bool{ for (const auto &f : functions) { @@ -856,12 +869,12 @@ namespace chaiscript }(); if (!functions.empty()) { - std::vector tmp_params(params); - tmp_params.insert(tmp_params.begin() + 1, var(t_name)); if (is_no_param) { + std::vector tmp_params(params); + tmp_params.insert(tmp_params.begin() + 1, var(t_name)); return do_attribute_call(2, tmp_params, functions, m_conversions); } else { - return dispatch::dispatch(functions, tmp_params, m_conversions); + return dispatch::dispatch(functions, {params[0], var(t_name), var(std::vector(params.begin()+1, params.end()))}, m_conversions); } } diff --git a/unittests/dynamic_object_dynamic_attrs.chai b/unittests/dynamic_object_dynamic_attrs.chai index d8a1664..aaa806f 100644 --- a/unittests/dynamic_object_dynamic_attrs.chai +++ b/unittests/dynamic_object_dynamic_attrs.chai @@ -22,12 +22,6 @@ assert_true(o.f3(4) == 60); assert_true(o.mult(3.0) == 45.0); -def method_missing(int i, string method_name, x, y) { - "method_missing called : " + to_string(i) + "." + method_name + "(" + to_string(x) + ", " + to_string(y) + ")"; -} - - -assert_true(5.bob(3,4) == "method_missing called : 5.bob(3, 4)" ) var o2 = Dynamic_Object(); o2.a = 15 diff --git a/unittests/method_missing.chai b/unittests/method_missing.chai new file mode 100644 index 0000000..69abc92 --- /dev/null +++ b/unittests/method_missing.chai @@ -0,0 +1,7 @@ +def method_missing(int i, string method_name, Vector params) { + "method_missing called : " + to_string(i) + "." + method_name + "(" + to_string(params[0]) + ", " + to_string(params[1]) + ")"; +} + + +assert_true(5.bob(3,4) == "method_missing called : 5.bob(3, 4)" ) +