Adding Object::dispatchMethod() as faster (OO) replacement for call_user_func_array

git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6452 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
nate 2008-02-11 06:02:40 +00:00
parent 96d2b4b738
commit 50236e3431
2 changed files with 129 additions and 3 deletions

View file

@ -108,6 +108,47 @@ class Object {
return false;
}
}
/**
* Calls a method on this object with the given parameters. Provides an OO wrapper
* for call_user_func_array, and improves performance by using straight method calls
* in most cases.
*
* @param string $method Name of the method to call
* @param array $params Parameter list to use when calling $method
* @param boolean $strict If true, checks to make sure that $method is defined
* in this object. Throws a warning if not.
* @return mixed Returns the result of the method call, or null if $strict is
* true and the method was not found
* @access public
*/
function dispatchMethod($method, $params = array(), $strict = false) {
if ($strict) {
if (!method_exists($this, $method)) {
trigger_error("Object::dispatchMethod() - Method {$method} not found in " . get_class($this), E_USER_WARNING);
return null;
}
}
if (empty($params)) {
return $this->{$method}();
}
$params = array_values($params);
switch (count($params)) {
case 1:
return $this->{$method}($params[0]);
case 2:
return $this->{$method}($params[0], $params[1]);
case 3:
return $this->{$method}($params[0], $params[1], $params[2]);
case 4:
return $this->{$method}($params[0], $params[1], $params[2], $params[3]);
case 5:
return $this->{$method}($params[0], $params[1], $params[2], $params[3], $params[4]);
default:
call_user_func_array(array(&$this, $method), $params);
break;
}
}
/**
* API for logging events.
*

View file

@ -26,7 +26,37 @@
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/
uses('object');
App::import('Core', 'Object');
class TestObject extends Object {
var $methodCalls = array();
function emptyMethod() {
$this->methodCalls[] = 'emptyMethod';
}
function oneParamMethod($param) {
$this->methodCalls[] = array('oneParamMethod' => array($param));
}
function twoParamMethod($param, $param2) {
$this->methodCalls[] = array('twooParamMethod' => array($param, $param2));
}
function threeParamMethod($param, $param2, $param3) {
$this->methodCalls[] = array('threeParamMethod' => array($param, $param2, $param3));
}
function crazyMethod($param, $param2, $param3, $param4, $param5, $param6, $param7 = null) {
$this->methodCalls[] = array('crazyMethod' => array($param, $param2, $param3, $param4, $param5, $param6, $param7));
}
function methodWithOptionalParam($param = null) {
$this->methodCalls[] = array('methodWithOptionalParam' => array($param));
}
}
/**
* Short description for class.
*
@ -35,8 +65,63 @@ uses('object');
*/
class ObjectTest extends UnitTestCase {
function skip() {
$this->skipif (true, 'ObjectTest not implemented');
function setUp() {
$this->object = new TestObject();
}
function testToString() {
$result = strtolower($this->object->toString());
$this->assertEqual($result, 'testobject');
}
function testMethodDispatching() {
$this->object->emptyMethod();
$expected = array('emptyMethod');
$this->assertIdentical($this->object->methodCalls, $expected);
$this->object->oneParamMethod('Hello');
$expected[] = array('oneParamMethod' => array('Hello'));
$this->assertIdentical($this->object->methodCalls, $expected);
$this->object->threeParamMethod(true, false, null);
$expected[] = array('threeParamMethod' => array(true, false, null));
$this->assertIdentical($this->object->methodCalls, $expected);
$this->object->crazyMethod(1, 2, 3, 4, 5, 6, 7);
$expected[] = array('crazyMethod' => array(1, 2, 3, 4, 5, 6, 7));
$this->assertIdentical($this->object->methodCalls, $expected);
$this->object = new TestObject();
$this->assertIdentical($this->object->methodCalls, array());
$this->object->dispatchMethod('emptyMethod');
$expected = array('emptyMethod');
$this->assertIdentical($this->object->methodCalls, $expected);
$this->object->dispatchMethod('oneParamMethod', array('Hello'));
$expected[] = array('oneParamMethod' => array('Hello'));
$this->assertIdentical($this->object->methodCalls, $expected);
$this->object->dispatchMethod('threeParamMethod', array(true, false, null));
$expected[] = array('threeParamMethod' => array(true, false, null));
$this->assertIdentical($this->object->methodCalls, $expected);
$this->object->dispatchMethod('crazyMethod', array(1, 2, 3, 4, 5, 6, 7));
$expected[] = array('crazyMethod' => array(1, 2, 3, 4, 5, 6, 7));
$this->assertIdentical($this->object->methodCalls, $expected);
$this->object->dispatchMethod('methodWithOptionalParam', array('Hello'));
$expected[] = array('methodWithOptionalParam' => array("Hello"));
$this->assertIdentical($this->object->methodCalls, $expected);
$this->object->dispatchMethod('methodWithOptionalParam');
$expected[] = array('methodWithOptionalParam' => array(null));
$this->assertIdentical($this->object->methodCalls, $expected);
}
function tearDown() {
unset($this->object);
}
}
?>