[limb-svn] r6421 - in 3.x/trunk/limb/core: src src/exception tests/bench tests/cases

svn at limb-project.com svn at limb-project.com
Tue Oct 16 11:42:54 MSD 2007


Author: serega
Date: 2007-10-16 11:42:54 +0400 (Tue, 16 Oct 2007)
New Revision: 6421
URL: http://fisheye.limb-project.com/changelog/limb/?cs=6421

Added:
   3.x/trunk/limb/core/src/exception/lmbNoSuchMethodException.class.php
   3.x/trunk/limb/core/src/exception/lmbNoSuchPropertyException.class.php
Modified:
   3.x/trunk/limb/core/src/lmbObject.class.php
   3.x/trunk/limb/core/tests/bench/object-attr.php
   3.x/trunk/limb/core/tests/cases/lmbObjectTest.class.php
Log:
-- lmbObject massive changes (possible small BC breaks)
  * lmbObject now stores all properties in $props array. This allowed to speed up get()/set() operations.
  * lmbObject now throws an exception of lmbNoSuchPropertyException if someone calls get() to non existing property. Please use has() or isset() before getting any property.
  * lmbObject now throws an exception of lmbNoSuchMethodException if someone calls getXX() for non existing property. 
  * lmbObject has __set, __get, __isset, __unset methods overloaded that delegate to set, get, has and remove accordingly
  * As the result lmbObject fulfils it's contract, i.e. $obj['foo'] == $obj->getFoo() == obj->get('foo') == $obj->foo

Added: 3.x/trunk/limb/core/src/exception/lmbNoSuchMethodException.class.php
===================================================================
--- 3.x/trunk/limb/core/src/exception/lmbNoSuchMethodException.class.php	                        (rev 0)
+++ 3.x/trunk/limb/core/src/exception/lmbNoSuchMethodException.class.php	2007-10-16 07:42:54 UTC (rev 6421)
@@ -0,0 +1,22 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+
+/**
+ * class lmbNoSuchMethodException.
+ * Used in __call() methods.
+ * @see lmbObject :: __call()
+ *
+ * @package core
+ * @version $Id$
+ */
+class lmbNoSuchMethodException extends lmbException
+{
+}
+
+

Added: 3.x/trunk/limb/core/src/exception/lmbNoSuchPropertyException.class.php
===================================================================
--- 3.x/trunk/limb/core/src/exception/lmbNoSuchPropertyException.class.php	                        (rev 0)
+++ 3.x/trunk/limb/core/src/exception/lmbNoSuchPropertyException.class.php	2007-10-16 07:42:54 UTC (rev 6421)
@@ -0,0 +1,21 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+
+/**
+ * class lmbNoSuchPropertyException.
+ * @see lmbObject :: get()
+ *
+ * @package core
+ * @version $Id$
+ */
+class lmbNoSuchPropertyException extends lmbException
+{
+}
+
+

Modified: 3.x/trunk/limb/core/src/lmbObject.class.php
===================================================================
--- 3.x/trunk/limb/core/src/lmbObject.class.php	2007-10-15 21:37:38 UTC (rev 6420)
+++ 3.x/trunk/limb/core/src/lmbObject.class.php	2007-10-16 07:42:54 UTC (rev 6421)
@@ -7,6 +7,8 @@
  * @license    LGPL http://www.gnu.org/copyleft/lesser.html
  */
 lmb_require('limb/core/src/lmbSetInterface.interface.php');
+lmb_require('limb/core/src/exception/lmbNoSuchMethodException.class.php');
+lmb_require('limb/core/src/exception/lmbNoSuchPropertyException.class.php');
 /**
  * Generic container for data with magic accessors.
  *
@@ -71,6 +73,7 @@
  */
 class lmbObject implements lmbSetInterface
 {
+  protected $props = array();
   /**
    * Constructor.
    * Fills internals properties if any
@@ -109,10 +112,7 @@
       return;
 
     foreach($values as $name => $value)
-    {
-      if(!$this->_isGuarded($name))
-        $this->_setRaw($name, $value);
-    }
+      $this->props[$name] = $value;
   }
   /**
    * Exports all object properties as an array
@@ -120,68 +120,34 @@
    */
   function export()
   {
-    $exported = array();
-    foreach($this->_getObjectVars() as $name => $var)
-    {
-      if(!$this->_isGuarded($name))
-        $exported[$name] = $var;
-    }
-    return $exported;
+    return $this->props;
   }
   /**
-   * Checks if such attribute exists
+   * Checks if such property exists
+   * Can be overriden in child classes like lmbActiveRecord
    * @return bool returns true even if attribute is null
    */
   function has($name)
   {
-    return in_array($name, $this->getAttributesNames());
+    return array_key_exists($name, $this->props) || $this->_mapPropertyToMethod($name);
   }
+
   /**
-   * @deprecated
-   * @see has()
-   */
-  function hasAttribute($name)
-  {
-    return $this->has($name);
-  }
-  /**
-   * Returns array filled with attribute names
-   * @return array
-   */
-  function getAttributesNames()
-  {
-    $names = array();
-    foreach($this->_getObjectVars() as $name => $value)
-    {
-      if(!$this->_isGuarded($name))
-        $names[] = $name;
-    }
-    return $names;
-  }
-  /**
    * Removes specified property
    * @param string
    */
   function remove($name)
   {
-    if($this->hasAttribute($name))
-      unset($this->$name);
+    if(array_key_exists($name, $this->props))
+      unset($this->props[$name]);
   }
+
   /**
-   * @deprecated
-   * @see reset()
-   */
-  function removeAll()
-  {
-    $this->reset();
-  }
-  /**
    * Removes all object properties
    */
   function reset()
   {
-    foreach($this->_getObjectVars() as $name => $var)
-      $this->remove($name);
+    $this->props = array();
   }
 
   /**
@@ -195,9 +161,18 @@
     if($method = $this->_mapPropertyToMethod($name))
       return $this->$method();
 
-    if(!$this->_isGuarded($name))
-      return $this->_getRaw($name);
+    if(array_key_exists($name, $this->props))
+      return $this->props[$name];
+
+    throw new lmbNoSuchPropertyException("No such property '$name' in " . get_class($this));
   }
+
+  protected function _getRaw($name)
+  {
+    if(isset($this->props[$name]))
+      return $this->props[$name];
+  }
+
   /**
    * Sets property value
    * Magically maps setter to fine-grained method if it exists, e.g. set('foo', $value) => setFoo($value)
@@ -209,17 +184,21 @@
     if($method = $this->_mapPropertyToSetMethod($name))
       return $this->$method($value);
 
-    if(!$this->_isGuarded($name))
-      $this->_setRaw($name, $value);
+    $this->props[$name] = $value;
   }
 
+  protected function _setRaw($name, $value)
+  {
+    $this->props[$name] = $value;
+  }
+
   /**#@+
    * Implements ArrayAccess interface
    * @see ArrayAccess
    */
   function offsetExists($offset)
   {
-    return $this->hasAttribute($offset);
+    return $this->has($offset);
   }
 
   function offsetGet($offset)
@@ -238,33 +217,14 @@
   }
   /**#@-*/
 
-  protected function _getRaw($name)
-  {
-    if(isset($this->$name))
-      return $this->$name;
-  }
-
-  protected function _getObjectVars()
-  {
-    return get_object_vars($this);
-  }
-
-  protected function _setRaw($name, $value)
-  {
-    $this->$name = $value;
-  }
-
-  protected function _isGuarded($property)
-  {
-    return $property{0} == '_';
-  }
-
   protected function __call($method, $args = array())
   {
     if($property = $this->_mapGetToProperty($method))
     {
-      if(!$this->_isGuarded($property))
-        return $this->_getRaw($property);
+      if($this->has($property))
+        return $this->get($property);
+      else
+        throw new lmbNoSuchMethodException("No such method '$method' in " . get_class($this));
     }
     elseif($property = $this->_mapSetToProperty($method))
     {
@@ -272,7 +232,7 @@
       return;
     }
 
-    throw new lmbException("No such method '$method' in " . get_class($this));
+    throw new lmbNoSuchMethodException("No such method '$method' in " . get_class($this));
   }
 
   protected function _mapGetToProperty($method)
@@ -315,5 +275,42 @@
     if(method_exists($this, $method))
       return $method;
   }
+
+  /**
+   * __set        an alias of set()
+   * @see set, offsetSet
+   */
+  public function __set($name,$value)
+  {
+      $this->set($name,$value);
+  }
+
+  /**
+   * __get -- an alias of get()
+   * @see get,  offsetGet
+   * @return mixed
+   */
+  public function __get($name)
+  {
+    return $this->get($name);
+  }
+
+  /**
+   * __isset()
+   * @return boolean          whether or not this object contains $name
+   */
+  public function __isset($name)
+  {
+    return $this->has($name);
+  }
+
+  /**
+   * __unset()
+   * @param string $name
+   */
+  public function __unset($name)
+  {
+    return $this->remove($name);
+  }
 }
 

Modified: 3.x/trunk/limb/core/tests/bench/object-attr.php
===================================================================
--- 3.x/trunk/limb/core/tests/bench/object-attr.php	2007-10-15 21:37:38 UTC (rev 6420)
+++ 3.x/trunk/limb/core/tests/bench/object-attr.php	2007-10-16 07:42:54 UTC (rev 6421)
@@ -13,8 +13,9 @@
 }
 $object = new Foo(array('foo' => 'foo'));
 
+// heating_up
 for($i=0;$i<1000;$i++)
-  $object->get('heating_up');
+  $object->get('foo');
 
 $mark = microtime(true);
 
@@ -26,13 +27,6 @@
 $mark = microtime(true);
 
 for($i=0;$i<1000;$i++)
-  $object->get('foo' . $i);
-
-echo "get('fooXXX'): " . (microtime(true) - $mark) . "\n";
-
-$mark = microtime(true);
-
-for($i=0;$i<1000;$i++)
   $object->get('bar');
 
 echo "get('bar') => getBar(): " . (microtime(true) - $mark) . "\n";

Modified: 3.x/trunk/limb/core/tests/cases/lmbObjectTest.class.php
===================================================================
--- 3.x/trunk/limb/core/tests/cases/lmbObjectTest.class.php	2007-10-15 21:37:38 UTC (rev 6420)
+++ 3.x/trunk/limb/core/tests/cases/lmbObjectTest.class.php	2007-10-16 07:42:54 UTC (rev 6421)
@@ -2,9 +2,9 @@
 /*
  * Limb PHP Framework
  *
- * @link http://limb-project.com 
+ * @link http://limb-project.com
  * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
- * @license    LGPL http://www.gnu.org/copyleft/lesser.html 
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
  */
 lmb_require('limb/core/src/lmbObject.class.php');
 
@@ -39,6 +39,10 @@
   }
 }
 
+class ObjectTestVersion2 extends lmbObject
+{
+}
+
 class lmbObjectTest extends UnitTestCase
 {
   function testHasAttribute()
@@ -46,51 +50,52 @@
     $object = new lmbObject();
     $object->set('bar', 1);
 
-    $this->assertFalse($object->hasAttribute('foo'));
-    $this->assertTrue($object->hasAttribute('bar'));
+    $this->assertFalse($object->has('foo'));
+    $this->assertTrue($object->has('bar'));
   }
 
   function testHasAttributeForExistingButNullProperty()
   {
     $object = new lmbObject();
     $object->set('foo', null);
-    $this->assertTrue($object->hasAttribute('foo'));
+    $this->assertTrue($object->has('foo'));
   }
 
-  function testHasAttributeForGuardedProperty()
+  function testHasAttributeForVirtualProperty()
   {
     $object = new ObjectTestVersion();
-    $object->_guarded = 'yeah';
-    $this->assertFalse($object->hasAttribute('_guarded'));
+    $this->assertTrue($object->has('is_error'));
   }
 
-  function testGetAttributesNames()
+  function testSetGet()
   {
-    $object = new ObjectTestVersion();
-    $this->assertEqual($object->getAttributesNames(), array('bar', 'protected'));
+    $object = new lmbObject();
+    $object->set('foo', 1);
+
+    $this->assertEqual($object->get('foo'), 1);
   }
 
-  function testGetNull()
+  function testSetGetNullValue()
   {
     $object = new lmbObject();
+    $object->set('foo', null);
+
     $this->assertNull($object->get('foo'));
   }
 
-  function testSetGet()
+  function testCallingGetterForNoneExistingPropertyThrowsException()
   {
     $object = new lmbObject();
-    $object->set('foo', 1);
-
-    $this->assertEqual($object->get('foo'), 1);
+    try
+    {
+      $object->get('no_such_property');
+      $this->assertTrue(false);
+    }
+    catch(lmbNoSuchPropertyException $e)
+    {
+    }
   }
 
-  function testCallGetterForGuardedProperty()
-  {
-    $object = new ObjectTestVersion();
-    $object->_guarded = 'yeah';
-    $this->assertNull($object->get('_guarded'));
-  }
-
   function testNonExistingGetter()
   {
     $object = new lmbObject();
@@ -135,6 +140,32 @@
     $this->assertTrue($object->get('is_error'));//getIsError overriden in ObjectTestVersion
   }
 
+  function testCallingMagicGetterForNoneExistingPropertyThrowsException()
+  {
+    $object = new lmbObject();
+    try
+    {
+      $object->getNoSuchPropety();
+      $this->assertTrue(false);
+    }
+    catch(lmbNoSuchMethodException $e)
+    {
+    }
+  }
+
+  function testNoneExistingMethodThrowsProperException()
+  {
+    $object = new lmbObject();
+    try
+    {
+      $object->noSuchMethod();
+      $this->assertTrue(false);
+    }
+    catch(lmbNoSuchMethodException $e)
+    {
+    }
+  }
+
   function testImportMergesWithExistingProps()
   {
     $object = new lmbObject();
@@ -147,14 +178,6 @@
     $this->assertEqual($object->get('baz'), 'wow');
   }
 
-  function testImportIgnoresGuardedProperties()
-  {
-    $object = new ObjectTestVersion();
-    $object->_guarded = 'yeah';
-    $object->import(array('_guarded' => 'no'));
-    $this->assertEqual($object->_guarded, 'yeah');
-  }
-
   function testPassAttributesInConstructor()
   {
     $object = new lmbObject(array('foo' => 'hey', 'baz' => 'wow'));
@@ -171,14 +194,6 @@
     $this->assertEqual($object->export(), array('foo' => 'yo-yo', 'bar' => 'zoo'));
   }
 
-  function testExportOnlyNonGuardedProperties()
-  {
-    $object = new ObjectTestVersion();
-    $object->set('foo', 'FOO');
-
-    $this->assertEqual($object->export(), array('bar' => null, 'foo' => 'FOO', 'protected' => 'me'));
-  }
-
   function testRemove()
   {
     $object = new lmbObject();
@@ -188,38 +203,21 @@
     $object->remove('bar');
 
     $this->assertEqual($object->get('foo'), 2);
-    $this->assertNull($object->get('bar'));
-    $this->assertFalse($object->hasAttribute('bar'));
+    $this->assertTrue($object->has('foo'));
+    $this->assertFalse($object->has('bar'));
   }
 
-  function testRemoveForGuardedProperty()
+  function testReset()
   {
-    $object = new ObjectTestVersion();
-    $object->_guarded = 'yeah';
-    $object->remove('_guarded');
-
-    $this->assertEqual($object->_guarded, 'yeah');
-  }
-
-  function testRemoveAll()
-  {
     $object = new lmbObject();
     $object->set('bar', 1);
     $object->set('foo', 2);
 
-    $object->removeAll();
+    $object->reset();
 
     $this->assertEqual($object->export(), array());
   }
 
-  function testRemoveAllExceptGuardedProperties()
-  {
-    $object = new ObjectTestVersion();
-    $object->_guarded = 'yeah';
-    $object->removeAll();
-    $this->assertEqual($object->_guarded, 'yeah');
-  }
-
   function testGetHash()
   {
     $o1 = new lmbObject();
@@ -245,15 +243,28 @@
     $o->set('foo', 'Bar');
     $this->assertEqual($o['foo'], 'Bar');
 
+    $this->assertTrue(isset($o['foo']));
+
     $o['foo'] = 'Zoo';
     $this->assertEqual($o->get('foo'), 'Zoo');
 
     unset($o['foo']);
-    $this->assertNull($o->get('foo'));
+    $this->assertFalse($o->has('foo'));
+    $this->assertFalse(isset($o['foo']));
 
     $o->set('foo', 'Bar');
     $this->assertTrue(isset($o['foo']));
     $this->assertFalse(isset($o['bar']));
   }
+
+  function testGettersCacheWorksForDifferentClassesProperly()
+  {
+    $object = new ObjectTestVersion();
+    $object->get('bar');
+    $object2 = new ObjectTestVersion2();
+    $object2->set('bar', 1);
+    $object2->get('bar');
+    $this->assertTrue(true);
+  }
 }
 



More information about the limb-svn mailing list