public
Description: JavaScript utilities for Metaobject Programming
Clone URL: git://github.com/osteele/mop-js.git
more docs
osteele (author)
Sat Apr 19 08:14:34 -0700 2008
commit  453c22fd9b9492554b68991c5258757611280c50
tree    9e4f9b9c9f2020cc7eb3f33f536706480b580e84
parent  506acb13b61719cda32c836183636d91175f9b5f
0
...
1
 
2
3
 
 
4
5
6
7
8
 
9
10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
12
13
14
15
16
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 
 
 
 
 
 
 
 
 
 
 
 
 
32
33
34
35
36
37
38
39
 
40
41
 
 
42
43
44
45
46
 
 
...
 
1
2
 
3
4
5
 
 
 
 
6
7
 
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
 
 
 
 
 
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
 
 
 
 
 
83
 
 
 
 
 
 
84
85
86
87
88
89
90
91
92
93
94
95
96
97
 
 
 
 
 
 
98
99
100
 
101
102
103
104
105
106
 
107
108
0
@@ -1,46 +1,108 @@
0
-== JavaScript MOP Utilities
0
+= JavaScript MOP Utilities
0
 
0
-Defines some utilities for JavaScript metaprogramming:
0
+Defines some utilities for JavaScript metaprogramming. See the specs
0
+for examples.
0
 
0
- MOP.delegate(target, propertyName, methods)
0
- For each name in `methods`, defines a method on `target` with this
0
- name, that delegates to the method of the `propertyName` property
0
- of `target` with the same name.
0
+== Method Definition Methods
0
 
0
-And these for asynchronous metaprogramming:
0
+ MOP.Object(object).accessor(propertyName)
0
+ MOP.Class(klass).accessor(propertyName)
0
+
0
+Attaches +getXXX+ and +setXXX+ to +object+ or to
0
+<code>klass.prototype</code>. +XXX+ is the capitalized form of
0
++propertyName+; for example, +name+ generates +getName+ and +setName+.
0
+
0
+ MOP.Object(object).getter(propertyName)
0
+ MOP.Class(klass).getter(propertyName)
0
+
0
+Attaches +getXXX+ to +object+ or to <code>klass.prototype</code>.
0
++XXX+ is the capitalized form of +propertyName+; for example, +name+
0
+generates +getName+.
0
+
0
+ MOP.Object(object).delegate(propertyName, methods)
0
+ MOP.Class(klass).delegate(propertyName, methods)
0
+
0
+For each name in +methods+, defines a method on +object+ or
0
+<code>klass.prototype</code> with this name, that delegates to the
0
+method of the +propertyName+ property of +object+ with the same name.
0
+
0
+
0
+== Method Wrapper Methods
0
+
0
+ MOP.Object(object).method(methodName).guardBy(guardFn)
0
+ MOP.Class(klass).method(methodName).guardBy(guardFn)
0
+
0
+Replaces <code>object.methodName</code> by a method that calls the
0
+underlying method only if +guardFn+, applied to the same arguments,
0
+returns a true value.
0
+
0
+ MOP.Object(object).method(methodName).guardUntil(guardFn, ms)
0
+ MOP.Class(klass).method(methodName).guardUntil(guardFn, ms)
0
+
0
+A call to <code>object.methodName</code> causes a timer to
0
+periodically call +guardFn+ until it returns a true value, at which
0
+point the underlying function is called, and the timer stops.
0
+
0
+ MOP.Object(object).method(methodName).time(guardFn)
0
+ MOP.Class(klass).method(methodName).time(guardFn)
0
+
0
+Replaces <code>object.methodName</code> by a method that calls the
0
+underlying function, and prints to the console the name of the method
0
+and the time it took to execute.
0
+
0
+ MOP.Object(object).method(methodName).trace(guardFn)
0
+ MOP.Class(klass).method(methodName).trace(guardFn)
0
+
0
+Replaces <code>object.methodName</code> by a method that calls the
0
+underlying function, and prints to the console the name of the method
0
+and its return value.
0
+
0
+
0
+== Temporary Method Replacement
0
 
0
   new MOP.MethodReplacer(object, methods)
0
- When a new MethodReplacer is constructed, it replaces each method
0
- on `object` by the method in `methods` with the same key value, if
0
- such a method exists. A MethodReplacer has a single method,
0
- `restore`, which restores each method to its pre-replacement
0
- value.
0
+
0
+When a new MethodReplacer is constructed, it replaces each method
0
+on +object+ by the method in +methods+ with the same key value, if
0
+such a method exists. A MethodReplacer has a single method,
0
++restore+, which restores each method to its pre-replacement
0
+value.
0
+
0
+ MOP.withMethodOverridesCallback(object, methods, k)
0
+
0
+Calls +fn+ on +object+, within a dynamic scope within which the
0
+methods in +methods+ have temporarily replaced the like-named
0
+methods on +object+. The scope is terminated by the argument to
0
+the call to +k+; this argument should be treated as a
0
+continuation, and restores the methods.
0
+
0
+
0
+== Method Call Serialization
0
 
0
   new MOP.QueueBall(object, methodNames)
0
- When a new QueueBall is constructed, it replaces each method named
0
- by `methodNames` with a method that enqueues the method call (the
0
- name of the method and its arguments). A QueueBall has a single
0
- method, `replayMethodCalls`, which plays back the method calls and
0
- restores the methods.
0
 
0
- MOP.withMethodOverridesCallback(object, methods, fn)
0
- Calls `fn` on `object`, within a dynamic scope within which the
0
- methods in `methods` have temporarily replaced the like-named
0
- methods on `object`. The scope is terminated by the argument to
0
- the call to `fn`; this argument should be treated as a
0
- continuation, and restores the methods.
0
+When a new QueueBall is constructed, it replaces each method named
0
+by +methodNames+ with a method that enqueues the method call (the
0
+name of the method and its arguments). A QueueBall has a single
0
+method, +replayMethodCalls+, which plays back the method calls and
0
+restores the methods.
0
+
0
+ MOP.withDeferredMethods(object, methodNames, k)
0
+
0
+Calls +fn+ on +object+, within a dynamic scope within which the
0
+methods in +methodNames+ have been enqueued. The scope is
0
+terminated by the argument to the call to +k+; this argument
0
+should be treated as a continuation, and ends the queue, replaying
0
+the methods.
0
 
0
- MOP.withDeferredMethods(object, methodNames, fn)
0
- Calls `fn` on `object`, within a dynamic scope within which the
0
- methods in `methodNames` have been enqueued. The scope is
0
- terminated by the argument to the call to `fn`; this argument
0
- should be treated as a continuation, and ends the queue, replaying
0
- the methods.
0
 
0
+== Repository
0
 
0
-See the specs for examples.
0
+Download from http://github.com/osteele/mop-js, or clone from
0
+ git clone http://github.com/osteele/mop-js.git
0
 
0
 
0
 == License
0
 
0
-Copyright 2007-2008 by Oliver Steele. Available under the MIT License.
0
+Copyright 2007-2008 by Oliver Steele. All rights reserved.
0
+Available under the MIT License.
...
9
10
11
12
13
 
 
 
14
15
...
9
10
11
 
 
12
13
14
15
16
0
@@ -9,7 +9,8 @@
0
 <body>
0
 More examples are in <a
0
 href="../spec/mop-specs.html">mop-specs.html</a>. This file has
0
-examples that the test suite framework doesn't currently support.
0
-They write their results to the console.
0
+examples that the test suite framework doesn't currently support,
0
+because they run asynchronously or because they write their results
0
+to the console. Check the console to see the run results.
0
 </body>
0
 </html>
...
18
19
20
21
 
 
22
23
24
25
26
27
 
28
29
30
 
31
32
33
 
34
35
36
...
149
150
151
152
 
153
154
155
156
 
157
158
159
 
 
160
161
 
162
163
164
 
165
166
167
 
168
169
 
170
171
 
172
173
...
18
19
20
 
21
22
23
24
25
26
27
 
28
29
30
 
31
32
33
 
34
35
36
37
...
150
151
152
 
153
154
155
156
 
157
158
 
 
159
160
161
 
162
163
164
 
165
166
167
 
168
169
 
170
171
 
172
173
174
0
@@ -18,19 +18,20 @@ MOP = {
0
             return {
0
                 guardBy: function(guard) {
0
                     return replaceBy(function() {
0
- return guard() && fn.apply(this, arguments);
0
+ if (!guard.apply(this, arguments)) return;
0
+ fn.apply(this, arguments);
0
                     });
0
                 },
0
                 guardUntil: function(guard, ms) {
0
                     ms = ms || 1000;
0
                     return replaceBy(function() {
0
- var self = this,
0
+ var thisObject = this,
0
                             args = Array.prototype.slice.call(arguments, 0),
0
                             timer = setInterval(function() {
0
- if (!guard()) return;
0
+ if (!guard.apply(thisObject, args)) return;
0
                                 clearInterval(timer);
0
                                 restore();
0
- fn.apply(self, args);
0
+ fn.apply(thisObject, args);
0
                             }, ms);
0
                         return timer;
0
                     });
0
@@ -149,25 +150,25 @@ MOP = {
0
         }
0
     },
0
     
0
- /** Calls `fn` on `object`, within a dynamic scope within
0
+ /** Calls `k` on `object`, within a dynamic scope within
0
       * which the methods in `methods` have temporarily replaced
0
       * the like-named methods on `object`.
0
       * The scope is terminated by the argument to the call to
0
- * `fn`; this argument should be treated as a continuation,
0
+ * `k`; this argument should be treated as a continuation,
0
       * and restores the methods. */
0
- withMethodOverridesCallback: function(object, methods, fn) {
0
- if (!methods) return fn.call(object, function() {});
0
+ withMethodOverridesCallback: function(object, methods, k) {
0
+ if (!methods) return k.call(object, function() {});
0
         var replacer = new MOP.MethodReplacer(object, methods);
0
- return fn.call(object, replacer.restore);
0
+ return k.call(object, replacer.restore);
0
     },
0
     
0
- /** Calls `fn` on `object`, within a dynamic scope within
0
+ /** Calls `k` on `object`, within a dynamic scope within
0
       * which the methods in `methodNames` have been enqueued.
0
       * The scope is terminated by the argument to the call to
0
- * `fn`; this argument should be treated as a continuation,
0
+ * `k`; this argument should be treated as a continuation,
0
       * and ends the queue, replaying the methods. */
0
- withDeferredMethods: function(object, methodNames, fn) {
0
+ withDeferredMethods: function(object, methodNames, k) {
0
         var qball = new MOP.QueueBall(object, methodNames);
0
- return fn.call(object, qball.replayMethodCalls);
0
+ return k.call(object, qball.replayMethodCalls);
0
     }
0
 }

Comments

    No one has commented yet.