Function nesting

From Remeis-Wiki
Jump to navigation Jump to search

Function nesting (or functions define functions) is, in principle, not possible:

define fun() {
  define fun2() { return 5; };
  return fun2();

This approach results in an error. But one can may use "eval" to define a nested function:

define fun() {
  eval("define fun2() { return 5; };");
  return eval("fun2()");

The nested function can also be made private.

In that way, functions can be defined dynamically during runtime. However, there are some disadvantages one should be aware of:

  • The "eval"uated string is parsed by the S-lang interpreter only during the call of eval. That means syntax errors are not detected beforehand, which could unnecessarily crash your script!
  • Never ever pass external input into eval-statements -- at least not directly, but best not at all! If not handled properly, malicious code can be injected into your process or script, which is a known computer attack (see also this article)

Note that the function defined in the eval-Statement is by no means "nested" (in the sense of: "internal to the function"), as the following example illustrates:

define f(x)
  if(x == 0)
    eval("define nested() { return 42; }");
  return eval("nested()");

define g()
  eval("define nested() { return `f's 'nested' function was hijacked by g`; }");

variable x;
_for x (0, 2) vmessage("f(%d) = %S", x, f(x));
_for x (3, 5) vmessage("f(%d) = %S", x, f(x));
define nested() { throw DataError; }
_for x (6, 9) vmessage("f(%d) = %S", x, f(x));