Inline isCallable and isTruthy into compiled templates

~3-5% performance gain.
This commit is contained in:
Justin Hileman
2012-03-13 20:45:26 -07:00
parent b27705375a
commit 9a334cddf0
3 changed files with 5 additions and 85 deletions
+5 -4
View File
@@ -140,14 +140,14 @@ class Compiler {
const SECTION = ' const SECTION = '
private function section%s(\Mustache\Buffer $buffer, \Mustache\Context $context, $value) { private function section%s(\Mustache\Buffer $buffer, \Mustache\Context $context, $value) {
if ($context->isCallable($value)) { if (!is_string($value) && is_callable($value)) {
$source = %s; $source = %s;
$buffer->write( $buffer->write(
$this->mustache $this->mustache
->loadLambda((string) call_user_func($value, $source)%s) ->loadLambda((string) call_user_func($value, $source)%s)
->renderInternal($context, $buffer->getIndent()) ->renderInternal($context, $buffer->getIndent())
); );
} elseif ($context->isTruthy($value)) { } elseif (!empty($value)) {
$values = $context->isIterable($value) ? $value : array($value); $values = $context->isIterable($value) ? $value : array($value);
foreach ($values as $value) { foreach ($values as $value) {
$context->push($value);%s $context->push($value);%s
@@ -191,7 +191,8 @@ class Compiler {
const INVERTED_SECTION = ' const INVERTED_SECTION = '
// %s inverted section // %s inverted section
if (!$context->isTruthy($context->%s(%s))) { $value = $context->%s(%s);
if (empty($value)) {
%s %s
}'; }';
@@ -232,7 +233,7 @@ class Compiler {
const VARIABLE = ' const VARIABLE = '
$value = $context->%s(%s); $value = $context->%s(%s);
if ($context->isCallable($value)) { if (!is_string($value) && is_callable($value)) {
$value = $this->mustache $value = $this->mustache
->loadLambda((string) call_user_func($value)) ->loadLambda((string) call_user_func($value))
->renderInternal($context, $buffer->getIndent()); ->renderInternal($context, $buffer->getIndent());
-30
View File
@@ -28,36 +28,6 @@ class Context {
} }
} }
/**
* Helper function to test whether a value is 'truthy'.
*
* @param mixed $value
*
* @return boolean True if the value is 'truthy'
*/
public function isTruthy($value) {
return !empty($value);
}
/**
* Higher order sections helper: tests whether a value is a valid callback.
*
* In Mustache.php, a variable is considered 'callable' if the variable is:
*
* 1. An anonymous function.
* 2. An object and the name of a public function, e.g. `array($someObject, 'methodName')`
* 3. A class name and the name of a public static function, e.g. `array('SomeClass', 'methodName')`
*
* Note that this specifically excludes strings, which PHP would normally consider 'callable'.
*
* @param mixed $value
*
* @return boolean True if the value is 'callable'
*/
public function isCallable($value) {
return !is_string($value) && is_callable($value);
}
/** /**
* Tests whether a value should be iterated over (e.g. in a section context). * Tests whether a value should be iterated over (e.g. in a section context).
* *
-51
View File
@@ -36,57 +36,6 @@ class ContextTest extends \PHPUnit_Framework_TestCase {
$this->assertEquals('NAME', $three->find('name')); $this->assertEquals('NAME', $three->find('name'));
} }
public function testIsTruthy() {
$context = new Context;
$this->assertTrue($context->isTruthy('string'));
$this->assertTrue($context->isTruthy(new \StdClass));
$this->assertTrue($context->isTruthy(1));
$this->assertTrue($context->isTruthy(array('a', 'b')));
$this->assertFalse($context->isTruthy(null));
$this->assertFalse($context->isTruthy(''));
$this->assertFalse($context->isTruthy(0));
$this->assertFalse($context->isTruthy(array()));
}
public function testIsCallable() {
$dummy = new TestDummy;
$context = new Context;
$this->assertTrue($context->isCallable(function() {
return null;
}));
$this->assertTrue($context->isCallable(array('\Mustache\Test\TestDummy', 'foo')));
$this->assertTrue($context->isCallable(array($dummy, 'bar')));
$this->assertTrue($context->isCallable($dummy));
$this->assertFalse($context->isCallable('count'));
$this->assertFalse($context->isCallable('TestDummy::foo'));
$this->assertFalse($context->isCallable(array('\Mustache\Test\TestDummy', 'name')));
$this->assertFalse($context->isCallable(array('NotReallyAClass', 'foo')));
$this->assertFalse($context->isCallable(array($dummy, 'name')));
}
/**
* @dataProvider getIterables
*/
public function testIsIterable($value, $iterable) {
$context = new Context;
$this->assertEquals($iterable, $context->isIterable($value));
}
public function getIterables() {
return array(
array(array(0 => 'a', 1 => 'b'), true),
array(array(0 => 'a', 2 => 'b'), false),
array(array(1 => 'a', 2 => 'b'), false),
array(array('a' => 0, 'b' => 1), false),
array('some string', false),
array(new \ArrayIterator, true),
);
}
public function testPushPopAndLast() { public function testPushPopAndLast() {
$context = new Context; $context = new Context;
$this->assertFalse($context->last()); $this->assertFalse($context->last());