7 Running functions

Our goal is to run a R instrumented function, under a given evaluation mode.

To do so, some prerequisites have to be met, prior to use some wyz.code.offensiveProgramming utilities to proceed to the function execution with context capture and human-readable feedback generation.

7.1 Prerequisites

To run a R function, it has to be instrumented. Two requirements have to be met

  1. the function must comply with semantic parameter naming
  2. the function return type must be specified

These prerequesites might be matched in two ways depending of transient or persistent invocations.

Persistent invocation means that function return type information is stored into an object according to a convention, and therefore could be retrieved from it to be used and reused whenever and wherever needed.

7.2 Transient invocations

Transient invocation means that function return type information is is explicitely set/given at invocation time. Invocation will be achieved dynamically and not persisted anywhere. In particular invocation context remains volatile, as long as you do not save it into a piece of code.

Transient invocation is a convenient way to discover and to play with an offensive programming instrumented package.

7.2.1 Nominal case

Here is a typical to invoque an offensive programming instrumented function in a transient way. Use function runTransientFunction to achieve desired result.

To get the definition for ‘emo’ variable, please refer to 6.

Semantically, function h takes a vector of strings as argument and returns a vector of strings.

As provided parameter ‘neonira’ is a vector of type character, parameter_type_checks succeed.

As returned value is a vector of type character, function_return_type_check also succeeds.

Therefore global status is TRUE. Generally, when used to use this function, you just jump onto the status and go deeper only when negative.

7.2.1.1 Wrong parameter type

Let’s change the provided argument from ‘neonira’ to pi value.

The status is FALSE. Looking at details, we see that root causes are parameter_type_checks failure and function_return_type_check failure.

We faced a case where function specification is unchanged but provided argument is not complying to specification, thus generating a double error.

If you have a great experience of R, you know that discovering such root causes are challenging due to weakly typed and script nature of the R language.

7.2.1.2 Change expected return type

Let’s change the expected function return type, to be double x_d.

The status is still FALSE but there is now one single root cause that is parameter_type_checks failure.

We now face a case where function specification is unchanged but expected return type is expected to be a double. Provided argument is not complying to specification. To fix the issue, just rename the parameter to be x_d or any other defined and recorded factory type that matches a double.

7.2.3 Object function call

What if the function you desire to call is an object function?

In such a case, be sure to pass the object as first parameter of the list of parameters, as shown by example below, based on a S3 object. A priori, all kind of R objects are supported: S3, S4, RC, R6 and environment objects.

7.3 Persistent invocations

Transient invocations are convenient but limited. Especially, when you create classes, they do not appear to be as friendly and useful as necessary.

When dealing with your own class code, you may opt for an easier and more industrial approach that is class instrumentation. Prerequisite remains the same, but you may fulfill them much more easily by defining a variable named function_return_type in your class.

7.3.1 Verifying recorded information

To verify function return types definition of a R object, you may use the low level function verifyFunctionReturnTypesDefinition or the higher level one named retrieveFunctionReturnTypes.

7.3.6 Second call case with ellipsis

Here, ellipsis still matches all, but parameter list is type heterogeneous. This brings two issues. Value 0 is double, not integer and floor function returns also a double. To get a correct results, enforce inout parameter coercision to expected type.