Permalink
Browse files

- merged JooseX.Attribute and Singleton

  • Loading branch information...
1 parent 83a7dbb commit 2cfc4c4b824163263a4e378a926f92c3da518634 @SamuraiJack SamuraiJack committed Aug 27, 2011
View
@@ -52,6 +52,15 @@
'Joose.Namespace.Keeper',
'Joose.Namespace.Manager',
+
+ 'Joose.Attribute.Delegate',
+ 'Joose.Attribute.Trigger',
+ 'Joose.Attribute.Lazy',
+ 'Joose.Attribute.Accessor.Combined',
+ 'Joose.Attribute',
+
+ 'Joose.Meta.Singleton',
+
{
text : '})();'
},
@@ -64,18 +73,9 @@
minify : 'yui',
- contains : [
- '+All'
- ]
- },
-
-
- 'BackwardCompat' : {
-
- saveAs : 'lib/Task/Joose/Core.js',
-
contains : [
'+All'
]
}
}
+
View
@@ -1,4 +1,4 @@
-Joose = {}
+var Joose = {}
// configuration hash
@@ -18,6 +18,10 @@ Joose.stub = function () {
Joose.VERSION = ({ /*VERSION*/ }).VERSION
+if (typeof module != 'undefined') module.exports = Joose
+if (!Joose.is_NodeJS) this.Joose = Joose
+
+
// Static helpers for Arrays
Joose.A = {
View
@@ -0,0 +1,4 @@
+Joose.Managed.Attribute.meta.extend({
+ does : [ Joose.Attribute.Delegate, Joose.Attribute.Trigger, Joose.Attribute.Lazy, Joose.Attribute.Accessor.Combined ]
+})
+
@@ -0,0 +1,51 @@
+Role('Joose.Attribute.Accessor.Combined', {
+
+
+ have : {
+ isCombined : false
+ },
+
+
+ after : {
+ initialize : function() {
+ this.isCombined = this.isCombined || /..c/i.test(this.is)
+
+ if (this.isCombined) {
+ this.slot = '$$' + this.name
+
+ this.hasGetter = true
+ this.hasSetter = false
+
+ this.setterName = this.getterName = this.publicName
+ }
+ }
+ },
+
+
+ override : {
+
+ getGetter : function() {
+ var getter = this.SUPER()
+
+ if (!this.isCombined) return getter
+
+ var setter = this.getSetter()
+
+ var me = this
+
+ return function () {
+
+ if (!arguments.length) {
+ if (me.readable) return getter.call(this)
+ throw new Error("Call to getter of unreadable attribute: [" + me.name + "]")
+ }
+
+ if (me.writeable) return setter.apply(this, arguments)
+
+ throw new Error("Call to setter of read-only attribute: [" + me.name + "]")
+ }
+ }
+ }
+
+})
+
@@ -0,0 +1,67 @@
+Role('Joose.Attribute.Delegate', {
+
+ have : {
+ handles : null
+ },
+
+
+ override : {
+
+ eachDelegate : function (handles, func, scope) {
+ if (typeof handles == 'string') return func.call(scope, handles, handles)
+
+ if (handles instanceof Array)
+ return Joose.A.each(handles, function (delegateTo) {
+
+ func.call(scope, delegateTo, delegateTo)
+ })
+
+ if (handles === Object(handles))
+ Joose.O.eachOwn(handles, function (delegateTo, handleAs) {
+
+ func.call(scope, handleAs, delegateTo)
+ })
+ },
+
+
+ getAccessorsFor : function (targetClass) {
+ var targetMeta = targetClass.meta
+ var methods = this.SUPER(targetClass)
+
+ var me = this
+
+ this.eachDelegate(this.handles, function (handleAs, delegateTo) {
+
+ if (!targetMeta.hasMethod(handleAs)) {
+ var handler = methods[ handleAs ] = function () {
+ var attrValue = me.getValueFrom(this)
+
+ return attrValue[ delegateTo ].apply(attrValue, arguments)
+ }
+
+ handler.ACCESSOR_FROM = me
+ }
+ })
+
+ return methods
+ },
+
+
+ getAccessorsFrom : function (from) {
+ var methods = this.SUPER(from)
+
+ var me = this
+ var targetMeta = from.meta
+
+ this.eachDelegate(this.handles, function (handleAs) {
+
+ var handler = targetMeta.getMethod(handleAs)
+
+ if (handler && handler.value.ACCESSOR_FROM == me) methods.push(handleAs)
+ })
+
+ return methods
+ }
+ }
+})
+
@@ -0,0 +1,48 @@
+Role('Joose.Attribute.Lazy', {
+
+
+ have : {
+ lazy : null
+ },
+
+
+ before : {
+ computeValue : function () {
+ if (typeof this.init == 'function' && this.lazy) {
+ this.lazy = this.init
+ delete this.init
+ }
+ }
+ },
+
+
+ after : {
+ initialize : function () {
+ if (this.lazy) this.readable = this.hasGetter = true
+ }
+ },
+
+
+ override : {
+
+ getGetter : function () {
+ var original = this.SUPER()
+ var lazy = this.lazy
+
+ if (!lazy) return original
+
+ var me = this
+
+ return function () {
+ if (!me.hasValue(this)) {
+ var initializer = typeof lazy == 'function' ? lazy : this[ lazy.replace(/^this\./, '') ]
+
+ me.setValueTo(this, initializer.call(this, me))
+ }
+
+ return original.call(this)
+ }
+ }
+ }
+})
+
@@ -0,0 +1,42 @@
+Role('Joose.Attribute.Trigger', {
+
+ have : {
+ trigger : null
+ },
+
+
+ after : {
+ initialize : function() {
+ if (this.trigger) {
+ if (!this.writeable) throw new Error("Can't use `trigger` for read-only attributes")
+
+ this.hasSetter = true
+ }
+ }
+ },
+
+
+ override : {
+
+ getSetter : function() {
+ var original = this.SUPER()
+ var trigger = this.trigger
+
+ if (!trigger) return original
+
+ var me = this
+ var init = Joose.O.isFunction(me.init) ? null : me.init
+
+ return function () {
+ var oldValue = me.hasValue(this) ? me.getValueFrom(this) : init
+
+ var res = original.apply(this, arguments)
+
+ trigger.call(this, me.getValueFrom(this), oldValue)
+
+ return res
+ }
+ }
+ }
+})
+
@@ -19,7 +19,7 @@ At its simplest, an attribute can be thought of as a named value (as in a hash)
Attributes are also referred to as slots or properties.
-However, all the "attributes magic" is often skipped by beginners, as its generally an advanced topic. Thats why its provided outside of the core, as JooseX.Attribute extension.
+However, all the "attributes magic" is often skipped by beginners, as its generally an advanced topic. Thats why its provided outside of the core, as Joose.Attribute extension.
In this document we'll cover only the base capabilities of attributes, which are included in the core.
@@ -236,15 +236,15 @@ When declaring an attribute, you can change its default metaclass with the `meta
has : {
password : {
- meta : JooseX.Attribute.Hashed,
+ meta : Joose.Attribute.Hashed,
init : '12345',
hashType : 'SHA-1',
salt : 'custom_metaclass'
}
}
-In this case, the `password` attribute will be created using hypotetical `JooseX.Attribute.Hashed` metaclss, which probably will provide a special setter method, which replace the actual attribute value with its hashed version.
+In this case, the `password` attribute will be created using hypotetical `Joose.Attribute.Hashed` metaclss, which probably will provide a special setter method, which replace the actual attribute value with its hashed version.
There are a number of JooseX modules on JSAN which provide useful attribute metaclasses. See [Joose.Manual.JooseX][1] for some examples. You can also write your own metaclasses.
See the "Meta" and "Extending" recipes in [Joose.Cookbook][2] for examples.
@@ -260,7 +260,7 @@ To override an attribute, you simply re-declare it with desired properties.
MORE ON ATTRIBUTES
==================
-Joose attributes are a big topic, and this document glosses over a few aspects. We recommend that you read the [JooseX.Attribute][3] documentation as further reading.
+Joose attributes are a big topic, and this document glosses over a few aspects. We recommend that you read the [Joose.Attribute][3] documentation as further reading.
AUTHOR
======
@@ -19,7 +19,7 @@ Explaining how to write extensions is beyond the scope of this manual. Fortunate
This document covers a few of the ones we like best.
-JooseX.Attribute
+Joose.Attribute
================
If you only look at one extension, it should be this one. It provides a lot of additional features for class's attributes, including lazy initialization,
@@ -53,7 +53,7 @@ This lets you create much cleaner and fluent APIs.
}
})
-For further reading please refer to [JooseX.Attribute][attributex]
+For further reading please refer to [Joose.Attribute][attributex]
JooseX.Namespace.Depended
View
@@ -5,4 +5,6 @@ Joose.Meta.Object = new Joose.Proto.Class('Joose.Meta.Object', {
isa : Joose.Proto.Object
-}).c
+}).c
+
+
Oops, something went wrong.

0 comments on commit 2cfc4c4

Please sign in to comment.