Commit | Line | Data |
---|---|---|
6a1aa64f DV |
1 | .. title:: MochiKit.Base - functional programming and useful comparisons |
2 | ||
3 | Name | |
4 | ==== | |
5 | ||
6 | MochiKit.Base - functional programming and useful comparisons | |
7 | ||
8 | ||
9 | Synopsis | |
10 | ======== | |
11 | ||
12 | :: | |
13 | ||
14 | myObjectRepr = function () { | |
15 | // gives a nice, stable string representation for objects, | |
16 | // ignoring any methods | |
17 | var keyValuePairs = []; | |
18 | for (var k in this) { | |
19 | var v = this[k]; | |
20 | if (typeof(v) != 'function') { | |
21 | keyValuePairs.push([k, v]); | |
22 | } | |
23 | }; | |
24 | keyValuePairs.sort(compare); | |
25 | return "{" + map( | |
26 | function (pair) { | |
27 | return map(repr, pair).join(":"); | |
28 | }, | |
29 | keyValuePairs | |
30 | ).join(", ") + "}"; | |
31 | }; | |
32 | ||
33 | // repr() will look for objects that have a repr method | |
34 | myObjectArray = [ | |
35 | {"a": 3, "b": 2, "repr": myObjectRepr}, | |
36 | {"a": 1, "b": 2, "repr": myObjectRepr} | |
37 | ]; | |
38 | ||
39 | // sort it by the "a" property, check to see if it matches | |
40 | myObjectArray.sort(keyComparator("a")); | |
41 | expectedRepr = '[{"a": 1, "b": 2}, {"a": 3, "b": 2}]'; | |
42 | assert( repr(myObjectArray) == expectedRepr ); | |
43 | ||
44 | // get just the "a" values out into an array | |
45 | sortedAValues = map(itemgetter("a"), myObjectArray); | |
46 | assert( compare(sortedAValues, [1, 3]) == 0 ); | |
47 | ||
48 | // serialize an array as JSON, unserialize it, expect something equivalent | |
49 | myArray = [1, 2, "3", null, undefined]; | |
50 | assert( objEqual(evalJSON(serializeJSON(myArray)), myArray) ); | |
51 | ||
52 | ||
53 | Description | |
54 | =========== | |
55 | ||
56 | :mochiref:`MochiKit.Base` is the foundation for the MochiKit suite. | |
57 | It provides: | |
58 | ||
59 | - An extensible comparison facility | |
60 | (:mochiref:`compare`, :mochiref:`registerComparator`) | |
61 | - An extensible programmer representation facility | |
62 | (:mochiref:`repr`, :mochiref:`registerRepr`) | |
63 | - An extensible JSON [1]_ serialization and evaluation facility | |
64 | (:mochiref:`serializeJSON`, :mochiref:`evalJSON`, | |
65 | :mochiref:`registerJSON`) | |
66 | - A simple adaptation facility (:mochiref:`AdapterRegistry`) | |
67 | - Convenience functions for manipulating objects and Arrays | |
68 | (:mochiref:`update`, :mochiref:`setdefault`, :mochiref:`extend`, etc.) | |
69 | - Array-based functional programming | |
70 | (:mochiref:`map`, :mochiref:`filter`, etc.) | |
71 | - Bound and partially applied functions | |
72 | (:mochiref:`bind`, :mochiref:`method`, :mochiref:`partial`) | |
73 | ||
74 | Python users will feel at home with :mochiref:`MochiKit.Base`, as the | |
75 | facilities are quite similar to those available as part of Python and | |
76 | the Python standard library. | |
77 | ||
78 | ||
79 | Dependencies | |
80 | ============ | |
81 | ||
82 | None. | |
83 | ||
84 | ||
85 | Overview | |
86 | ======== | |
87 | ||
88 | Comparison | |
89 | ---------- | |
90 | ||
91 | The comparators (operators for comparison) in JavaScript are deeply | |
92 | broken, and it is not possible to teach them new tricks. | |
93 | ||
94 | MochiKit exposes an extensible comparison facility as a simple | |
95 | :mochiref:`compare(a, b)` function, which should be used in lieu of | |
96 | JavaScript's operators whenever comparing objects other than numbers | |
97 | or strings (though you can certainly use :mochiref:`compare` for | |
98 | those, too!). | |
99 | ||
100 | The :mochiref:`compare` function has the same signature and return | |
101 | value as a sort function for ``Array.prototype.sort``, and is often | |
102 | used in that context. | |
103 | ||
104 | Defining new comparators for the :mochiref:`compare` function to use | |
105 | is done by adding an entry to its :mochiref:`AdapterRegistry` with the | |
106 | :mochiref:`registerComparator` function. | |
107 | ||
108 | ||
109 | Programmer Representation | |
110 | ------------------------- | |
111 | ||
112 | JavaScript's default representation mechanism, ``toString``, is | |
113 | notorious for having terrible default behavior. It's also very unwise | |
114 | to change that default, as other JavaScript code you may be using may | |
115 | depend on it. | |
116 | ||
117 | It's also useful to separate the concept of a "string representation" | |
118 | and a "string representation for programmers", much like Python does | |
119 | with its str and repr protocols. | |
120 | ||
121 | :mochiref:`repr` provides this programmer representation for | |
122 | JavaScript, in a way that doesn't require object prototype hacking: | |
123 | using an :mochiref:`AdapterRegistry`. | |
124 | ||
125 | Objects that implement the repr protocol can either implement a | |
126 | ``.repr()`` or ``.__repr__()`` method, or they can simply have an | |
127 | adapter setup to generate programmer representations. By default, the | |
128 | registry provides nice representations for ``null``, ``undefined``, | |
129 | ``Array``, and objects or functions with a ``NAME`` attribute that use | |
130 | the default ``toString``. For objects that ``repr`` doesn't already | |
131 | understand, it simply defaults to ``toString``, so it will integrate | |
132 | seamlessly with code that implements the idiomatic JavaScript | |
133 | ``toString`` method! | |
134 | ||
135 | To define a programmer representation for your own objects, simply add | |
136 | a ``.repr()`` or ``.__repr__()`` method that returns a string. For | |
137 | objects that you didn't create (e.g., from a script you didn't write, | |
138 | or a built-in object), it is instead recommended that you create an | |
139 | adapter with :mochiref:`registerRepr`. | |
140 | ||
141 | ||
142 | JSON Serialization | |
143 | ------------------ | |
144 | ||
145 | JSON [1]_, JavaScript Object Notation, is a widely used serialization | |
146 | format in the context of web development. It's extremely simple, | |
147 | lightweight, and fast. In its essence, JSON is a restricted subset of | |
148 | JavaScript syntax suitable for sending over the wire that can be | |
149 | unserialized with a simple eval. It's often used as an alternative to | |
150 | XML in "AJAX" contexts because it is compact, fast, and much simpler | |
151 | to use for most purposes. | |
152 | ||
153 | To create a JSON serialization of any object, simply call | |
154 | :mochiref:`serializeJSON()` with that object. To unserialize a JSON | |
155 | string, simply call :mochiref:`evalJSON()` with the serialization. | |
156 | ||
157 | In order of precedence, :mochiref:`serializeJSON` coerces the given | |
158 | argument into a JSON serialization: | |
159 | ||
160 | 1. Primitive types are returned as their JSON representation: | |
161 | ``string``, ``number``, ``boolean``, ``null``. | |
162 | 2. If the object has a ``__json__`` or ``json`` method, then it is | |
163 | called with no arguments. If the result of this method is not the | |
164 | object itself, then the new object goes through rule processing | |
165 | again (e.g. it may return a string, which is then serialized in | |
166 | JSON format). | |
167 | 3. If the object is ``Array``-like (has a ``length`` property that is | |
168 | a number, and is not a function), then it is serialized as a JSON | |
169 | array. Each element will be processed according to these rules in | |
170 | order. Elements that can not be serialized (e.g. functions) will | |
171 | be replaced with ``undefined``. | |
172 | 4. The ``jsonRegistry`` :mochiref:`AdapterRegistry` is consulted for | |
173 | an adapter for this object. JSON adapters take one argument (the | |
174 | object), and are expected to behave like a ``__json__`` or | |
175 | ``json`` method (return another object to be serialized, or | |
176 | itself). | |
177 | 5. If the object is ``undefined``, a ``TypeError`` is thrown. If you | |
178 | wish to serialize ``undefined`` as ``null`` or some other value, you | |
179 | should create an adapter to do so. | |
180 | 6. If no adapter is available, the object is enumerated and | |
181 | serialized as a JSON object (name:value pairs). All names are | |
182 | expected to be strings. Each value is serialized according to | |
183 | these rules, and if it can not be serialized (e.g. methods), then | |
184 | that name:value pair will be skipped. | |
185 | ||
186 | ||
187 | Adapter Registries | |
188 | ------------------ | |
189 | ||
190 | MochiKit makes extensive use of adapter registries, which enable you | |
191 | to implement object-specific behaviors for objects that you do not | |
192 | necessarily want to modify, such as built-in objects. This is | |
193 | especially useful because JavaScript does not provide a method for | |
194 | hiding user-defined properties from ``for propName in obj`` | |
195 | enumeration. | |
196 | ||
197 | :mochiref:`AdapterRegistry` is simply an encapsulation for an ordered | |
198 | list of "check" and "wrap" function pairs. Each | |
199 | :mochiref:`AdapterRegistry` instance should perform one function, but | |
200 | may have multiple ways to achieve that function based upon the | |
201 | arguments. One way to think of it is as a poor man's generic function, | |
202 | or multiple dispatch (on arbitrary functions, not just type!). | |
203 | ||
204 | Check functions take one or more arguments, and return ``true`` if the | |
205 | argument list is suitable for the wrap function. Check functions | |
206 | should perform "cheap" checks of an object's type or contents, before | |
207 | the "expensive" wrap function is called. | |
208 | ||
209 | Wrap functions take the same arguments as check functions and do some | |
210 | operation, such as creating a programmer representation or comparing | |
211 | both arguments. | |
212 | ||
213 | ||
214 | Convenience Functions | |
215 | --------------------- | |
216 | ||
217 | Much of :mochiref:`MochiKit.Base` is there to simply remove the grunt | |
218 | work of doing generic JavaScript programming. | |
219 | ||
220 | Need to take every property from one object and set them on another? | |
221 | No problem, just call :mochiref:`update(dest, src)`! What if you just | |
222 | wanted to update keys that weren't already set? Look no further than | |
223 | :mochiref:`setdefault(dest, src[, ...])`. | |
224 | ||
225 | Want to return a mutable object, but don't want to suffer the | |
226 | consequences if the user mutates it? Just :mochiref:`clone(it)` and | |
227 | you'll get a copy-on-write clone. Cheaper than a copy! | |
228 | ||
229 | Need to extend an ``Array`` with another array? Or even an | |
230 | ``Array``-like object such as a ``NodeList`` or the special | |
231 | ``arguments`` object? Even if you need to skip the first few elements | |
232 | of the source ``Array``-like object, it's no problem with | |
233 | :mochiref:`extend(dstArray, srcArrayLike[, skip])`! | |
234 | ||
235 | Wouldn't it be convenient to have all of the JavaScript operators were | |
236 | available as functions somewhere? That's what the | |
237 | :mochiref:`operators` table is for, and it even comes with additional | |
238 | operators based on the :mochiref:`compare` function. | |
239 | ||
240 | Need to walk some tree of objects and manipulate or find something in | |
241 | it? A DOM element tree perhaps? Use :mochiref:`nodeWalk(node, | |
242 | visitor)`! | |
243 | ||
244 | There's plenty more, so check out the `API Reference`_ below. | |
245 | ||
246 | ||
247 | Functional Programming | |
248 | ---------------------- | |
249 | ||
250 | Functional programming constructs such as :mochiref:`map` and | |
251 | :mochiref:`filter` can save you a lot of time, because JavaScript | |
252 | iteration is error-prone and arduous. Writing less code is the best | |
253 | way to prevent bugs, and functional programming can help you do that. | |
254 | ||
255 | :mochiref:`MochiKit.Base` ships with a few simple Array-based | |
256 | functional programming constructs, namely :mochiref:`map` and | |
257 | :mochiref:`filter`, and their "extended" brethren, :mochiref:`xmap` | |
258 | and :mochiref:`xfilter`. | |
259 | ||
260 | :mochiref:`map(func, arrayLike[, ...])` takes a function and an | |
261 | ``Array``-like object, and creates a new ``Array``. The new ``Array`` | |
262 | is the result of ``func(element)`` for every element of ``arrayLike``, | |
263 | much like the ``Array.prototype.map`` extension in Mozilla. However, | |
264 | :mochiref:`MochiKit.Base` takes that a step further and gives you the | |
265 | full blown Python version of :mochiref:`map`, which will take several | |
266 | ``Array``-like objects, and calls the function with one argument per | |
267 | given ``Array``-like, e.g.:: | |
268 | ||
269 | var arrayOne = [1, 2, 3, 4, 5]; | |
270 | var arrayTwo = [1, 5, 2, 4, 3]; | |
271 | var arrayThree = [5, 2, 1, 3, 4]; | |
272 | var biggestElements = map(objMax, arrayOne, arrayTwo, arrayThree); | |
273 | assert( objEqual(biggestElements, [5, 5, 3, 4, 5]) ); | |
274 | ||
275 | :mochiref:`filter(func, arrayLike[, self])` takes a function and an | |
276 | ``Array``-like object, and returns a new ``Array``. This is basically | |
277 | identical to the ``Array.prototype.filter`` extension in | |
278 | Mozilla. self, if given, will be used as ``this`` in the context of | |
279 | func when called. | |
280 | ||
281 | :mochiref:`xmap` and :mochiref:`xfilter` are just special forms of | |
282 | :mochiref:`map` and :mochiref:`filter` that accept a function as the | |
283 | first argument, and use the extra arguments as the ``Array``-like. Not | |
284 | terribly interesting, but a definite time-saver in some cases. | |
285 | ||
286 | If you appreciate the functional programming facilities here, you | |
287 | should definitely check out :mochiref:`MochiKit.Iter`, which provides | |
288 | full blown iterators, :mochiref:`MochiKit.Iter.range`, | |
289 | :mochiref:`MochiKit.Iter.reduce`, and a near-complete port of Python's | |
290 | itertools [2]_ module, with some extra stuff thrown in for good | |
291 | measure! | |
292 | ||
293 | ||
294 | Bound and Partial Functions | |
295 | --------------------------- | |
296 | ||
297 | JavaScript's method-calling special form and lack of bound functions | |
298 | (functions that know what ``this`` should be) are one of the first | |
299 | stumbling blocks that programmers new to JavaScript face. The | |
300 | :mochiref:`bind(func, self)` method fixes that right up by returning a | |
301 | new function that calls func with the right ``this``. | |
302 | ||
303 | In order to take real advantage of all this fancy functional | |
304 | programming stuff, you're probably going to want partial | |
305 | application. This allows you to create a new function from an existing | |
306 | function that remembers some of the arguments. For example, if you | |
307 | wanted to compare a given object to a slew of other objects, you could | |
308 | do something like this:: | |
309 | ||
310 | compareWithOne = partial(compare, 1); | |
311 | results = map(compareWithOne, [0, 1, 2, 3]); | |
312 | assert( objEqual(results, [-1, 0, 1, 1]) ); | |
313 | ||
314 | One of the better uses of partial functions is in | |
315 | :mochiref:`MochiKit.DOM`, which is certainly a must-see for those of | |
316 | you creating lots of DOM elements with JavaScript! | |
317 | ||
318 | ||
319 | API Reference | |
320 | ============= | |
321 | ||
322 | Errors | |
323 | ------ | |
324 | ||
325 | :mochidef:`NotFound`: | |
326 | ||
327 | A singleton error raised when no suitable adapter is found | |
328 | ||
329 | *Availability*: | |
330 | Available in MochiKit 1.3.1+ | |
331 | ||
332 | ||
333 | Constructors | |
334 | ------------ | |
335 | ||
336 | :mochidef:`AdapterRegistry`: | |
337 | ||
338 | A registry to facilitate adaptation. | |
339 | ||
340 | All ``check``/``wrap`` function pairs in a given registry should | |
341 | take the same number of arguments. | |
342 | ||
343 | *Availability*: | |
344 | Available in MochiKit 1.3.1+ | |
345 | ||
346 | ||
347 | :mochidef:`AdapterRegistry.prototype.register(name, check, wrap[, override])`: | |
348 | ||
349 | ``name``: | |
350 | a unique identifier used to identify this adapter so that it | |
351 | may be unregistered. | |
352 | ||
353 | ``check``: | |
354 | function that should return ``true`` if the given arguments | |
355 | are appropriate for the ``wrap`` function. | |
356 | ||
357 | ``wrap``: | |
358 | function that takes the same parameters as ``check`` and does | |
359 | the adaptation. Every ``wrap``/``check`` function pair in the | |
360 | registry should have the same number of arguments. | |
361 | ||
362 | ``override``: | |
363 | if ``true``, the ``check`` function will be | |
364 | given highest priority. Otherwise, the lowest. | |
365 | ||
366 | *Availability*: | |
367 | Available in MochiKit 1.3.1+ | |
368 | ||
369 | ||
370 | :mochidef:`AdapterRegistry.prototype.match(obj[, ...])`: | |
371 | ||
372 | Find an adapter for the given arguments by calling every ``check`` | |
373 | function until one returns ``true``. | |
374 | ||
375 | If no suitable adapter is found, throws :mochiref:`NotFound`. | |
376 | ||
377 | *Availability*: | |
378 | Available in MochiKit 1.3.1+ | |
379 | ||
380 | ||
381 | :mochidef:`AdapterRegistry.prototype.unregister(name)`: | |
382 | ||
383 | Remove a named adapter from the registry | |
384 | ||
385 | *Availability*: | |
386 | Available in MochiKit 1.3.1+ | |
387 | ||
388 | ||
389 | :mochidef:`NamedError`: | |
390 | ||
391 | Convenience constructor for creating new errors | |
392 | (e.g. :mochiref:`NotFound`) | |
393 | ||
394 | *Availability*: | |
395 | Available in MochiKit 1.3.1+ | |
396 | ||
397 | ||
398 | Functions | |
399 | --------- | |
400 | ||
401 | :mochidef:`arrayEqual(self, arr)`: | |
402 | ||
403 | Compare the arrays ``self`` and ``arr`` for equality using | |
404 | ``compare`` on each element. Uses a fast-path for length | |
405 | differences. | |
406 | ||
407 | *Availability*: | |
408 | Available in MochiKit 1.3.1+ | |
409 | ||
410 | ||
411 | :mochidef:`average(lst[, ...])`: | |
412 | ||
413 | This function is an alias of :mochiref:`mean()`. | |
414 | ||
415 | *Availability*: | |
416 | Available in MochiKit 1.3.1+ | |
417 | ||
418 | ||
419 | :mochidef:`bind(func, self[, arg, ...])`: | |
420 | ||
421 | Return a copy of ``func`` bound to ``self``. This means whenever | |
422 | and however the returned function is called, ``this`` will always | |
423 | reference the given ``self``. ``func`` may be either a function | |
424 | object, or a string. If it is a string, then ``self[func]`` will | |
425 | be used, making these two statements equivalent:: | |
426 | ||
427 | bind("method", self); | |
428 | bind(self.method, self); | |
429 | ||
430 | Calling :mochiref:`bind(func, self)` on an already bound function | |
431 | will return a new function that is bound to the new ``self``! If | |
432 | ``self`` is ``undefined``, then the previous ``self`` is used. If | |
433 | ``self`` is ``null``, then the ``this`` object is used (which may | |
434 | or may not be the global object). To force binding to the global | |
435 | object, you should pass it explicitly. | |
436 | ||
437 | Additional arguments, if given, will be partially applied to the | |
438 | function. These three expressions are equivalent and return | |
439 | equally efficient functions (:mochiref:`bind` and | |
440 | :mochiref:`partial` share the same code path): | |
441 | ||
442 | - :mochiref:`bind(oldfunc, self, arg1, arg2)` | |
443 | - :mochiref:`bind(partial(oldfunc, arg1, arg2), self)` | |
444 | - :mochiref:`partial(bind(oldfunc, self), arg1, arg2)` | |
445 | ||
446 | *Availability*: | |
447 | Available in MochiKit 1.3.1+ | |
448 | ||
449 | ||
450 | :mochidef:`bindMethods(self)`: | |
451 | ||
452 | Replace all functions ``meth`` on ``self`` with | |
453 | :mochiref:`bind(meth, self)`. This emulates Python's bound | |
454 | instance methods, where there is no need to worry about preserving | |
455 | ``this`` when the method is used as a callback. | |
456 | ||
457 | *Availability*: | |
458 | Available in MochiKit 1.3.1+ | |
459 | ||
460 | ||
461 | :mochidef:`camelize(str)`: | |
462 | ||
463 | Converts hyphenated strings to camelCase:: | |
464 | ||
465 | assert( camelize("border-left") == "borderLeft" ); | |
466 | ||
467 | *Availability*: | |
468 | Available in MochiKit 1.4+ | |
469 | ||
470 | ||
471 | :mochidef:`clone(obj)`: | |
472 | ||
473 | Return a new object using ``obj`` as its prototype. Use this if | |
474 | you want to return a mutable object (e.g. instance state), but | |
475 | don't want the user to mutate it. If they do, it won't have any | |
476 | effect on the original ``obj``. | |
477 | ||
478 | Note that this is a shallow clone, so mutable properties will have | |
479 | to be cloned separately if you want to "protect" them. | |
480 | ||
481 | *Availability*: | |
482 | Available in MochiKit 1.3.1+ | |
483 | ||
484 | ||
485 | :mochidef:`compare(a, b)`: | |
486 | ||
487 | Compare two objects in a sensible manner. Currently this is: | |
488 | ||
489 | 1. ``undefined`` and ``null`` compare equal to each other | |
490 | 2. ``undefined`` and ``null`` are less than anything else | |
491 | 3. If JavaScript says ``a == b``, then we trust it | |
492 | 4. comparators registered with registerComparator are used to | |
493 | find a good comparator. Built-in comparators are currently | |
494 | available for ``Array``-like and ``Date``-like objects. | |
495 | 5. Otherwise hope that the built-in comparison operators do | |
496 | something useful, which should work for numbers and strings. | |
497 | 6. If neither ``a < b`` or ``a > b``, then throw a ``TypeError`` | |
498 | ||
499 | Returns what one would expect from a comparison function: | |
500 | ||
501 | +-----------+---------------+ | |
502 | | Value | Condition | | |
503 | +-----------+---------------+ | |
504 | | ``0`` | ``a == b`` | | |
505 | +-----------+---------------+ | |
506 | | ``1`` | ``a > b`` | | |
507 | +-----------+---------------+ | |
508 | | ``-1`` | ``a < b`` | | |
509 | +-----------+---------------+ | |
510 | ||
511 | *Availability*: | |
512 | Available in MochiKit 1.3.1+ | |
513 | ||
514 | ||
515 | :mochidef:`compose(f1, f2, ..., fN)`: | |
516 | ||
517 | Return a new function as the combination of the given function | |
518 | arguments, equivalent to ``f1(f2(arguments))``. | |
519 | ||
520 | *Availability*: | |
521 | Available in MochiKit 1.4+ | |
522 | ||
523 | ||
524 | :mochidef:`concat(lst[, ...])`: | |
525 | ||
526 | Concatenates all given ``Array``-like arguments and returns | |
527 | a new ``Array``:: | |
528 | ||
529 | var lst = concat(["1","3","5"], ["2","4","6"]); | |
530 | assert( lst.toString() == "1,3,5,2,4,6" ); | |
531 | ||
532 | *Availability*: | |
533 | Available in MochiKit 1.3.1+ | |
534 | ||
535 | ||
536 | :mochidef:`counter(n=1)`: | |
537 | ||
538 | Returns a function that will return a number one greater than | |
539 | the previous returned value, starting at ``n``. For example:: | |
540 | ||
541 | nextId = counter() | |
542 | assert( nextId() == 1 ) | |
543 | assert( nextId() == 2 ) | |
544 | ||
545 | For an iterator with this behavior, see | |
546 | :mochiref:`MochiKit.Iter.count`. | |
547 | ||
548 | *Availability*: | |
549 | Available in MochiKit 1.3.1+ | |
550 | ||
551 | ||
552 | :mochidef:`extend(self, obj, skip=0)`: | |
553 | ||
554 | Mutate the array ``self`` by extending it with an ``Array``-like | |
555 | ``obj``, starting from index ``skip``. If ``null`` is given as the | |
556 | initial array, a new one will be created. | |
557 | ||
558 | This mutates *and returns* ``self``, be warned. | |
559 | ||
560 | *Availability*: | |
561 | Available in MochiKit 1.3.1+ | |
562 | ||
563 | ||
564 | :mochidef:`evalJSON(aJSONString)`: | |
565 | ||
566 | Unserialize a JSON [1]_ represenation of an object. | |
567 | ||
568 | Note that this uses the ``eval`` function of the interpreter, and | |
569 | therefore trusts the contents of ``aJSONString`` to be safe. This | |
570 | is acceptable when the JSON and JavaScript application originate | |
571 | from the same server, but in other scenarios it may not be the | |
572 | appropriate security model. Currently, a validating JSON parser is | |
573 | beyond the scope of MochiKit, but there is one available from | |
574 | json.org [1]_. | |
575 | ||
576 | *Availability*: | |
577 | Available in MochiKit 1.3.1+ | |
578 | ||
579 | ||
580 | :mochidef:`filter(fn, lst)`: | |
581 | ||
582 | Returns a new ``Array`` composed of all elements from ``lst`` | |
583 | where ``fn(lst[i])`` returns a true value. | |
584 | ||
585 | If ``fn`` is ``null``, ``operator.truth`` will be used. | |
586 | ||
587 | *Availability*: | |
588 | Available in MochiKit 1.3.1+ | |
589 | ||
590 | ||
591 | :mochidef:`findValue(lst, value, start=0, end=lst.length)`: | |
592 | ||
593 | Finds the index of ``value`` in the ``Array``-like object ``lst`` | |
594 | using :mochiref:`compare`. The search starts at the index | |
595 | ``start``, and ends at the index ``end - 1``. If ``value`` is not | |
596 | found in ``lst``, it will return ``-1``. | |
597 | ||
598 | For example:: | |
599 | ||
600 | assert( findValue([1, 2, 3, 2, 1], 2) == 1 ) | |
601 | assert( findValue([1, 2, 3, 2, 1], 2, 2) == 3 ) | |
602 | ||
603 | *Availability*: | |
604 | Available in MochiKit 1.3.1+ | |
605 | ||
606 | ||
607 | :mochidef:`findIdentical(lst, value, start=0, end=lst.length)`: | |
608 | ||
609 | Finds the index of ``value`` in the ``Array``-like object ``lst`` | |
610 | using the ``===`` operator. The search starts at the index | |
611 | ``start``, and ends at the index ``end - 1``. If ``value`` is not | |
612 | found in ``lst``, it will return ``-1``. | |
613 | ||
614 | You should use this function instead of :mochiref:`findValue` if | |
615 | ``lst`` may be comprised of objects for which no comparator is | |
616 | defined and all you care about is finding an identical object | |
617 | (e.g. the same instance), or if ``lst`` is comprised of just | |
618 | numbers or strings and performance is important. | |
619 | ||
620 | For example:: | |
621 | ||
622 | assert( findIdentical([1, 2, 3, 2, 1], 2) == 1 ) | |
623 | assert( findIdentical([1, 2, 3, 2, 1], 2, 2) == 3 ) | |
624 | ||
625 | *Availability*: | |
626 | Available in MochiKit 1.3.1+ | |
627 | ||
628 | ||
629 | :mochidef:`flattenArguments(arg[, ...])`: | |
630 | ||
631 | Given a bunch of arguments, return a single ``Array`` containing | |
632 | all of those arguments. Any ``Array``-like argument will be extended | |
633 | in-place, e.g.:: | |
634 | ||
635 | compare(flattenArguments(1, [2, 3, [4, 5]]), [1, 2, 3, 4, 5]) == 0 | |
636 | ||
637 | *Availability*: | |
638 | Available in MochiKit 1.3.1+ | |
639 | ||
640 | ||
641 | :mochidef:`flattenArray(lst)`: | |
642 | ||
643 | Return a new ``Array`` consisting of every item in lst with ``Array`` | |
644 | items expanded in-place recursively. This differs from | |
645 | :mochiref:`flattenArguments` in that it only takes one argument and | |
646 | it only flattens items that are ``instanceof Array``. | |
647 | ||
648 | compare(flattenArray([1, [2, 3, [4, 5]]]), [1, 2, 3, 4, 5]) == 0 | |
649 | ||
650 | *Availability*: | |
651 | Available in MochiKit 1.4+ | |
652 | ||
653 | ||
654 | :mochidef:`forwardCall(name)`: | |
655 | ||
656 | Returns a function that forwards a method call to | |
657 | ``this.name(...)`` | |
658 | ||
659 | *Availability*: | |
660 | Available in MochiKit 1.3.1+ | |
661 | ||
662 | ||
663 | :mochidef:`isArrayLike(obj[, ...])`: | |
664 | ||
665 | Returns ``true`` if all given arguments are ``Array``-like (have a | |
666 | ``.length`` property and ``typeof(obj) == 'object'``) | |
667 | ||
668 | *Availability*: | |
669 | Available in MochiKit 1.3.1+ | |
670 | ||
671 | ||
672 | :mochidef:`isDateLike(obj[, ...])`: | |
673 | ||
674 | Returns ``true`` if all given arguments are ``Date``-like (have a | |
675 | ``.getTime()`` method) | |
676 | ||
677 | *Availability*: | |
678 | Available in MochiKit 1.3.1+ | |
679 | ||
680 | ||
681 | :mochidef:`isEmpty(obj[, ...])`: | |
682 | ||
683 | Returns ``true`` if all the given ``Array``-like or string | |
684 | arguments are empty ``(obj.length == 0)`` | |
685 | ||
686 | *Availability*: | |
687 | Available in MochiKit 1.3.1+ | |
688 | ||
689 | ||
690 | :mochidef:`isNotEmpty(obj[, ...])`: | |
691 | ||
692 | Returns ``true`` if all the given ``Array``-like or string | |
693 | arguments are not empty ``(obj.length > 0)`` | |
694 | ||
695 | *Availability*: | |
696 | Available in MochiKit 1.3.1+ | |
697 | ||
698 | ||
699 | :mochidef:`isNull(obj[, ...])`: | |
700 | ||
701 | Returns ``true`` if all arguments are ``null``. | |
702 | ||
703 | *Availability*: | |
704 | Available in MochiKit 1.3.1+ | |
705 | ||
706 | ||
707 | :mochidef:`isUndefinedOrNull(obj[, ...])`: | |
708 | ||
709 | Returns ``true`` if all arguments are undefined or ``null`` | |
710 | ||
711 | *Availability*: | |
712 | Available in MochiKit 1.3.1+ | |
713 | ||
714 | ||
715 | :mochidef:`itemgetter(name)`: | |
716 | ||
717 | Returns a ``function(obj)`` that returns ``obj[name]`` | |
718 | ||
719 | *Availability*: | |
720 | Available in MochiKit 1.3.1+ | |
721 | ||
722 | ||
723 | :mochidef:`items(obj)`: | |
724 | ||
725 | Return an ``Array`` of ``[propertyName, propertyValue]`` pairs for | |
726 | the given ``obj`` (in the order determined by ``for propName in | |
727 | obj``). | |
728 | ||
729 | *Availability*: | |
730 | Available in MochiKit 1.3.1+ | |
731 | ||
732 | ||
733 | :mochidef:`keyComparator(key[, ...])`: | |
734 | ||
735 | A comparator factory that compares ``a[key]`` with ``b[key]``. | |
736 | e.g.:: | |
737 | ||
738 | var lst = ["a", "bbb", "cc"]; | |
739 | lst.sort(keyComparator("length")); | |
740 | assert( lst.toString() == "a,cc,bbb" ); | |
741 | ||
742 | *Availability*: | |
743 | Available in MochiKit 1.3.1+ | |
744 | ||
745 | ||
746 | :mochidef:`keys(obj)`: | |
747 | ||
748 | Return an ``Array`` of the property names of an object (in the | |
749 | order determined by ``for propName in obj``). | |
750 | ||
751 | *Availability*: | |
752 | Available in MochiKit 1.3.1+ | |
753 | ||
754 | ||
755 | :mochidef:`listMax(lst)`: | |
756 | ||
757 | Return the largest element of an ``Array``-like object, as | |
758 | determined by :mochiref:`compare`. This is a special form of | |
759 | :mochiref:`listMinMax`, specifically | |
760 | :mochiref:`partial(listMinMax, 1)`. | |
761 | ||
762 | *Availability*: | |
763 | Available in MochiKit 1.3.1+ | |
764 | ||
765 | ||
766 | :mochidef:`listMin(lst)`: | |
767 | ||
768 | Return the smallest element of an ``Array``-like object, as | |
769 | determined by :mochiref:`compare`. This is a special form of | |
770 | :mochiref:`listMinMax`, specifically | |
771 | :mochiref:`partial(listMinMax, -1)`. | |
772 | ||
773 | *Availability*: | |
774 | Available in MochiKit 1.3.1+ | |
775 | ||
776 | ||
777 | :mochidef:`listMinMax(which, lst)`: | |
778 | ||
779 | If ``which == -1`` then it will return the smallest element of the | |
780 | ``Array``-like ``lst``. This is also available as | |
781 | :mochiref:`listMin(lst)`. | |
782 | ||
783 | If ``which == 1`` then it will return the largest element of the | |
784 | ``Array``-like ``lst``. This is also available as | |
785 | :mochiref:`listMax(list)`. | |
786 | ||
787 | *Availability*: | |
788 | Available in MochiKit 1.3.1+ | |
789 | ||
790 | ||
791 | :mochidef:`map(fn, lst[, ...])`: | |
792 | ||
793 | Return a new array composed of the results of ``fn(x)`` for every | |
794 | ``x`` in ``lst``. | |
795 | ||
796 | If ``fn`` is ``null``, and only one sequence argument is given the | |
797 | identity function is used. | |
798 | ||
799 | :mochiref:`map(null, lst)` -> ``lst.slice()``; | |
800 | ||
801 | If ``fn`` is not ``null`` and more than one sequence argument is | |
802 | given, then one element from each sequence is used to build the | |
803 | argument list for ``fn``. | |
804 | ||
805 | :mochiref:`map(fn, p, q, ...)` | |
806 | -> ``[fn(p[0], q[0], ..), fn(p[1], q[1], ...), ...]`` | |
807 | ||
808 | If ``fn`` is ``null``, and more than one sequence is given as | |
809 | arguments, then the ``Array`` function is used, making it | |
810 | equivalent to :mochiref:`MochiKit.Iter.zip`. | |
811 | ||
812 | :mochiref:`map(null, p, q, ...)` | |
813 | -> :mochiref:`MochiKit.Iter.zip(p, q, ...)` | |
814 | -> ``[[p0, q0, ...], [p1, q1, ...], ...];`` | |
815 | ||
816 | *Availability*: | |
817 | Available in MochiKit 1.3.1+ | |
818 | ||
819 | ||
820 | :mochidef:`mean(lst[, ...])`: | |
821 | ||
822 | Returns the arithmetic mean (average) of the argument list, or an array. | |
823 | This function applies :mochiref:`flattenArguments()` to the argument list. | |
824 | ||
825 | *Availability*: | |
826 | Available in MochiKit 1.4+ | |
827 | ||
828 | ||
829 | :mochidef:`median(lst[, ...])`: | |
830 | ||
831 | Returns the median of the argument list, or an array. This function | |
832 | applies :mochiref:`flattenArguments()` to the argument list. | |
833 | ||
834 | *Availability*: | |
835 | Available in MochiKit 1.4+ | |
836 | ||
837 | ||
838 | :mochidef:`merge(obj[, ...])`: | |
839 | ||
840 | Create a new instance of ``Object`` that contains every property | |
841 | from all given objects. If a property is defined on more than one | |
842 | of the objects, the last property is used. | |
843 | ||
844 | This is a special form of :mochiref:`update(self, obj[, ...])`, | |
845 | specifically, it is defined as :mochiref:`partial(update, null)`. | |
846 | ||
847 | *Availability*: | |
848 | Available in MochiKit 1.3.1+ | |
849 | ||
850 | ||
851 | :mochidef:`method(self, func, ...)`: | |
852 | ||
853 | Alternate form of :mochiref:`bind` that takes the object before | |
854 | the function. These two calls are equivalent:: | |
855 | ||
856 | bind("method", myobject) | |
857 | method(myobject, "method") | |
858 | ||
859 | *Availability*: | |
860 | Available in MochiKit 1.3.1+ | |
861 | ||
862 | ||
863 | :mochidef:`methodcaller(name[, args...])`: | |
864 | ||
865 | Return a new function that calls a method on its argument, | |
866 | for example:: | |
867 | ||
868 | lst = map(methodcaller("toLowerCase"), ["THIS", "is", "LoWeRCaSe"]); | |
869 | assert( lst.join(" ") == "this is lowercase" ); | |
870 | ||
871 | *Availability*: | |
872 | Available in MochiKit 1.4+ | |
873 | ||
874 | ||
875 | :mochidef:`nameFunctions(namespace)`: | |
876 | ||
877 | Given a ``namespace`` (object or function) with a ``NAME`` | |
878 | property, find all methods in it and give them nice ``NAME`` | |
879 | properties too (for use with :mochiref:`repr`). e.g.:: | |
880 | ||
881 | namespace = { | |
882 | NAME: "Awesome", | |
883 | Dude: function () {} | |
884 | } | |
885 | nameFunctions(namespace); | |
886 | assert( namespace.Dude.NAME == 'Awesome.Dude' ); | |
887 | ||
888 | *Availability*: | |
889 | Available in MochiKit 1.3.1+ | |
890 | ||
891 | ||
892 | :mochidef:`noop()`: | |
893 | ||
894 | A function that performs no operation. Use this where you would | |
895 | otherwise use ``(function () {})`` in order to avoid Internet | |
896 | Explorer cyclic garbage leakage. | |
897 | ||
898 | *Availability*: | |
899 | Available in MochiKit 1.4 | |
900 | ||
901 | ||
902 | :mochidef:`objEqual(a, b)`: | |
903 | ||
904 | Return ``true`` if ``compare(a, b) == 0`` | |
905 | ||
906 | *Availability*: | |
907 | Available in MochiKit 1.3.1+ | |
908 | ||
909 | ||
910 | :mochidef:`nodeWalk(node, visitor)`: | |
911 | ||
912 | Non-recursive generic node walking function (e.g. for a DOM). | |
913 | ||
914 | The walk order for nodeWalk is breadth first, meaning that all | |
915 | siblings will be visited before any children. | |
916 | ||
917 | ``node``: | |
918 | The initial node to be searched. | |
919 | ||
920 | ``visitor``: | |
921 | The visitor function, will be called as ``visitor(node)``, and | |
922 | should return an ``Array``-like of nodes to be searched next | |
923 | (e.g. ``node.childNodes``). Leaf nodes may return ``null`` or | |
924 | ``undefined``. | |
925 | ||
926 | *Availability*: | |
927 | Available in MochiKit 1.3.1+ | |
928 | ||
929 | ||
930 | :mochidef:`objMax(obj[, ...])`: | |
931 | ||
932 | Return the maximum object according to :mochiref:`compare` out of | |
933 | the given arguments. This is similar to :mochiref:`listMax`, | |
934 | except is uses the arguments instead of a given ``Array``-like. | |
935 | ||
936 | *Availability*: | |
937 | Available in MochiKit 1.3.1+ | |
938 | ||
939 | ||
940 | :mochidef:`objMin(obj[, ...])`: | |
941 | ||
942 | Return the minimum object according to :mochiref:`compare` out of | |
943 | the given arguments. This is similar to :mochiref:`listMin`, | |
944 | except it uses the arguments instead of a given ``Array``-like. | |
945 | ||
946 | *Availability*: | |
947 | Available in MochiKit 1.3.1+ | |
948 | ||
949 | ||
950 | :mochidef:`operator`: | |
951 | ||
952 | A table of JavaScript's operators for usage with :mochiref:`map`, | |
953 | :mochiref:`filter`, etc. | |
954 | ||
955 | ||
956 | Unary Logic Operators: | |
957 | ||
958 | +--------------------+--------------------------+-------------------+ | |
959 | | Operator | Implementation | Description | | |
960 | +====================+==========================+===================+ | |
961 | | ``truth(a)`` | ``!!a`` | Logical truth | | |
962 | +--------------------+--------------------------+-------------------+ | |
963 | | ``lognot(a)`` | ``!a`` | Logical not | | |
964 | +--------------------+--------------------------+-------------------+ | |
965 | | ``identity(a)`` | ``a`` | Logical identity | | |
966 | +--------------------+--------------------------+-------------------+ | |
967 | ||
968 | ||
969 | ||
970 | Unary Math Operators: | |
971 | ||
972 | +--------------------+--------------------------+---------------+ | |
973 | | Operator | Implementation | Description | | |
974 | +====================+==========================+===============+ | |
975 | | ``not(a)`` | ``~a`` | Bitwise not | | |
976 | +--------------------+--------------------------+---------------+ | |
977 | | ``neg(a)`` | ``-a`` | Negation | | |
978 | +--------------------+--------------------------+---------------+ | |
979 | ||
980 | ||
981 | ||
982 | Binary Operators: | |
983 | ||
984 | +-------------------+-------------------+-------------------------------+ | |
985 | | Operator | Implementation | Description | | |
986 | +===================+===================+===============================+ | |
987 | | ``add(a, b)`` | ``a + b`` | Addition | | |
988 | +-------------------+-------------------+-------------------------------+ | |
989 | | ``sub(a, b)`` | ``a - b`` | Subtraction | | |
990 | +-------------------+-------------------+-------------------------------+ | |
991 | | ``div(a, b)`` | ``a / b`` | Division | | |
992 | +-------------------+-------------------+-------------------------------+ | |
993 | | ``mod(a, b)`` | ``a % b`` | Modulus | | |
994 | +-------------------+-------------------+-------------------------------+ | |
995 | | ``mul(a, b)`` | ``a * b`` | Multiplication | | |
996 | +-------------------+-------------------+-------------------------------+ | |
997 | | ``and(a, b)`` | ``a & b`` | Bitwise and | | |
998 | +-------------------+-------------------+-------------------------------+ | |
999 | | ``or(a, b)`` | ``a | b`` | Bitwise or | | |
1000 | +-------------------+-------------------+-------------------------------+ | |
1001 | | ``xor(a, b)`` | ``a ^ b`` | Bitwise exclusive or | | |
1002 | +-------------------+-------------------+-------------------------------+ | |
1003 | | ``lshift(a, b)`` | ``a << b`` | Bitwise left shift | | |
1004 | +-------------------+-------------------+-------------------------------+ | |
1005 | | ``rshift(a, b)`` | ``a >> b`` | Bitwise signed right shift | | |
1006 | +-------------------+-------------------+-------------------------------+ | |
1007 | | ``zrshift(a, b)`` | ``a >>> b`` | Bitwise unsigned right shift | | |
1008 | +-------------------+-------------------+-------------------------------+ | |
1009 | ||
1010 | ||
1011 | ||
1012 | Built-in Comparators: | |
1013 | ||
1014 | +---------------+-------------------+---------------------------+ | |
1015 | | Operator | Implementation | Description | | |
1016 | +===============+===================+===========================+ | |
1017 | | ``eq(a, b)`` | ``a == b`` | Equals | | |
1018 | +---------------+-------------------+---------------------------+ | |
1019 | | ``ne(a, b)`` | ``a != b`` | Not equals | | |
1020 | +---------------+-------------------+---------------------------+ | |
1021 | | ``gt(a, b)`` | ``a > b`` | Greater than | | |
1022 | +---------------+-------------------+---------------------------+ | |
1023 | | ``ge(a, b)`` | ``a >= b`` | Greater than or equal to | | |
1024 | +---------------+-------------------+---------------------------+ | |
1025 | | ``lt(a, b)`` | ``a < b`` | Less than | | |
1026 | +---------------+-------------------+---------------------------+ | |
1027 | | ``le(a, b)`` | ``a <= b`` | Less than or equal to | | |
1028 | +---------------+-------------------+---------------------------+ | |
1029 | ||
1030 | ||
1031 | ||
1032 | Strict Built-in Comparators: | |
1033 | ||
1034 | +---------------+-------------------+---------------------------+ | |
1035 | | Operator | Implementation | Description | | |
1036 | +===============+===================+===========================+ | |
1037 | | ``seq(a, b)`` | ``a === b`` | Strict equals | | |
1038 | +---------------+-------------------+---------------------------+ | |
1039 | | ``sne(a, b)`` | ``a !== b`` | Strict not equals | | |
1040 | +---------------+-------------------+---------------------------+ | |
1041 | ||
1042 | ||
1043 | ||
1044 | Extended Comparators (uses :mochiref:`compare`): | |
1045 | ||
1046 | +---------------+---------------------------+---------------------------+ | |
1047 | | Operator | Implementation | Description | | |
1048 | +===============+===========================+===========================+ | |
1049 | | ``ceq(a, b)`` | ``compare(a, b) == 0`` | Equals | | |
1050 | +---------------+---------------------------+---------------------------+ | |
1051 | | ``cne(a, b)`` | ``compare(a, b) != 0`` | Not equals | | |
1052 | +---------------+---------------------------+---------------------------+ | |
1053 | | ``cgt(a, b)`` | ``compare(a, b) == 1`` | Greater than | | |
1054 | +---------------+---------------------------+---------------------------+ | |
1055 | | ``cge(a, b)`` | ``compare(a, b) != -1`` | Greater than or equal to | | |
1056 | +---------------+---------------------------+---------------------------+ | |
1057 | | ``clt(a, b)`` | ``compare(a, b) == -1`` | Less than | | |
1058 | +---------------+---------------------------+---------------------------+ | |
1059 | | ``cle(a, b)`` | ``compare(a, b) != 1`` | Less than or equal to | | |
1060 | +---------------+---------------------------+---------------------------+ | |
1061 | ||
1062 | ||
1063 | ||
1064 | Binary Logical Operators: | |
1065 | ||
1066 | +-----------------------+-------------------+---------------------------+ | |
1067 | | Operator | Implementation | Description | | |
1068 | +=======================+===================+===========================+ | |
1069 | | ``logand(a, b)`` | ``a && b`` | Logical and | | |
1070 | +-----------------------+-------------------+---------------------------+ | |
1071 | | ``logor(a, b)`` | ``a || b`` | Logical or | | |
1072 | +-----------------------+-------------------+---------------------------+ | |
1073 | | ``contains(a, b)`` | ``b in a`` | Has property (note order) | | |
1074 | +-----------------------+-------------------+---------------------------+ | |
1075 | ||
1076 | *Availability*: | |
1077 | Available in MochiKit 1.3.1+ | |
1078 | ||
1079 | ||
1080 | :mochidef:`parseQueryString(encodedString[, useArrays=false])`: | |
1081 | ||
1082 | Parse a name=value pair URL query string into an object with a | |
1083 | property for each pair. e.g.:: | |
1084 | ||
1085 | var args = parseQueryString("foo=value%20one&bar=two"); | |
1086 | assert( args.foo == "value one" && args.bar == "two" ); | |
1087 | ||
1088 | If you expect that the query string will reuse the same name, then | |
1089 | give ``true`` as a second argument, which will use arrays to store | |
1090 | the values. e.g.:: | |
1091 | ||
1092 | var args = parseQueryString("foo=one&foo=two", true); | |
1093 | assert( args.foo[0] == "one" && args.foo[1] == "two" ); | |
1094 | ||
1095 | *Availability*: | |
1096 | Available in MochiKit 1.3.1+ | |
1097 | ||
1098 | ||
1099 | :mochidef:`partial(func, arg[, ...])`: | |
1100 | ||
1101 | Return a partially applied function, e.g.:: | |
1102 | ||
1103 | addNumbers = function (a, b) { | |
1104 | return a + b; | |
1105 | } | |
1106 | ||
1107 | addOne = partial(addNumbers, 1); | |
1108 | ||
1109 | assert(addOne(2) == 3); | |
1110 | ||
1111 | :mochiref:`partial` is a special form of :mochiref:`bind` that | |
1112 | does not alter the bound ``self`` (if any). It is equivalent to | |
1113 | calling:: | |
1114 | ||
1115 | bind(func, undefined, arg[, ...]); | |
1116 | ||
1117 | See the documentation for :mochiref:`bind` for more details about | |
1118 | this facility. | |
1119 | ||
1120 | This could be used to implement, but is NOT currying. | |
1121 | ||
1122 | *Availability*: | |
1123 | Available in MochiKit 1.3.1+ | |
1124 | ||
1125 | ||
1126 | :mochidef:`queryString(names, values)`: | |
1127 | ||
1128 | Creates a URL query string from a pair of ``Array``-like objects | |
1129 | representing ``names`` and ``values``. Each name=value pair will | |
1130 | be URL encoded by :mochiref:`urlEncode`. name=value pairs with a | |
1131 | value of ``undefined`` or ``null`` will be skipped. e.g.:: | |
1132 | ||
1133 | var keys = ["foo", "bar"]; | |
1134 | var values = ["value one", "two"]; | |
1135 | assert( queryString(keys, values) == "foo=value%20one&bar=two" ); | |
1136 | ||
1137 | Alternate form 1: | |
1138 | :mochiref:`queryString(domElement)` | |
1139 | ||
1140 | If :mochiref:`MochiKit.DOM` is loaded, one argument is given, and | |
1141 | that argument is either a string or has a ``nodeType`` property | |
1142 | greater than zero, then ``names`` and ``values`` will be the | |
1143 | result of :mochiref:`MochiKit.DOM.formContents(domElement)`. | |
1144 | ||
1145 | Alternate form 2: | |
1146 | :mochiref:`queryString({name: value, ...})` | |
1147 | ||
1148 | Note that when using the alternate form, the order of the | |
1149 | name=value pairs in the resultant query string is dependent on how | |
1150 | the particular JavaScript implementation handles ``for (..in..)`` | |
1151 | property enumeration. | |
1152 | ||
1153 | When using the second alternate form, name=value pairs with | |
1154 | ``typeof(value) == "function"`` are ignored. This is a workaround | |
1155 | for the case where a poorly designed library has modified | |
1156 | ``Object.prototype`` and inserted "convenience functions". | |
1157 | ||
1158 | Values that are Array-like will be expanded as if they were multiply | |
1159 | defined HTML elements. For example:: | |
1160 | ||
1161 | assert( queryString({a: [1,2]}) === "a=1&a=2" ); | |
1162 | ||
1163 | Alternate form 2 (MochiKit 1.4+): | |
1164 | :mochiref:`queryString([names, values])` | |
1165 | ||
1166 | This form behaves identically to :mochiref:`queryString(names, values)`, | |
1167 | except it takes both arguments as a single Array. This mirrors the | |
1168 | return value of :mochiref:`MochiKit.DOM.formContents`. | |
1169 | ||
1170 | *Availability*: | |
1171 | Available in MochiKit 1.3.1+ | |
1172 | ||
1173 | ||
1174 | :mochidef:`registerComparator(name, check, comparator[, override])`: | |
1175 | ||
1176 | Register a comparator for use with :mochiref:`compare`. | |
1177 | ||
1178 | ``name``: | |
1179 | unique identifier describing the comparator. | |
1180 | ||
1181 | ``check``: | |
1182 | ``function(a, b)`` that returns ``true`` if ``a`` and ``b`` | |
1183 | can be compared with ``comparator``. | |
1184 | ||
1185 | ``comparator``: | |
1186 | ``function(a, b)`` that returns: | |
1187 | ||
1188 | +-------+-----------+ | |
1189 | | Value | Condition | | |
1190 | +-------+-----------+ | |
1191 | | 0 | a == b | | |
1192 | +-------+-----------+ | |
1193 | | 1 | a > b | | |
1194 | +-------+-----------+ | |
1195 | | -1 | a < b | | |
1196 | +-------+-----------+ | |
1197 | ||
1198 | ``comparator`` is guaranteed to only be called if ``check(a, | |
1199 | b)`` returns a ``true`` value. | |
1200 | ||
1201 | ``override``: | |
1202 | if ``true``, then this will be made the highest precedence | |
1203 | comparator. Otherwise, the lowest. | |
1204 | ||
1205 | *Availability*: | |
1206 | Available in MochiKit 1.3.1+ | |
1207 | ||
1208 | ||
1209 | :mochidef:`registerJSON(name, check, simplifier[, override])`: | |
1210 | ||
1211 | Register a simplifier function for use with | |
1212 | :mochiref:`serializeJSON`. | |
1213 | ||
1214 | ``name``: | |
1215 | unique identifier describing the serialization. | |
1216 | ||
1217 | ``check``: | |
1218 | ``function(obj)`` that returns ``true`` if ``obj`` can | |
1219 | can be simplified for serialization by ``simplifier``. | |
1220 | ||
1221 | ``simplifier``: | |
1222 | ``function(obj)`` that returns a simpler object that can be | |
1223 | further serialized by :mochiref:`serializeJSON`. For example, | |
1224 | you could simplify ``Date``-like objects to ISO 8601 timestamp | |
1225 | strings with the following simplifier:: | |
1226 | ||
1227 | var simplifyDateAsISO = function (obj) { | |
1228 | return toISOTimestamp(obj, true); | |
1229 | }; | |
1230 | registerJSON("DateLike", isDateLike, simplifyDateAsISO); | |
1231 | ||
1232 | ``simplifier`` is guaranteed to only be called if | |
1233 | ``check(obj)`` returns a ``true`` value. | |
1234 | ||
1235 | ``override``: | |
1236 | if ``true``, then this will be made the highest precedence | |
1237 | serialization. Otherwise, the lowest. | |
1238 | ||
1239 | *Availability*: | |
1240 | Available in MochiKit 1.3.1+ | |
1241 | ||
1242 | ||
1243 | :mochidef:`registerRepr(name, check, wrap[, override])`: | |
1244 | ||
1245 | Register a programmer representation function. :mochiref:`repr` | |
1246 | functions should take one argument and return a string | |
1247 | representation of it suitable for developers, primarily used when | |
1248 | debugging. | |
1249 | ||
1250 | If ``override`` is given, it is used as the highest priority repr, | |
1251 | otherwise it will be used as the lowest. | |
1252 | ||
1253 | *Availability*: | |
1254 | Available in MochiKit 1.3.1+ | |
1255 | ||
1256 | ||
1257 | :mochidef:`repr(obj)`: | |
1258 | ||
1259 | Return a programmer representation for ``obj``. See the | |
1260 | `Programmer Representation`_ overview for more information about | |
1261 | this function. | |
1262 | ||
1263 | *Availability*: | |
1264 | Available in MochiKit 1.3.1+ | |
1265 | ||
1266 | ||
1267 | :mochidef:`reverseKeyComparator(key)`: | |
1268 | ||
1269 | A comparator factory that compares ``a[key]`` with ``b[key]`` in | |
1270 | reverse. e.g.:: | |
1271 | ||
1272 | var lst = ["a", "bbb", "cc"]; | |
1273 | lst.sort(reverseKeyComparator("length")); | |
1274 | assert(lst.toString() == "bbb,cc,a"); | |
1275 | ||
1276 | *Availability*: | |
1277 | Available in MochiKit 1.3.1+ | |
1278 | ||
1279 | ||
1280 | :mochidef:`serializeJSON(anObject)`: | |
1281 | ||
1282 | Serialize ``anObject`` in the JSON [1]_ format, see `JSON | |
1283 | Serialization`_ for the coercion rules. For unserializable objects | |
1284 | (functions that do not have an adapter, ``__json__`` method, or | |
1285 | ``json`` method), this will return ``undefined``. | |
1286 | ||
1287 | For those familiar with Python, JSON is similar in scope to | |
1288 | pickle, but it can not handle recursive object graphs. | |
1289 | ||
1290 | *Availability*: | |
1291 | Available in MochiKit 1.3.1+ | |
1292 | ||
1293 | ||
1294 | :mochidef:`setdefault(self, obj[, ...])`: | |
1295 | ||
1296 | Mutate ``self`` by adding all properties from other object(s) that | |
1297 | it does not already have set. | |
1298 | ||
1299 | If ``self`` is ``null``, a new ``Object`` instance will be created | |
1300 | and returned. | |
1301 | ||
1302 | This mutates *and returns* ``self``, be warned. | |
1303 | ||
1304 | *Availability*: | |
1305 | Available in MochiKit 1.3.1+ | |
1306 | ||
1307 | ||
1308 | :mochidef:`typeMatcher(typ[, ...])`: | |
1309 | ||
1310 | Given a set of types (as string arguments), returns a | |
1311 | ``function(obj[, ...])`` that will return ``true`` if the types of | |
1312 | the given arguments are all members of that set. | |
1313 | ||
1314 | *Availability*: | |
1315 | Available in MochiKit 1.3.1+ | |
1316 | ||
1317 | ||
1318 | :mochidef:`update(self, obj[, ...])`: | |
1319 | ||
1320 | Mutate ``self`` by replacing its key:value pairs with those from | |
1321 | other object(s). Key:value pairs from later objects will overwrite | |
1322 | those from earlier objects. | |
1323 | ||
1324 | If ``self`` is ``null``, a new ``Object`` instance will be created | |
1325 | and returned. | |
1326 | ||
1327 | This mutates *and returns* ``self``, be warned. | |
1328 | ||
1329 | A version of this function that creates a new object is available | |
1330 | as :mochiref:`merge(a, b[, ...])` | |
1331 | ||
1332 | *Availability*: | |
1333 | Available in MochiKit 1.3.1+ | |
1334 | ||
1335 | ||
1336 | :mochidef:`updatetree(self, obj[, ...])`: | |
1337 | ||
1338 | Mutate ``self`` by replacing its key:value pairs with those from | |
1339 | other object(s). If a given key has an object value in both | |
1340 | ``self`` and ``obj``, then this function will be called | |
1341 | recursively, updating instead of replacing that object. | |
1342 | ||
1343 | If ``self`` is ``null``, a new ``Object`` instance will be created | |
1344 | and returned. | |
1345 | ||
1346 | This mutates *and returns* ``self``, be warned. | |
1347 | ||
1348 | *Availability*: | |
1349 | Available in MochiKit 1.3.1+ | |
1350 | ||
1351 | ||
1352 | :mochidef:`urlEncode(unencoded)`: | |
1353 | ||
1354 | Converts ``unencoded`` into a URL-encoded string. In this | |
1355 | implementation, spaces are converted to %20 instead of "+". e.g.:: | |
1356 | ||
1357 | assert( URLencode("1+2=2") == "1%2B2%3D2"); | |
1358 | ||
1359 | *Availability*: | |
1360 | Available in MochiKit 1.3.1+ | |
1361 | ||
1362 | ||
1363 | :mochidef:`values(obj)`: | |
1364 | ||
1365 | Return an ``Array`` of the property values of an object (in the | |
1366 | order determined by ``for propName in obj``). | |
1367 | ||
1368 | *Availability*: | |
1369 | Available in MochiKit 1.4+ | |
1370 | ||
1371 | ||
1372 | :mochidef:`xfilter(fn, obj[, ...])`: | |
1373 | ||
1374 | Returns a new ``Array`` composed of the arguments where | |
1375 | ``fn(obj)`` returns a true value. | |
1376 | ||
1377 | If ``fn`` is ``null``, ``operator.truth`` will be used. | |
1378 | ||
1379 | *Availability*: | |
1380 | Available in MochiKit 1.3.1+ | |
1381 | ||
1382 | ||
1383 | :mochidef:`xmap(fn, obj[, ...)`: | |
1384 | ||
1385 | Return a new ``Array`` composed of ``fn(obj)`` for every ``obj`` | |
1386 | given as an argument. | |
1387 | ||
1388 | If ``fn`` is ``null``, ``operator.identity`` is used. | |
1389 | ||
1390 | *Availability*: | |
1391 | Available in MochiKit 1.3.1+ | |
1392 | ||
1393 | ||
1394 | See Also | |
1395 | ======== | |
1396 | ||
1397 | .. [1] JSON, JavaScript Object Notation: http://json.org/ | |
1398 | .. [2] Python's itertools | |
1399 | module: http://docs.python.org/lib/module-itertools.html | |
1400 | ||
1401 | Authors | |
1402 | ======= | |
1403 | ||
1404 | - Bob Ippolito <bob@redivi.com> | |
1405 | ||
1406 | ||
1407 | Copyright | |
1408 | ========= | |
1409 | ||
1410 | Copyright 2005 Bob Ippolito <bob@redivi.com>. This program is | |
1411 | dual-licensed free software; you can redistribute it and/or modify it | |
1412 | under the terms of the `MIT License`_ or the `Academic Free License | |
1413 | v2.1`_. | |
1414 | ||
1415 | .. _`MIT License`: http://www.opensource.org/licenses/mit-license.php | |
1416 | .. _`Academic Free License v2.1`: http://www.opensource.org/licenses/afl-2.1.php |