Function nesting

From Remeis-Wiki
Revision as of 14:23, 11 April 2018 by Stierhof (talk | contribs) (copy from old wiki)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
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));
g();
_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));