Jump to content

Closures and Pre and Post Return Processing


WhIteSidE

Recommended Posts

While working on a project the other day, something came up that got me to thinking about the use of closures to simplify various debugging and other "academic" questions about how function calls are made.

 

Consider a function which has a big, nasty, ugly logic tree, with many return statements. As the function executes a different branch will be executed. Thus, if I am worried about what the function is returning (if I want to log it for instance), I need to either (a) Write some logging code in the calling function, (b) Write and invoker function or © Use some method to "catch" the return inside the function.

 

For an example class MyClass:

class MyClass {

     function MyClass()  {
     }

     function Method($input) {
          if($input===false) {
               return 'FALSE';
          }
          if($input=='Hello') {
               return 'GREETING';
          }
     }

}

 

To execute logging method a, then, in my code I would write:

$myclass = new MyClass();
$returnValue = $myclass->Method('Hello');
Logger::log($returnValue);
doSomething($returnValue);

 

This has the unfortunate side effect, however, that I need to log wherever I use the code, and cannot simply call the function.

 

Another way to do this would be to use a helper, or 'invoker' method:

class MyClass {

     $_logReturn;

     function MyClass($logReturn=TRUE)  {
          $_logReturn=$logReturn;
     }

     public function Method($input) {
          $returnValue = $this->_Method($input);
          if ($_logReturn) Logger::log($returnValue);
          return $returnValue;
     }

     private function _Method($input) {
          if($input===false) {
               return 'FALSE';
          }
          if($input=='Hello') {
               return 'GREETING';
          }
     }

}

 

Now from my calling function, I simply write:

$myclass = new MyClass();
doSomething($myclass->Method('Hello'));

 

Now, method b isn't entirely terrible, although it would be really tedious for a huge class to write a real and helper function for each method. Closure to the rescue. Modify MyClass to look something like this:

class MyClass {

     $return

     function MyClass($logReturn=TRUE)  {
          $ret = function ($returnValue) use ($logReturn) {
               if ($logReturn) Logger::log($returnValue);
               return $returnValue;
          }
     }

     function Method($input) {
          if($input===false) {
               $ret('FALSE');
          }
          if($input=='Hello') {
               $ret('GREETING');
          }
     }

}

 

Now my simple calling code works, and I don't need to write each function twice. However, there is a messy aspect to this, in that I need to use the $ret() call instead of the return keyword. To that end, does anyone know of a way to trap the return value directly?

 

~ Christopher

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.