[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
value extractors for octave_value class
From: |
John W. Eaton |
Subject: |
value extractors for octave_value class |
Date: |
Wed, 11 Nov 2015 11:59:31 -0500 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Icedove/31.7.0 |
As discussed previously, I've been working on using C++ exception
handling for errors in Octave and removing the global error_state
variable. In many cases, this is trivial. For example, in (C++) code
like this
do_something ();
if (error_state)
return retval;
the check of error_state and the return statement can be removed because
instead of setting error_state when an error occurs, Octave will now
throw a C++ exception and this code will never be executed.
Other cases are a bit more complicated. There are many instances of
things like this
std::string file = args(0).string_value ();
if (error_state)
error ("foobar: FILE must be a string");
and previous versions of Octave would emit two error messages, something
like this if args(0) isn't a string:
error: octave_base_value::convert_to_str_internal (): wrong type
argument 'scalar struct'
error: foobar: FILE must be a string
Here, omitting the check on error state would eliminate the second more
helpful message leave us with only the first more cryptic message. In
an attempt to fix this problem and make extracting values in the Octave
internals a bit easier, I added a string_value function that accepts
printf-style messages so the above could be replaced by
std::string file = args(0).string_value ("foobar: FILE must be a
string");
So far, so good. Although it seems a little strange to be passing in an
error message to the value extractor, the resulting code is pretty clear
about what is happening and it is easy to write. It is certainly MUCH
easier than wrapping these value extractions in try/catch blocks!
But then I ran into trouble when attempting the same with array
extractors. First, many (all?) of them have the form
Array<double> vector_value (bool frc_str_conv = false,
bool frc_vec_conv = false) const;
or
Array<int> int_vector_value (bool req_int = false,
bool frc_str_conv = false,
bool frc_vec_conv = false) const;
When overloading these functions with (for example)
Array<double> vector_value (const char *fmt, ...) const;
some compilers complained that the overloaded function was ambiguous.
I'm not sure what is best here.
Defining the new function as
Array<double> vector_value (bool frc_str_conv, bool frc_vec_conv
const char *fmt, ...);
doesn't look good to me (since the function takes a variable number of
arguments, there is no way to make the frc_str_conv and frc_vec_conv
arguments optional).
I would rather not use different names for these functions just to avoid
that error, as it seems awkward to have to write something like
args(0).vector_value_with_msg ("foobar: FILE must be a string");
In nearly all cases, the extra arguments are not used. Rarely do we ask
the extractor function to force character strings to be converted to
numeric values or for the result to be coerced into a vector. So maybe
we should just eliminate those arguments? In the few cases where it
matters, the user could be required to force conversions or query actual
types before performing the value extraction.
Comments?
jwe