octave-maintainers
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]