From 9a334cddf075b47ab2ed95fdaa21a04ed365fc62 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Tue, 13 Mar 2012 14:14:20 -0500 Subject: [PATCH] Inline `isCallable` and `isTruthy` into compiled templates ~3-5% performance gain. --- src/Mustache/Compiler.php | 9 +++--- src/Mustache/Context.php | 30 ------------------ test/Mustache/Test/ContextTest.php | 51 ------------------------------ 3 files changed, 5 insertions(+), 85 deletions(-) diff --git a/src/Mustache/Compiler.php b/src/Mustache/Compiler.php index 2cd469c..7213117 100644 --- a/src/Mustache/Compiler.php +++ b/src/Mustache/Compiler.php @@ -140,14 +140,14 @@ class Compiler { const SECTION = ' private function section%s(\Mustache\Buffer $buffer, \Mustache\Context $context, $value) { - if ($context->isCallable($value)) { + if (!is_string($value) && is_callable($value)) { $source = %s; $buffer->write( $this->mustache ->loadLambda((string) call_user_func($value, $source)%s) ->renderInternal($context, $buffer->getIndent()) ); - } elseif ($context->isTruthy($value)) { + } elseif (!empty($value)) { $values = $context->isIterable($value) ? $value : array($value); foreach ($values as $value) { $context->push($value);%s @@ -191,7 +191,8 @@ class Compiler { const INVERTED_SECTION = ' // %s inverted section - if (!$context->isTruthy($context->%s(%s))) { + $value = $context->%s(%s); + if (empty($value)) { %s }'; @@ -232,7 +233,7 @@ class Compiler { const VARIABLE = ' $value = $context->%s(%s); - if ($context->isCallable($value)) { + if (!is_string($value) && is_callable($value)) { $value = $this->mustache ->loadLambda((string) call_user_func($value)) ->renderInternal($context, $buffer->getIndent()); diff --git a/src/Mustache/Context.php b/src/Mustache/Context.php index 33f3409..d63fc2b 100644 --- a/src/Mustache/Context.php +++ b/src/Mustache/Context.php @@ -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). * diff --git a/test/Mustache/Test/ContextTest.php b/test/Mustache/Test/ContextTest.php index 07e9c11..c71cd53 100644 --- a/test/Mustache/Test/ContextTest.php +++ b/test/Mustache/Test/ContextTest.php @@ -36,57 +36,6 @@ class ContextTest extends \PHPUnit_Framework_TestCase { $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() { $context = new Context; $this->assertFalse($context->last());