Implement option explicit for dynamic objects.

Closes #218
This commit is contained in:
Jason Turner
2015-10-16 21:41:54 -06:00
parent 882cbf2dfb
commit 7ba7b81a5c
4 changed files with 49 additions and 6 deletions

View File

@@ -354,6 +354,18 @@ o.f = fun(y) { print(this.x + y); }
o.f(10); // prints 13
```
### Option Explicit
If you want to disable dynamic parameter definitions, you can `set_explicit`.
```
class My_Class {
def My_Class() {
this.set_explicit(true);
this.x = 2; // this would fail with explicit set to true
}
};
## method_missing
A function of the signature `method_missing(object, name, param1, param2, param3)` will be called if an appropriate

View File

@@ -1002,12 +1002,17 @@ namespace chaiscript
}();
if (!functions.empty()) {
if (is_no_param) {
std::vector<Boxed_Value> 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, {params[0], var(t_name), var(std::vector<Boxed_Value>(params.begin()+1, params.end()))}, m_conversions);
try {
if (is_no_param) {
std::vector<Boxed_Value> 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, {params[0], var(t_name), var(std::vector<Boxed_Value>(params.begin()+1, params.end()))}, m_conversions);
}
} catch (const dispatch::option_explicit_set &e) {
throw chaiscript::exception::dispatch_error(params, std::vector<Const_Proxy_Function>(funs.second->begin(), funs.second->end()),
e.what());
}
}

View File

@@ -24,6 +24,16 @@ namespace chaiscript
{
namespace dispatch
{
struct option_explicit_set : std::runtime_error {
option_explicit_set(const std::string &t_param_name)
: std::runtime_error("option explicit set and parameter '" + t_param_name + "' does not exist")
{
}
virtual ~option_explicit_set() CHAISCRIPT_NOEXCEPT {}
};
class Dynamic_Object
{
public:
@@ -79,11 +89,19 @@ namespace chaiscript
Boxed_Value &method_missing(const std::string &t_method_name)
{
if (m_option_explicit && m_attrs.find(t_method_name) == m_attrs.end()) {
throw option_explicit_set(t_method_name);
}
return get_attr(t_method_name);
}
const Boxed_Value &method_missing(const std::string &t_method_name) const
{
if (m_option_explicit && m_attrs.find(t_method_name) == m_attrs.end()) {
throw option_explicit_set(t_method_name);
}
return get_attr(t_method_name);
}

View File

@@ -760,6 +760,14 @@ namespace chaiscript
{
}
dispatch_error(std::vector<Boxed_Value> t_parameters,
std::vector<Const_Proxy_Function> t_functions,
const std::string &t_desc)
: std::runtime_error(t_desc), parameters(std::move(t_parameters)), functions(std::move(t_functions))
{
}
dispatch_error(const dispatch_error &) = default;
virtual ~dispatch_error() CHAISCRIPT_NOEXCEPT {}