/** * Adds prototype method locally if argument matches signature * otherwise calls existing prototype methods * @param mixed $object * @param string $name * @param array $arguments * @return mixed * @throws prototypr\Exception */ static function call($object, $name, array $arguments = []) { $class = get_class($object); $uid = self::identify($object); // DOES PROTOTYPE EXIST, IF SO INVOKE IT if (($result = Registry::prototypes([$class, $uid], $name)) !== false) { if (count($arguments) === 1 && $arguments[0] instanceof \Closure) { self::callStatic(get_class($object), $name, $arguments); self::clearScope(); return $object; } // 99% WILL LAND HERE return self::invoke([$class, $uid], $name, $arguments, $object); } self::newScope($object); // ARE WE JUST ADDING A NEW PROTOTYPE? if (is_array($arguments) && count($arguments) > 0 && isset($arguments[0]) && $arguments[0] instanceof \Closure) { Registry::prototype([$object, $uid], $name, $arguments[0]); } else { throw new Exception('Method ("' . $name . '") not found ("' . get_class($object) . '")'); } self::clearScope(); return $object; }