Initial check-in
[dygraphs.git] / mochikit_v14 / doc / rst / MochiKit / Base.rst
CommitLineData
6a1aa64f
DV
1.. title:: MochiKit.Base - functional programming and useful comparisons
2
3Name
4====
5
6MochiKit.Base - functional programming and useful comparisons
7
8
9Synopsis
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
53Description
54===========
55
56:mochiref:`MochiKit.Base` is the foundation for the MochiKit suite.
57It 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
74Python users will feel at home with :mochiref:`MochiKit.Base`, as the
75facilities are quite similar to those available as part of Python and
76the Python standard library.
77
78
79Dependencies
80============
81
82None.
83
84
85Overview
86========
87
88Comparison
89----------
90
91The comparators (operators for comparison) in JavaScript are deeply
92broken, and it is not possible to teach them new tricks.
93
94MochiKit exposes an extensible comparison facility as a simple
95:mochiref:`compare(a, b)` function, which should be used in lieu of
96JavaScript's operators whenever comparing objects other than numbers
97or strings (though you can certainly use :mochiref:`compare` for
98those, too!).
99
100The :mochiref:`compare` function has the same signature and return
101value as a sort function for ``Array.prototype.sort``, and is often
102used in that context.
103
104Defining new comparators for the :mochiref:`compare` function to use
105is done by adding an entry to its :mochiref:`AdapterRegistry` with the
106:mochiref:`registerComparator` function.
107
108
109Programmer Representation
110-------------------------
111
112JavaScript's default representation mechanism, ``toString``, is
113notorious for having terrible default behavior. It's also very unwise
114to change that default, as other JavaScript code you may be using may
115depend on it.
116
117It's also useful to separate the concept of a "string representation"
118and a "string representation for programmers", much like Python does
119with its str and repr protocols.
120
121:mochiref:`repr` provides this programmer representation for
122JavaScript, in a way that doesn't require object prototype hacking:
123using an :mochiref:`AdapterRegistry`.
124
125Objects that implement the repr protocol can either implement a
126``.repr()`` or ``.__repr__()`` method, or they can simply have an
127adapter setup to generate programmer representations. By default, the
128registry provides nice representations for ``null``, ``undefined``,
129``Array``, and objects or functions with a ``NAME`` attribute that use
130the default ``toString``. For objects that ``repr`` doesn't already
131understand, it simply defaults to ``toString``, so it will integrate
132seamlessly with code that implements the idiomatic JavaScript
133``toString`` method!
134
135To define a programmer representation for your own objects, simply add
136a ``.repr()`` or ``.__repr__()`` method that returns a string. For
137objects that you didn't create (e.g., from a script you didn't write,
138or a built-in object), it is instead recommended that you create an
139adapter with :mochiref:`registerRepr`.
140
141
142JSON Serialization
143------------------
144
145JSON [1]_, JavaScript Object Notation, is a widely used serialization
146format in the context of web development. It's extremely simple,
147lightweight, and fast. In its essence, JSON is a restricted subset of
148JavaScript syntax suitable for sending over the wire that can be
149unserialized with a simple eval. It's often used as an alternative to
150XML in "AJAX" contexts because it is compact, fast, and much simpler
151to use for most purposes.
152
153To create a JSON serialization of any object, simply call
154:mochiref:`serializeJSON()` with that object. To unserialize a JSON
155string, simply call :mochiref:`evalJSON()` with the serialization.
156
157In order of precedence, :mochiref:`serializeJSON` coerces the given
158argument into a JSON serialization:
159
1601. Primitive types are returned as their JSON representation:
161 ``string``, ``number``, ``boolean``, ``null``.
1622. 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).
1673. 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``.
1724. 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).
1775. 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.
1806. 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
187Adapter Registries
188------------------
189
190MochiKit makes extensive use of adapter registries, which enable you
191to implement object-specific behaviors for objects that you do not
192necessarily want to modify, such as built-in objects. This is
193especially useful because JavaScript does not provide a method for
194hiding user-defined properties from ``for propName in obj``
195enumeration.
196
197:mochiref:`AdapterRegistry` is simply an encapsulation for an ordered
198list of "check" and "wrap" function pairs. Each
199:mochiref:`AdapterRegistry` instance should perform one function, but
200may have multiple ways to achieve that function based upon the
201arguments. One way to think of it is as a poor man's generic function,
202or multiple dispatch (on arbitrary functions, not just type!).
203
204Check functions take one or more arguments, and return ``true`` if the
205argument list is suitable for the wrap function. Check functions
206should perform "cheap" checks of an object's type or contents, before
207the "expensive" wrap function is called.
208
209Wrap functions take the same arguments as check functions and do some
210operation, such as creating a programmer representation or comparing
211both arguments.
212
213
214Convenience Functions
215---------------------
216
217Much of :mochiref:`MochiKit.Base` is there to simply remove the grunt
218work of doing generic JavaScript programming.
219
220Need to take every property from one object and set them on another?
221No problem, just call :mochiref:`update(dest, src)`! What if you just
222wanted to update keys that weren't already set? Look no further than
223:mochiref:`setdefault(dest, src[, ...])`.
224
225Want to return a mutable object, but don't want to suffer the
226consequences if the user mutates it? Just :mochiref:`clone(it)` and
227you'll get a copy-on-write clone. Cheaper than a copy!
228
229Need 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
232of the source ``Array``-like object, it's no problem with
233:mochiref:`extend(dstArray, srcArrayLike[, skip])`!
234
235Wouldn't it be convenient to have all of the JavaScript operators were
236available as functions somewhere? That's what the
237:mochiref:`operators` table is for, and it even comes with additional
238operators based on the :mochiref:`compare` function.
239
240Need to walk some tree of objects and manipulate or find something in
241it? A DOM element tree perhaps? Use :mochiref:`nodeWalk(node,
242visitor)`!
243
244There's plenty more, so check out the `API Reference`_ below.
245
246
247Functional Programming
248----------------------
249
250Functional programming constructs such as :mochiref:`map` and
251:mochiref:`filter` can save you a lot of time, because JavaScript
252iteration is error-prone and arduous. Writing less code is the best
253way to prevent bugs, and functional programming can help you do that.
254
255:mochiref:`MochiKit.Base` ships with a few simple Array-based
256functional programming constructs, namely :mochiref:`map` and
257:mochiref:`filter`, and their "extended" brethren, :mochiref:`xmap`
258and :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``
262is the result of ``func(element)`` for every element of ``arrayLike``,
263much like the ``Array.prototype.map`` extension in Mozilla. However,
264:mochiref:`MochiKit.Base` takes that a step further and gives you the
265full blown Python version of :mochiref:`map`, which will take several
266``Array``-like objects, and calls the function with one argument per
267given ``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
277identical to the ``Array.prototype.filter`` extension in
278Mozilla. self, if given, will be used as ``this`` in the context of
279func 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
283first argument, and use the extra arguments as the ``Array``-like. Not
284terribly interesting, but a definite time-saver in some cases.
285
286If you appreciate the functional programming facilities here, you
287should definitely check out :mochiref:`MochiKit.Iter`, which provides
288full blown iterators, :mochiref:`MochiKit.Iter.range`,
289:mochiref:`MochiKit.Iter.reduce`, and a near-complete port of Python's
290itertools [2]_ module, with some extra stuff thrown in for good
291measure!
292
293
294Bound and Partial Functions
295---------------------------
296
297JavaScript's method-calling special form and lack of bound functions
298(functions that know what ``this`` should be) are one of the first
299stumbling blocks that programmers new to JavaScript face. The
300:mochiref:`bind(func, self)` method fixes that right up by returning a
301new function that calls func with the right ``this``.
302
303In order to take real advantage of all this fancy functional
304programming stuff, you're probably going to want partial
305application. This allows you to create a new function from an existing
306function that remembers some of the arguments. For example, if you
307wanted to compare a given object to a slew of other objects, you could
308do 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
314One of the better uses of partial functions is in
315:mochiref:`MochiKit.DOM`, which is certainly a must-see for those of
316you creating lots of DOM elements with JavaScript!
317
318
319API Reference
320=============
321
322Errors
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
333Constructors
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
398Functions
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
1394See 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
1401Authors
1402=======
1403
1404- Bob Ippolito <bob@redivi.com>
1405
1406
1407Copyright
1408=========
1409
1410Copyright 2005 Bob Ippolito <bob@redivi.com>. This program is
1411dual-licensed free software; you can redistribute it and/or modify it
1412under the terms of the `MIT License`_ or the `Academic Free License
1413v2.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