Well, i've thought of a few ways to allow localized overriding of
values returned by functions in case of an error.

I have yet to figure out what the exact advantages are of this
code-standard, but the overhead seems acceptable and i recon this,
when done, will beat the "trigger_error()-try-catch" paradigm.
I'd like to hear your comments.

// imo unsafe & prone to fatalities:
$r = funcA ( funcB ( funcC ($p) ), funcD ($q) );

// "safe"; make all notices, warnings and errors from any level
// in the call-chain fully visible, identifiable, and "survivable/fudgeable"
// by code at (all) higher levels in the call-chain.
// [disclaimer] the code below here doesn't pass 3rd-level (funcC())
// (meta-)results back to the first level (funcA()) yet, but this code
// is a start towards that;
$r = funcA (defaults(array(0=>'[funcB failed]',1=>'funcD failed'))),
        funcB (defaults($onError_cCallvalue),
                funcC (defaults($onError_pValue), $p)
        ),
        funcD (defaults($onError_qValue), $q)
);

function funcA ($defaults, $returnedByFuncB, $returnedByFuncD) {
        $returnedByFuncB = workWith ($defaults, $returnedByFuncB, 0);
        $returnedByFuncD = workWith ($defaults, $returnedByFuncD, 1);
        //all parameters (with idx>0) are meta-arrays containing the
"parameter-value" and all meta-info.
        // workWith() always returns the actual parameter-value in 
$p['workValue'];

        //if any parameter $p (with idx>0) is not a meta-array,
        //      workWith($d, $r, $n) turns it into a meta array(
        //              'workValue' => $p
        //      );

        //if a param is a meta-array $p, and it contains an ['errors'] subarray,
        //      workWith() sets by-reference $p['workValue'] to one of these
(order of trying):
        //              $defaults['onError'][$n] (localized override)
        //              $p['onErrorDefault'], (functions own default value for 
when an
error occurs)

        //first call to workWith(,,0) will call beginErrorContext()

        //beginErrorContext() will increase a global idx $callID (int),
        //  used to list all notices, warnings and errors, and their details in
        //      the global variable $callsErrors[$callID][$errorIdx++] = array(
        //              'errorMsg' => 'for coders'
        //              (optional:)'userErrorMsg' => 'for laymen'
        //              'backtrace' => array(....)
        //      )

        // the never-fatal error handler specified with set_error_handler() will
        //      call getDebugInfo() and append full error info into
        //      $callsErrors[$callID][$errorIdx++]





        //forwardDefaults() clones all meta-details for
        //      re-used parameters into a new $defaults array to be used
        //      by funcE().
        //the 2nd parameter for forwardDefaults lists which parameter
        //      passed deeper refers to which parameter received by this here 
function.
        //the 3rd parameter for forwardDefaults is used to specify new defaults.
        $returnedByFuncF = funcF('blablasetting');
        $x = funcE (
                forwardDefaults($defaults, array(0=>0,2=>1), array(1 => 
'defaultblabla')),
                $returnedByFuncB, $returnedByFuncF, $returnedByFuncD
        );
        return goodResult($x);
}

function funcE ($defaults, $returnedByFuncB, $returnedByFuncF,
$returnedByFuncD) {
        $returnedByFuncB = workWith ($defaults, $returnedByFuncB, 0);
        $returnedByFuncF = workWith ($defaults, $returnedByFuncF, 2);
        $returnedByFuncD = workWith ($defaults, $returnedByFuncD, 2);

        // do a call that might raise E_WARNINGS or other crap;
        // safeCall() is only a try-except struct to call in this case
        // str_replace('xx','yy', ...) and if it fails,
        // return the default instead of the actual result.
        $x = safeCall (
                defaults('returnedByFuncB not a string'),
                'str_replace', 'xx','yy',$returnedByFuncB
        );


        if (is_string($returnedByFuncB) && is_string($returnedByFuncD)) {
                return goodResult (
                        $returnedByFuncB . $returnedByFuncD . $x
                );
                // goodResult() and badResult() will both call
                //      endErrorContext(), and copy the errors in
                //      $callsErrors[$callID]
                // to the array returned to the calling function.

                // goodResult() and badResult() will call processErrors(),
                //      which is repsonsible for mailing / db-storage of any
                //      notices, warnings, errors, etc.

        } else {
                //      badResult() will call getDebugInfo() to include
                //              a full trace, superglobals, lotsa details.
                return badResult (array(
                'errorMsg' => 'params 1 and 2 must be strings'
                'onErrorDefault' => ''
                ));
                //shorthand of the above:
                return badResult ('params 1 and 2 must be strings', '');
        }
}


function defaults () {
        $r = array (
        'isMetaForFuncs' => true
        );

        if (func_num_args()==1) {
                return array_merge_recursive ($r,
array('onError'=>array(0=>func_get_arg(0))));
        } else {
                switch (func_get_arg(0)) {
                case 'onError':
                        $p = func_get_arg(1);
                        if (is_array($p)) {
                                return array_merge_recursive ($r, 
array('onError'=>$p));
                        } else {
                                return array_merge_recursive ($r, 
array('onError'=>array(0=>$p)));
                        }
                        break;
                }
        }
}


I also considered the following constructs but rejected them for
clumsiness (first) or sheer uselessness (2nd).

  $r = funcA ($bcalldef, funcB($ccalldef, funcC ($pdef, $p)),
$dcalldef, funcD($qdef, $q));

  $r = funcA ( funcB ( funcC ( $p ) ), funcD ($q), array (
    'isMetaForFuncs' => true,
    0 => array (
      'onError' => $bCallDefaultOnError,
      0 => array (
        'onError' => $cCallDefaultOnError,
        0 => array (
          'onError' => $pDefaultOnError,
        )
      )
    ),
    1 => array (
      'onError' => $qDefaultOnError
    )
  );

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to