Nickolay - JooseX.Role.Parameterized-0.02

Documentation | Source
Class('JooseX.Role.Parameterized.Initializer', {
    
    meta    : Joose.Meta.Class,
    
    isa     : Joose.Meta.Role,
    
    
    has : {
        initializer        : null
    },
    
        
    builder : {
        
        methods : {
            
            initializer : function (meta, initializer) {
                meta.initializer = initializer
            }
        }
    
    },
    
    
    stem : {
        
        // this will cause the role to remain open after creation (we need to wait till the application moment)
        has : {
            firstConsumption    : true
        },
        
        
        methods : {
            
            beforeConsumedBy : function (targetStem) {
                if (this.firstConsumption) {
                    var targetMeta          = this.targetMeta
                    var initializer         = targetMeta.initializer
                    var consumingClass      = targetStem.targetMeta.c
                    
                    var res                 = initializer.meta.roleFunc.call(initializer, initializer, consumingClass)
                    
                    if (Joose.O.isFunction(res)) res = { does : res }
                    
                    targetMeta.extend(res)
                    
                    this.firstConsumption = false
                }
            }            
        }
    }  
});
Class('JooseX.Role.Parameterized', {
    
    meta    : Joose.Meta.Class,
    
    isa     : Joose.Meta.Class,
    
    does    : 'JooseX.Class.SimpleConstructor',
    
    use     : 'JooseX.Role.Parameterized.Initializer',
    
    
    has : {
        roleFunc        : null,
        introspect      : false
    },
    
        
    builder : {
        
        methods : {
            
            parameter : function (meta, info) {
                this.has(meta, info)
            },
            
            
            role : function (meta, roleFunc) {
                meta.roleFunc = roleFunc
            },
            
            
            introspect : function (meta, value) {
                meta.introspect = value
            }
        }
    
    },
    
    
    after : {
        
        processStem : function () {
            
            var meta = this
            
            // adds a default `initialize` method to any parameterized role 
            this.addMethod('initialize', function () {
                
                var roleFunc = meta.roleFunc
                
                if (!roleFunc) throw "The producing `role` function is not defined for [" + meta.name + "]"
                
                if (meta.introspect) 
                    return Role({
                        meta        : JooseX.Role.Parameterized.Initializer,
                        
                        initializer : this
                    })
                else {
                    var res = roleFunc.call(this, this)
                    
                    if (!Joose.O.isFunction(res)) res = Role(res)
                    
                    return res
                }
            })
        }
    }
    
});