<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>lib/arr.php</filename>
    </added>
    <added>
      <filename>lib/delegator.php</filename>
    </added>
    <added>
      <filename>lib/marshal.php</filename>
    </added>
    <added>
      <filename>lib/module.php</filename>
    </added>
    <added>
      <filename>lib/proc.php</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -12,14 +12,12 @@ rubyisms in php
 
 ## Features
 
-INCOMPLETE
-
-* mixins - methods and properties can be added to an existing class OR instance of an object
-* alias\_method and alias\_method\_chain (also works at the class OR instance level)
-* Object class (all classes should inherit from this)
-* Enumerable, A (array), and H (hash) classes
-* blocks (as strings)
-* structs
+* A base `Object` class (all classes should inherit from this)
+* Mixins - `Post::extend('Validations');`
+* alias\_method - `Post::alias_method('save_with_validation', 'save');`
+* alias\_method\_chain - `Post::alias_method_chain('save', 'validation');`
+* Procs - `$proc = new Proc('name', 'echo &quot;hello $name&quot;;'); $proc-&gt;call('Sean');`
+* Various classes and modules from the standard ruby library like `Enumerable`, `Arr`, `Hash`, `Struct`, etc
 
 
 ## Usage</diff>
      <filename>README.markdown</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,13 @@
+2009-06-11 - Sean Huber (shuber@huberry.com)
+  * Huge refactor
+  * Add Object::new_instance_array method
+  * Add autoloading and marshal class
+  * Add Object::cloned and Object#dup
+  * Add Object#__clone
+  * Add Object#superclass
+  * build_function_call supports calling instance methods
+  * Add Delegator (incomplete)
+
 2009-03-16 - Sean Huber (shuber@huberry.com)
   * Add Struct class
   * Add some methods to Struct</diff>
      <filename>doc/CHANGELOG</filename>
    </modified>
    <modified>
      <diff>@@ -5,7 +5,4 @@
 * look into stream filters
 * observers
 * Object#call should build an instance method call to eval so that protected and private methods can be called
-* Mod#ancestors
-* Mod#append_features
-* fix static property inheritance issues
-* classes should copy extended methods/properties from the mixin's extended methods/properties
\ No newline at end of file
+* Mod#append_features
\ No newline at end of file</diff>
      <filename>doc/TODO</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,6 @@
 &lt;?php
 
-class Enumerator extends Object implements ArrayAccess, Countable, IteratorAggregate {
+class Enumerator extends Object implements Iterator, ArrayAccess, Countable {
     
     public $array;
     public $default;
@@ -14,11 +14,19 @@ class Enumerator extends Object implements ArrayAccess, Countable, IteratorAggre
     function count() {
         return count($this-&gt;array);
     }
-
+    
+    function current() {
+        return current($this-&gt;array);
+    }
+    
     function getIterator() {
-        return new ArrayIterator($this-&gt;array);
+        return $this;
     }
-
+    
+    function key() {
+        return key($this-&gt;array);
+    }
+    
     function offsetExists($offset) {
         return isset($this-&gt;array[$offset]);
     }
@@ -35,9 +43,23 @@ class Enumerator extends Object implements ArrayAccess, Countable, IteratorAggre
     function offsetUnset($offset) {
         unset($this-&gt;array[$offset]);
     }
+    
+    function next() {
+        $this-&gt;valid = (next($this-&gt;array) !== false);
+    }
+    
+    function rewind() {
+        $this-&gt;valid = (reset($this-&gt;array) !== false);
+    }
+    
+    function valid() {
+        return $this-&gt;valid;
+    }
 
 }
 
+abstract class Enumerable extends Enumerator { }
+
 abstract class EnumerableMethods {
     
     function all($block) {
@@ -56,7 +78,7 @@ abstract class EnumerableMethods {
     }
     
     function collect($block) {
-        $result = new A;
+        $result = new Arr;
         foreach ($this as $key =&gt; $value) $result[] = evaluate_block($block, get_defined_vars());
         return $result;
     }
@@ -67,7 +89,7 @@ abstract class EnumerableMethods {
     }
     
     function filter($callback = null) {
-        return $this-&gt;new_instance(array_filter($this-&gt;array, $callback));
+        return call_class_method($this-&gt;class, 'new_instance', array(array_filter($this-&gt;array, $callback)));
     }
     
     function has_key($key) {
@@ -98,8 +120,8 @@ abstract class EnumerableMethods {
     }
     
     function partition($block) {
-        $passed = $this-&gt;new_instance();
-        $failed = $this-&gt;new_instance();
+        $passed = call_class_method($this-&gt;class, 'new_instance');
+        $failed = call_class_method($this-&gt;class, 'new_instance');
         foreach ($this as $key =&gt; $value) {
             if (evaluate_block($block, get_defined_vars())) {
                 $passed[$key] = $value;
@@ -107,11 +129,11 @@ abstract class EnumerableMethods {
                 $failed[$key] = $value;
             }
         }
-        return new A(array($passed, $failed));
+        return new Arr(array($passed, $failed));
     }
     
     function reject($block) {
-        $result = $this-&gt;new_instance();
+        $result = call_class_method($this-&gt;class, 'new_instance');
         foreach ($this as $key =&gt; $value) if (!evaluate_block($block, get_defined_vars())) $result[$key] = $value;
         return $result;
     }
@@ -129,7 +151,7 @@ abstract class EnumerableMethods {
     }
     
     function select($block) {
-        $result = $this-&gt;new_instance();
+        $result = call_class_method($this-&gt;class, 'new_instance');
         foreach ($this as $key =&gt; $value) if (evaluate_block($block, get_defined_vars())) $result[$key] = $value;
         return $result;
     }
@@ -142,16 +164,12 @@ abstract class EnumerableMethods {
         if (is_null($sort_flags)) $sort_flags = SORT_REGULAR;
         $array = $this-&gt;array;
         asort($array, $sort_flags);
-        return $this-&gt;new_instance($array);
+        return call_class_method($this-&gt;class, 'new_instance', array($array));
     }
     
     function sort_by($block, $sort_flags = null) {
-        $sorted = $this-&gt;inject(new H, '
-            $object[$key] = evaluate_block(\''.$block.'\', get_defined_vars()); 
-            $object;
-        ')-&gt;sort($sort_flags);
-        
-        $result = $this-&gt;new_instance();
+        $sorted = $this-&gt;inject(new Hash, '$object[$key] = evaluate_block(\''.$block.'\', get_defined_vars()); return $object;')-&gt;sort($sort_flags);
+        $result = call_class_method($this-&gt;class, 'new_instance');
         foreach ($sorted as $key =&gt; $value) $result[$key] = $this[$key];
         return $result;
     }
@@ -172,24 +190,18 @@ abstract class EnumerableMethods {
     
     function values_at($keys) {
         $keys = func_get_args();
-        $result = new A;
+        $result = new Arr;
         foreach ($keys as $key) $result[] = $this[$key];
         return $result;
     }
     
 }
 
-abstract class Enumerable extends Enumerator {
-    static $extended = array();
-}
-
-extend('Enumerable', 'EnumerableMethods');
-alias_method('Enumerable', 'at', 'offsetGet');
-alias_method('Enumerable', 'fetch', 'offsetGet');
-alias_method('Enumerable', 'length', 'count');
-alias_method('Enumerable', 'map', 'collect');
-alias_method('Enumerable', 'reduce', 'inject');
-alias_method('Enumerable', 'size', 'count');
-alias_method('Enumerable', 'store', 'offsetSet');
+Enumerable::extend('EnumerableMethods');
 
-?&gt;
\ No newline at end of file
+Enumerable::alias_method('at', 'offsetGet');
+Enumerable::alias_method('fetch', 'offsetGet');
+Enumerable::alias_method('length', 'count');
+Enumerable::alias_method('map', 'collect');
+Enumerable::alias_method('size', 'count');
+Enumerable::alias_method('store', 'offsetSet');
\ No newline at end of file</diff>
      <filename>lib/enumerable.php</filename>
    </modified>
    <modified>
      <diff>@@ -1,151 +1,80 @@
 &lt;?php
 
-function alias_method($object, $new_name, $old_name) {
-    extend_method($object, $object, $old_name, $new_name);
-}
-
-function alias_method_chain($object, $method, $with) {
-    $without = $method.'_without_'.$with;
-    if (is_object($object)) {
-        $object-&gt;instance_extended_methods[$without] = $object-&gt;instance_extended_methods[$method];
-        unset($object-&gt;instance_extended_methods[$method]);
-    } else {
-        $extended = get_static_property($object, 'extended');
-        
-        if (!isset($extended['methods'])) {
-            $extended['methods'] = array();
-        }
-
-        $extended['methods'][$without] = $extended['methods'][$method];
-        unset($extended['methods'][$method]);
-        set_static_property($object, 'extended', $extended);
-    }
-    extend_method($object, $object, $method.'_with_'.$with, $method);
-}
-
-function build_function_call($function, $arguments = array(), $variable_name = 'arguments') {
-    if (!is_array($function)) $function = array($function);
-    if (is_object($function[0])) $function[0] = get_class($function[0]);
-    $function_call = join('::', $function).'(';
-    if (!empty($arguments)) {
-        $function_call .= '$'.$variable_name.'[0]';
-        for ($i = 1; $i &lt; count($arguments); $i++) {
-            $function_call .= ', $'.$variable_name.'['.$i.']';
+if (!function_exists('get_called_class')) {
+    function get_called_class() { 
+        $backtrace = debug_backtrace();
+        if (preg_match('/eval\(\)\'d code$/', $backtrace[1]['file'])) {
+            return $backtrace[3]['args'][0];
+        } else {
+            $lines = file($backtrace[1]['file']);
+            preg_match('/([a-zA-Z0-9\_]+)::'.$backtrace[1]['function'].'/', $lines[$backtrace[1]['line']-1], $matches);
+            return $matches[1];
         }
     }
-    return $function_call .= ')';
 }
 
-function evaluate_block($block, $arguments = array()) {
-     # implict return
-    $lines = explode(';', $block);
-    $last =&amp; $lines[count($lines)-2];
-    if (strpos($last, 'return') === false) $last = 'return '.$last;
-    $block = join(';', $lines);
 
-    if (isset($arguments['this'])) {
-        $arguments['self'] = $arguments['this'];
-        unset($arguments['this']);
-    }
-    unset($arguments['block']);
-    extract($arguments);
-    return eval($block);
+# Class related
+function get_class_variable($class, $variable) {
+    return eval('return '.$class.'::$'.$variable.';');
 }
 
-function get_ancestors($class) {
-    for ($classes[] = $class; $class = get_parent_class($class); $classes[] = $class);
-    return $classes;
+function set_class_variable($class, $variable, $value) {
+    eval($class.'::$'.$variable.' = $value;');
 }
 
-function extend($object, $classes) {
-    if (!is_array($classes)) {
-        $classes = func_get_args();
-        $object = array_shift($classes);
-    }
-
-    foreach (array_unique($classes) as $class) {
-
-        $class_name = (is_object($class)) ? get_class($class) : $class;
-        if (!class_exists($class_name)) trigger_error('Undefined class '.$class_name, E_USER_ERROR);
-
-        $methods = get_class_methods($class_name);
-        foreach ($methods as $method) extend_method($object, $class, $method);
-
-        $properties = (is_object($class)) ? get_object_vars($class) : get_class_vars($class);
-        foreach ($properties as $property =&gt; $value) extend_property($object, $property, $value);
-
-        if (is_object($object)) {
-            $object-&gt;instance_extended_parents[] = $class_name;
-        } else {
-            $extended = get_static_property($object, 'extended');
-            if (!isset($extended['parents'])) {
-                $extended['parents'] = array();
-            }
-            $extended['parents'] = array_merge($extended['parents'], array($class_name));
-            set_static_property($object, 'extended', $extended);
-        }
-
-        $arguments = array($object);
-        if (method_exists($class_name, 'extended')) eval(build_function_call(array($class_name, 'extended'), $arguments).';');
-    }
+function &amp;call_class_method($class, $method, $arguments = array()) {
+    eval('$result = &amp;'.build_function_call(array($class, $method), $arguments).';');
+    return $result;
 }
 
-function extend_method($object, $class, $method, $method_name = null) {
-    $class_name = (is_object($class)) ? get_class($class) : $class;
-    if (is_null($method_name)) $method_name = $method;
-    if (is_object($object)) {
-        if (!isset($object-&gt;instance_extended_methods[$method_name])) $object-&gt;instance_extended_methods[$method_name] = array();
-        $object-&gt;instance_extended_methods[$method_name][] = array($class_name, $method);
-    } else {
-        $extended = get_static_property($object, 'extended');
-        
-        if (!isset($extended['methods'])) $extended['methods'] = array();
-        if (!isset($extended['methods'][$method_name])) $extended['methods'][$method_name] = array();
-        
-        $extended['methods'][$method_name][] = array($class_name, $method);
-        set_static_property($object, 'extended', $extended);
+function phuby_autoload($class) {
+    $namespaces = split('::', $class);
+    $file = dirname(__FILE__). DS. '..' . DS . 'lib';
+    foreach ($namespaces as $namespace) {
+        $file .= DS.strtolower(preg_replace('/[^A-Z^a-z^0-9]+/', '_', preg_replace('/([a-z\d])([A-Z])/', '\1_\2', preg_replace('/([A-Z]+)([A-Z][a-z])/', '\1_\2', $namespace))));
     }
-
-    $object_class_name = (is_object($object)) ? get_class($object) : $object;
-    $arguments = array($method_name);
-    if (method_exists($object_class_name, 'method_added')) eval(build_function_call(array($object_class_name, 'method_added'), $arguments).';');
+    require_once $file.'.php';
 }
 
-function extend_property($object, $property, $value) {
-    if (is_object($object)) {
-        $object-&gt;instance_extended_properties[$property] = $value;
-    } else {
-        $class_name = (is_object($object)) ? get_class($object) : $object;
-
-        $extended = get_static_property($class_name, 'extended');
-        if (!isset($extended['properties'])) $extended['properties'] = array();
-
-        $extended['properties'] = array_merge($extended['properties'], array($property =&gt; $value));
-        set_static_property($class_name, 'extended', $extended);
-    }
-}
 
-function get_static_property($class, $property) {
-    return eval('return '.$class.'::$'.$property.';');
+function proc($block) {
+    $arguments = func_get_args();
+    return eval('return '.build_function_call('new Proc', $arguments).';');
 }
 
-function set_static_property($class, $property, $value) {
-    eval($class.'::$'.$property.' = $value;');
-}
 
-# Convenience functions
+function evaluate_block($block, $binding = array()) {
+    # implict return
+    $lines = explode(';', $block);
+    $last =&amp; $lines[count($lines)-2];
+    
+    if (strpos($last, 'return') === false) $last = 'return '.$last;
+    $block = join(';', $lines);
 
-function a($array = array()) {
-    $args = func_get_args();
+    $parameters = array_merge(array_keys($binding), array($block));
+    eval('$proc = '.build_function_call('proc', $parameters, 'parameters').';');
+    return $proc-&gt;call_array(array_values($binding));
+}
 
-    if (count($args) &gt; 1) {
-        return new A($args);
+function build_function_call($function, $arguments = array(), $variable_name = 'arguments') {
+    if (!is_array($function)) $function = array($function);
+    if (is_object($function[0])) { 
+        $function[0] = get_class($function[0]);
+        $join = '-&gt;';
     } else {
-        return new A($array);
+        $join = '::';
     }
+    return join($join, $function).'('.splat($arguments, $variable_name).')';
 }
 
-function h($hash = array()) {
-    return new H($hash);
-}
-?&gt;
\ No newline at end of file
+function splat($arguments, $variable_name = 'arguments') {
+    $result = '';
+    if (!empty($arguments)) {
+        $result .= '$'.$variable_name.'[0]';
+        for ($i = 1; $i &lt; count($arguments); $i++) {
+            $result .= ', $'.$variable_name.'['.$i.']';
+        }
+    }
+    return $result;
+}
\ No newline at end of file</diff>
      <filename>lib/functions.php</filename>
    </modified>
    <modified>
      <diff>@@ -1,22 +1,24 @@
 &lt;?php
 
+class Hash extends Enumerable { }
+
 abstract class HashMethods {
     
     function invert() {
-        return $this-&gt;new_instance(array_flip($this-&gt;array));
+        return call_class_method($this-&gt;class, 'new_instance', array(array_flip($this-&gt;array)));
     }
     
     function merge($hash) {
         if ($hash instanceof Enumerable) $hash = $hash-&gt;array;
-        return $this-&gt;new_instance(array_merge($this-&gt;array, $hash));
+        return call_class_method($this-&gt;class, 'new_instance', array(array_merge($this-&gt;array, $hash)));
     }
     
     function shift() {
-        return (empty($this-&gt;array)) ? $this-&gt;super() : new A(array($this-&gt;keys()-&gt;shift(), $this-&gt;super()));
+        return (empty($this-&gt;array)) ? $this-&gt;super() : new Arr(array($this-&gt;keys()-&gt;shift(), $this-&gt;super()));
     }
     
     function to_a() {
-        return $this-&gt;inject(new A, '$object[] = new A(array($key, $value)); return $object;');
+        return $this-&gt;inject(new Arr, '$object[] = new A(array($key, $value)); return $object;');
     }
     
     function update($hash) {
@@ -27,11 +29,6 @@ abstract class HashMethods {
     
 }
 
-class H extends Enumerable {
-    static $extended = array();
-}
-
-extend('H', 'HashMethods');
-alias_method('H', 'flip', 'invert');
+Hash::extend('HashMethods');
 
-?&gt;
\ No newline at end of file
+Hash::alias_method('flip', 'invert');
\ No newline at end of file</diff>
      <filename>lib/hash.php</filename>
    </modified>
    <modified>
      <diff>@@ -1,134 +1,142 @@
 &lt;?php
 
-class Object {
-
-    static $extended = array();
+class Object extends Module {
+    
     public $class;
-    public $instance_extended_methods;
-    public $instance_extended_parents;
-    public $instance_extended_properties;
-
+    public $instance_variables;
+    public $superclass;
+    
+    function __clone() {
+        $this-&gt;send_array('cloned');
+    }
+    
     function __construct($arguments = null) {
         $this-&gt;class = get_class($this);
-
-        $extended = get_static_property($this-&gt;class, 'extended');
-        $extending = array('methods', 'parents', 'properties');
-
-        foreach($extending as $extend_meta) {
-            $$extend_meta = isset($extended[$extend_meta]) ? $extended[$extend_meta] :array();
-
-            foreach(get_ancestors($this-&gt;class) as $parent) {
-                $parent_extended = get_static_property($parent, 'extended');
-                if (!empty($parent_extended[$extend_meta])) {
-                    $$extend_meta = array_merge($$extend_meta, $parent_extended[$extend_meta]);
-                }
-            }
-            $this-&gt;{&quot;instance_extended_&quot;.$extend_meta} = $$extend_meta;
-        }
-
+        $this-&gt;instance_variables = call_class_method($this-&gt;class, 'properties');
+        $this-&gt;superclass = array_pop(class_parents($this-&gt;class));
         if ($this-&gt;respond_to('initialize')) {
             $arguments = func_get_args();
-            $this-&gt;call('send', 'initialize', $arguments);
+            $this-&gt;send_array('initialize', $arguments);
         }
     }
-
+    
     function __destruct() {
-        if ($this-&gt;respond_to('finalize')) $this-&gt;send('finalize');
-    }
-
-    function call($method, $arguments) {
-        $args = func_get_args();
-        $arguments = $this-&gt;extract_call_arguments($args);
-        return call_user_func_array(array($this, $method), $arguments);
-    }
-
-    function call_extended_method($method_name, $arguments) {
-        $args = func_get_args();
-        $arguments = $this-&gt;extract_call_arguments($args);
-        $callee = array_pop($this-&gt;instance_extended_methods[$method_name]);
-        eval('$result = '.build_function_call($callee, $arguments).';');
-        $this-&gt;instance_extended_methods[$method_name][] = $callee;
-        return $result;
+        if ($this-&gt;respond_to('finalize')) $this-&gt;send_array('finalize');
     }
-
-    function inspect() {
-        ob_start();
-        print_r($this);
-        return ob_get_clean();
-    }
-
-    function is_a($class) {
-        return $this instanceof $class;
-    }
-
-    function method_extended($method) {
-        return isset($this-&gt;instance_extended_methods[$method]);
-    }
-
-    function new_instance($arguments = null) {
-        $arguments = func_get_args();
-        return eval('return new '.build_function_call($this-&gt;class, $arguments).';');
-    }
-
+    
     function respond_to($method) {
-        return isset($this-&gt;instance_extended_methods[$method]) || in_array($method, get_class_methods(get_class($this)));
+        $methods = call_class_method($this-&gt;class, 'methods');
+        return in_array($method, get_class_methods($this-&gt;class)) || (in_array($method, array_keys($methods)) &amp;&amp; !empty($methods[$method]));
     }
-
-    function send($method, $arguments = null) {
-        $arguments = func_get_args();
-        $method = array_shift($arguments);
+    
+    function &amp;send_array($method, $arguments = array()) {
+        $methods = &amp;call_class_method($this-&gt;class, 'methods');
         if (!$this-&gt;respond_to($method)) {
-            trigger_error('Undefined method '.get_class($this).'::'.$method.'()', E_USER_ERROR);
-        } else if (isset($this-&gt;instance_extended_methods[$method]) &amp;&amp; !empty($this-&gt;instance_extended_methods[$method])) {
-            return $this-&gt;call_extended_method($method, $arguments);
+            trigger_error('Undefined method '.$this-&gt;class.'::'.$method.'()', E_USER_ERROR);
+        } else if (!isset($methods[$method]) || empty($methods[$method])) {
+            $result = call_user_func_array(array($this, $method), $arguments);
+            return $result;
         } else {
-            return $this-&gt;call($method, $arguments);
+            eval('$result = &amp;'.build_function_call($methods[$method][0], $arguments).';');
+            return $result;
         }
     }
-
-    function super($arguments = null) {
+    
+    function &amp;super($arguments = null) {
         $arguments = func_get_args();
         $caller = array_pop(array_slice(debug_backtrace(), 1, 1));
+        
         if (empty($caller)) {
-            trigger_error(get_class($this).'::super() must be called from inside of an instance method', E_USER_ERROR);
-        } else if ($this-&gt;respond_to($caller['function']) &amp;&amp; $caller['class'] != get_class($this)) {
-            return $this-&gt;call('send', $caller['function'], $arguments);
+            trigger_error($this-&gt;class.'::super() must be called from inside of an instance method', E_USER_ERROR);
         } else {
-            return eval('return '.build_function_call(array(get_parent_class($this), $caller['function']), $arguments).';');
+            $methods = &amp;call_class_method($this-&gt;class, 'methods');
+            $aliases = call_class_method($this-&gt;class, 'aliases');
+            $method = $caller['function'];
+            foreach (array_reverse($aliases) as $alias) {
+                if ($alias[1] == $method) {
+                    $method = $alias[0];
+                    break;
+                }
+            }
+            if (isset($methods[$method]) &amp;&amp; !empty($methods[$method])) {
+                $callee = array_shift($methods[$method]);
+                $result = &amp;$this-&gt;send_array($method, $arguments);
+                array_unshift($methods[$method], $callee);
+            } else {
+                eval('$result = &amp;'.build_function_call(array(get_parent_class($this), $method), $arguments).';');
+            }
+            return $result;
         }
     }
-
-    protected function __call($method, $arguments = array()) {
-        return $this-&gt;call('send', $method, $arguments);
+    
+    protected function &amp;__call($method, $arguments = array()) {
+        $result = &amp;$this-&gt;send_array('method_missing', array($method, $arguments));
+        return $result;
     }
-
-    protected function __get($key) {
-        if (isset($this-&gt;instance_extended_properties[$key])) {
-            return $this-&gt;instance_extended_properties[$key];
+    
+    protected function &amp;__get($property) {
+        if (isset($this-&gt;$property)) {
+            return $this-&gt;instance_variables[$property];
         } else {
-            trigger_error('Undefined property $'.$key, E_USER_ERROR);
+            $this-&gt;instance_variables = array_merge(call_class_method($this-&gt;class, 'properties'), $this-&gt;instance_variables);
+            if (isset($this-&gt;instance_variables[$property])) {
+                return $this-&gt;instance_variables[$property];
+            } else {
+                trigger_error('Undefined property $'.$property, E_USER_ERROR);
+            }
         }
     }
-
-    protected function __isset($key) {
-        return isset($this-&gt;instance_extended_properties[$key]);
+    
+    protected function __isset($property) {
+        return isset($this-&gt;instance_variables[$property]);
     }
-
-    protected function __set($key, $value) {
-        if (isset($this-&gt;instance_extended_properties[$key])) $this-&gt;instance_extended_properties[$key] = $value;
+    
+    protected function __set($property, $value) {
+        $this-&gt;instance_variables[$property] = $value;
     }
-
-    protected function __unset($key) {
-        unset($this-&gt;instance_extended_properties[$key]);
+    
+    protected function __unset($property) {
+        unset($this-&gt;instance_variables[$property]);
     }
+    
+}
 
-    protected function extract_call_arguments($args) {
-        array_shift($args);
-        $arguments = array_pop($args);
-        if (!is_array($arguments)) trigger_error('The last argument in '.get_class($this).'::extract_call_arguments() must be an array', E_USER_ERROR);
-        return array_merge($args, $arguments);
+abstract class ObjectMethods {
+    
+    function cloned() { }
+    
+    function dup() {
+        return clone $this;
     }
-
+    
+    function inspect() {
+        ob_start();
+        print_r($this);
+        return ob_get_clean();
+    }
+    
+    function instance_variables() {
+        return $this-&gt;instance_variables;
+    }
+    
+    function is_a($class) {
+        return $this instanceof $class;
+    }
+    
+    function &amp;method_missing($method, $arguments = array()) {
+        $result = &amp;$this-&gt;send_array($method, $arguments);
+        return $result;
+    }
+    
+    function &amp;send($method, $arguments = null) {
+        $arguments = func_get_args();
+        $method = array_shift($arguments);
+        $result = &amp;$this-&gt;send_array($method, $arguments);
+        return $result;
+    }
+    
 }
 
-?&gt;
\ No newline at end of file
+Object::extend('ObjectMethods', 'Delegator');
+
+Object::alias_method('is_an', 'is_a');
\ No newline at end of file</diff>
      <filename>lib/object.php</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,7 @@
 &lt;?php
 
+class Struct extends Object { }
+
 abstract class StructMethods {
     
     public $members = array();
@@ -14,9 +16,9 @@ abstract class StructMethods {
     }
     
     function instance($values) {
-        $instance = $this-&gt;new_instance($this-&gt;members);
+        $instance = call_class_method($this-&gt;class, 'new_instance', array($this-&gt;members));
         $values = func_get_args();
-        foreach ($this-&gt;members as $key =&gt; $member) extend_property($instance, $member, $values[$key]);
+        foreach ($this-&gt;members as $key =&gt; $member) $instance-&gt;$member = $values[$key];
         return $instance;
     }
     
@@ -25,13 +27,13 @@ abstract class StructMethods {
     }
     
     function to_a() {
-        $result = new A;
+        $result = new Arr;
         foreach ($this-&gt;members as $member) $result[] = $this-&gt;$member;
         return $result;
     }
     
     function to_h() {
-        $result = new H;
+        $result = new Hash;
         foreach ($this-&gt;members as $member) $result[$member] = $this-&gt;$member;
         return $result;
     }
@@ -43,13 +45,8 @@ abstract class StructMethods {
     
 }
 
-class Struct extends Object {
-    static $extended = array();
-}
-
-extend('Struct', 'StructMethods');
-alias_method('Struct', 'length', 'count');
-alias_method('Struct', 'size', 'count');
-alias_method('Struct', 'values', 'to_a');
+Struct::extend('StructMethods');
 
-?&gt;
\ No newline at end of file
+Struct::alias_method('length', 'count');
+Struct::alias_method('size', 'count');
+Struct::alias_method('values', 'to_a');
\ No newline at end of file</diff>
      <filename>lib/struct.php</filename>
    </modified>
    <modified>
      <diff>@@ -1,10 +1,7 @@
 &lt;?php
 
-require_once 'lib/functions.php';
-require_once 'lib/object.php';
-require_once 'lib/enumerable.php';
-require_once 'lib/array.php';
-require_once 'lib/hash.php';
-require_once 'lib/struct.php';
+if (!defined('DS')) define('DS', DIRECTORY_SEPARATOR);
 
-?&gt;
\ No newline at end of file
+require_once 'lib'.DS.'functions.php';
+
+spl_autoload_register('phuby_autoload');
\ No newline at end of file</diff>
      <filename>phuby.php</filename>
    </modified>
    <modified>
      <diff>@@ -4,12 +4,12 @@ require 'spec_helper.php';
 class Describe_Enumerable_Array extends SimpleSpec {
     
     function should_instantiate_a_array_object() {
-        $e = new A(array('ing', 'cool', 'wow'));
-        expects( $e )-&gt;should_be_a('A');
-        expects( $e )-&gt;should_be_a('Enumerable');
-        expects( $e )-&gt;should_be_a('Object');
+        $e = new Arr(array('ing', 'cool', 'wow'));
+        expect( $e )-&gt;should_be_a('Arr');
+        expect( $e )-&gt;should_be_a('Enumerable');
+        expect( $e )-&gt;should_be_a('Object');
         
-        expects($e-&gt;array)-&gt;should_be(array('ing', 'cool', 'wow'));
+        expect($e-&gt;array)-&gt;should_be(array('ing', 'cool', 'wow'));
     }
     
     function should_be_iteratable_with_foreach() {
@@ -18,27 +18,30 @@ class Describe_Enumerable_Array extends SimpleSpec {
         foreach ($e as $k =&gt; $v) {
             $results[] = $v;
         }
-        expects($results)-&gt;should_be(array('ing', 'cool', 'wow'));
+        expect($results)-&gt;should_be(array('ing', 'cool', 'wow'));
     }
     
     function should_provide_functional_iterators() {
         $e = a('ing', 'cool', 'wow');
-        expects($e-&gt;any('$value == &quot;ing&quot;;'))-&gt;should_be(true);
-        expects($e-&gt;any('$value == &quot;invalid&quot;;'))-&gt;should_be(false);
         
-        expects($e-&gt;map('strlen($value);')-&gt;array)-&gt;should_be(array(3,4,3));
+        expect($e-&gt;any('$value == &quot;ing&quot;;'))-&gt;should_be(true);
+        expect($e-&gt;any('$value == &quot;invalid&quot;;'))-&gt;should_be(false);
         
-        $rs = $e-&gt;reduce('', '$object .= $value;$object;');
-        expects($rs)-&gt;should_be('ingcoolwow');
+        expect($e-&gt;map('strlen($value);')-&gt;array)-&gt;should_be(array(3,4,3));
+        
+        $rs = $e-&gt;inject('', '$object .= $value;$object;');
+        expect($rs)-&gt;should_be('ingcoolwow');
 
     }
     
     function should_provide_enumeration_methods() {
-        # Enumerable#sort uses asort which maintain index association, make sense here?
-        expects(a(3,2,1)-&gt;sort()-&gt;array)-&gt;should_be(array(1,2,3));
+        //FIXME: uses asort which maintain index association, make sense here?
+        # Enumerable#sort 
+        expect(array_values(a(3,2,1)-&gt;sort()-&gt;array))-&gt;should_be(array(1,2,3));
         
         $e = a(1, 2, 3, a(4, 5, 6, a(7, 8, 9)));
-        expects($e-&gt;flatten()-&gt;array)-&gt;should_be(array(1,2,3,4,5,6,7,8,9));
+        
+        expect($e-&gt;flatten()-&gt;array)-&gt;should_be(array(1,2,3,4,5,6,7,8,9));
     }
 }
 </diff>
      <filename>spec/enumerable_spec.php</filename>
    </modified>
    <modified>
      <diff>@@ -6,20 +6,20 @@ class Describe_Object extends SimpleSpec {
     function should_be_able_to_invoke_overloaded_methods() {
         $t = new Testing;
         
-        expects($t-&gt;testing())-&gt;should_be('Whoa::testing');
+        expects($t-&gt;testing())-&gt;should_be('cooool');
         
-        expects($t-&gt;testing2())-&gt;should_be('Dude::testing2');
+        expects($t-&gt;testing2())-&gt;should_be('this is a returned value');
     }
     
     function should_dispatch_message_passing_using_method_send() {
         $t = new Testing;
-        expects($t-&gt;send('testing'))-&gt;should_be('Whoa::testing');
+        expects($t-&gt;send('testing'))-&gt;should_be('cooool');
         
     }
     
     function should_respond_to_a_implemented_method() {
         $t = new Testing;
-        
+
         expects($t-&gt;respond_to('real_method'))-&gt;should_be(true);
 
         expects($t-&gt;respond_to('testing'))-&gt;should_be(true);
@@ -41,12 +41,12 @@ class Describe_Object extends SimpleSpec {
     
     function should_call_parent_method_using_method_super() {
         $t = new Testing;
-        expects($t-&gt;super_test('sean'))-&gt;should_match('/Hello sean from Whoa::super_test/');
+        expects($t-&gt;super_test('sean'))-&gt;should_match('/Hello sean from super/');
     }
     
     function should_raise_error_when_caller_does_not_exists_for_method_super() {
         $t = new Testing;
-        // fixme: this is not working yet
+        //fixme: this is not working yet
         // $t-&gt;super();
         // $this-&gt;should_expect_error();
     }
@@ -55,28 +55,27 @@ class Describe_Object extends SimpleSpec {
 
 class Whoa {
     function super_test($name) {
-        return &quot;Hello {$name} from &quot;. __METHOD__;
+        return &quot;Hello {$name} from super&quot;;
     }
     
     function testing() {
-        return __METHOD__;
+        return 'cooool';
     }
 }
 
 class Dude {
     public $test_property = 'cool';
     
-    static function extended($object) {
-        if (is_object($object)) $object = get_class($object);
-        // echo $object.' extended Dude'.&quot;\n&quot;;
-    }
-    
     function super_test($name) {
-        return __METHOD__ . ' ' . $this-&gt;super($name);
+        return $this-&gt;super($name);
     }
     
     function testing2() {
-        return __METHOD__;
+        return 'this is a returned value';
+    }
+    
+    function delegated() {
+        return 'delegated from Dude'.&quot;\n&quot;;
     }
 }
 
@@ -88,10 +87,6 @@ class UhOh {
 
 class Testing extends Object {
     
-    function initialize() {
-        extend($this, 'Whoa', 'Dude');
-    }
-    
     function real_method() {
         return 'real_method';
     }
@@ -101,3 +96,4 @@ class Testing extends Object {
     }
     
 }
+Testing::extend('Whoa', 'Dude');</diff>
      <filename>spec/object_spec.php</filename>
    </modified>
    <modified>
      <diff>@@ -131,6 +131,12 @@ function expects($subject) {
     return $object-&gt;expect($subject);
 }
 
+function expect($subject) {
+    $trace = debug_backtrace();
+    $object = $trace[1]['object'];
+    return $object-&gt;expect($subject);
+}
+
 class Have_Matcher {
     function __construct($subject, $count, $runtime) {
         $this-&gt;subject = $subject;</diff>
      <filename>spec/simplespec.php</filename>
    </modified>
    <modified>
      <diff>@@ -2,7 +2,14 @@
 
 require_once '../phuby.php';
 
-$e = new A;
+// print_r(Enumerable::methods());
+
+// print_r(Module::$mixins);
+
+$e = new Arr;
+
+// print_r(Arr::mixins());
+// print_r(Arr::methods());
 
 $e[] = 'ing';
 $e[] = 'cool';
@@ -26,18 +33,13 @@ if ($e-&gt;any('$key == 1;')) echo &quot;true\n&quot;;
 if ($e-&gt;any('$key == 4;')) echo &quot;true\n&quot;;
 
 echo &quot;***INJECT***\n&quot;;
-print_r($e-&gt;inject(array(), '
-    $object[&quot;injected_$key&quot;] = $value;
-    $object;
-'));
-
-$e = new H;
+print_r($e-&gt;inject(array(), '$object[&quot;injected_$key&quot;] = $value;$object;'));
 
+$e = new Hash;
 $e['short'] = 4;
 $e['this is a longer one'] = 12;
 $e['this is long'] = 2;
 
-
 echo &quot;***ARRAY***\n&quot;;
 print_r($e-&gt;array);
 
@@ -48,11 +50,9 @@ echo &quot;***SORT_BY***\n&quot;;
 print_r($e-&gt;sort_by('strlen($key);')-&gt;array);
 
 echo &quot;***FLATTEN***\n&quot;;
-$e = new A(array(1, 2, 3, new A(array(4, 5, 6, new A(array(7, 8, 9))))));
+$e = new Arr(array(1, 2, 3, new Arr(array(4, 5, 6, new Arr(array(7, 8, 9))))));
 print_r($e-&gt;flatten()-&gt;array);
 
 echo &quot;***CHUNK***\n&quot;;
-$e = new A(array(1,2,3,4,5,6,7,8));
-print_r($e-&gt;chunk(3)-&gt;to_native_a());
-
-?&gt;
\ No newline at end of file
+$e = new Arr(array(1,2,3,4,5,6,7,8));
+print_r($e-&gt;chunk(3)-&gt;to_native_a());
\ No newline at end of file</diff>
      <filename>test/enumerable_test.php</filename>
    </modified>
    <modified>
      <diff>@@ -15,11 +15,6 @@ class Whoa {
 class Dude {
     public $test_property = 'cool';
     
-    static function extended($object) {
-        if (is_object($object)) $object = get_class($object);
-        // echo $object.' extended Dude'.&quot;\n&quot;;
-    }
-    
     function super_test($name) {
         echo &quot;I like the name $name\n&quot;;
         return $this-&gt;super($name);
@@ -29,6 +24,10 @@ class Dude {
         echo 'totally';
         return 'this is a returned value';
     }
+    
+    function delegated() {
+        echo 'delegated from Dude'.&quot;\n&quot;;
+    }
 }
 
 class UhOh {
@@ -39,10 +38,6 @@ class UhOh {
 
 class Testing extends Object {
     
-    function initialize() {
-        extend($this, 'Whoa', 'Dude');
-    }
-    
     function real_method() {
         return 'real_method';
     }
@@ -52,6 +47,7 @@ class Testing extends Object {
     }
     
 }
+Testing::extend('Whoa', 'Dude');
 
 $t = new Testing;
 
@@ -64,7 +60,7 @@ echo &quot;\n&quot;;
 echo $t-&gt;testing2();
 echo &quot;\n&quot;;
 
-$t-&gt;send('testing');
+echo $t-&gt;send('testing').' guy';
 echo &quot;\n&quot;;
 
 echo $t-&gt;respond_to('real_method');
@@ -88,7 +84,11 @@ echo &quot;\n&quot;;
 echo $t-&gt;is_a('Invalid');
 echo &quot;\n&quot;;
 
-// print_r($t);
+// $dup = $t-&gt;dup();
+// print_r($dup);
+
+Testing::delegate('delegated', 'Dude');
+$t-&gt;delegated();
 
 $t-&gt;super();
 </diff>
      <filename>test/object_test.php</filename>
    </modified>
    <modified>
      <diff>@@ -2,7 +2,8 @@
 
 require_once '../phuby.php';
 
-$customer = new Struct('first_name', 'last_name');
+// $customer = new Struct('first_name', 'last_name');
+$customer = Struct::new_instance('first_name', 'last_name');
 
 $sean = $customer-&gt;instance('Sean', 'Huber');
 </diff>
      <filename>test/struct_test.php</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>lib/array.php</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>224a4421b4915eae88b9e88e3ab77e6133a7ccc4</id>
    </parent>
  </parents>
  <author>
    <name>speedmax</name>
    <email>subjective@gmail.com</email>
  </author>
  <url>http://github.com/shuber/phuby/commit/804b2b936d410d45a393694289e0d0e607899103</url>
  <id>804b2b936d410d45a393694289e0d0e607899103</id>
  <committed-date>2009-06-11T20:17:53-07:00</committed-date>
  <authored-date>2009-06-11T20:17:53-07:00</authored-date>
  <message>Getting all spec running again and merge conflicts
 - cleanup proc unset into single function call
 - Fixed undefined constant error (DS) in phuby.php
 - Adding implicit return to evaluate_block</message>
  <tree>bf228044c8d0e00046b44c1349589fc4d5fc7630</tree>
  <committer>
    <name>speedmax</name>
    <email>subjective@gmail.com</email>
  </committer>
</commit>
