Hi guys,
Phalcon is the best Framework I have ever seen, and Zephir surprise me, too. I have read the Zephir documents and explored a DI as Phalcon DI, and test it with phpunit. Amazing! it is easier more to explore php extensions with Zephir, but I still have some questions as bellow.
Q1: unexpected result return when using magic functions to register services. As the test show:
$di = new Dogstar\Di::getInstance();
$di->setName('dogstar');
$this->assertEquals($this->fdi->getName(), 'dogstar');It FAILED! it returned null not 'dogstar'. I debug it with my code, i found that DI::_$data become empty after I use Setter function. but i don't know why.
Q2: how can I call closure functions?
My DI Zephir Code as below:
//DI.zep
namespace Dogstar;
class Di implements \ArrayAccess
{
    protected static _instance = null;
    protected _data = [];
    public function __construct()
    {
    }
    public static function getInstance()
    {
        if (typeof self::_instance == "NULL") {
            let self::_instance = new Di();
            self::_instance->onConstruct();
        }
        self::_instance->onInitialize();
        return self::_instance;
    }
    public function onConstruct()
    {
        //TODO
    }
    public function onInitialize()
    {
        //TODO
    }
    public function set(var key, var value)
    {
        this->_checkKey(key);
        let this->_data[key] = value;
    }
    public function get(key, defaultValue = null, boolean isShare = false)
    {
        this->_checkKey(key);
        var value;
        if !(fetch value, this->_data[key]) {
            return defaultValue;
        }
        let value = this->_data[key];
        if gettype(value) == "object" && is_callable(value) {
            //TODO how to call clourse?
            //let value = {value}();
        } else {
            if is_string(value) && class_exists(value) {
                var tmp;
                let tmp = create_instance(value);
                let value = tmp;
                if gettype(value) == "object" && is_callable([value, "onConstruct"]) {
                    call_user_func([value, "onConstruct"]);
                }
                let isShare = false;
                return value;
            } else {
                //TODO
                //init by array configs
            }
        }
        if !isShare && gettype(value) == "object" && is_callable([value, "onInitialize"]) {
            call_user_func([value, "onInitialize"]);
        }
        let this->_data[key] = value;
        return value;
    }
    protected function _checkKey(var key)
    {
        if empty(key) || (!is_string(key) && !is_numeric(key)) {
            throw new \Exception("Unvalid key(" . gettype(key) . "), expect to string or numeric");
        }
    }
    public function __call(name, params)
    {
        var prefix;
        let prefix = substr(name, 0, 3);
        var key;
        let key = lcfirst(substr(name, 3, strlen(name)));
        var value = null;
        fetch value, params[0];
        if prefix == "get" {
            return this->get(key, value);
        }
        if prefix == "set" {
            this->set(key, value);
            return;
        }
        throw new \Exception("Call to undefined method Di::" . name . "()");
    }
    public function __set(key, value)
    {
        this->set(key, value);
    }
    public function __get(key)
    {
        return this->get(key, null, true);
    }
    public function offsetSet(offset, value)
    {
        this->set(offset, value);
    }
    public function offsetGet(offset)
    {
        return this->get(offset);
    }
    public function offsetUnset($offset)
    {
        unset(this->_data[offset]);
    }
    public function offsetExists(offset)
    {
        var value;
        return fetch value, this->_data[offset];
    }
}Could somebody help?