-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathobject.vim.txt
1033 lines (852 loc) · 38 KB
/
object.vim.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
*object.vim.txt* An Object-Oriented Framework for Vimscript
cgsdfc *object* *object.vim*
==============================================================================
CONTENTS *object.vim-contents*
1. Introduction...........................................|object.vim-intro|
2. Class..................................................|object.vim-class|
3. Super..................................................|object.vim-super|
4. Protocols..........................................|object.vim-protocols|
5. Mapping..............................................|object.vim-mapping|
6. Iterator................................................|object.vim-iter|
7. File....................................................|object.vim-file|
8. Types..................................................|object.vim-types|
9. Lambda................................................|object.vim-lambda|
10. Int.....................................................|object.vim-int|
11. Dictionaries..........................................|object.vim-dicts|
12. Functions.........................................|object.vim-functions|
13. Motivation.......................................|object.vim-motivation|
==============================================================================
INTRODUCTION *object.vim-intro*
>
__ _ __
____ / /_ (_)__ _____/ /_
/ __ \/ __ \ / / _ \/ ___/ __/
/ /_/ / /_/ / / / __/ /__/ /_
\____/_.___/_/ /\___/\___/\__/
/___/
<
QUICK-START
object.vim is an object-oriented framework for plugin writers of Vim. It aims
to augment and enrich the existing techniques for OOP in Vim. That means
instead of doing this:
>
let s:MyAwesomeClass = {}
<
you can do this:
>
let s:MyAwesomeClass = object#class('MyAwesomeClass')
<
And yes, you type the class name twice, but here are the prizes:
>
echo object#repr(s:MyAwesomeClass)
<type 'MyAwesomeClass'>
let awesome = object#new(s:MyAwesomeClass)
echo object#repr(awesome)
<'MyAwesomeClass' object>
<
What you get is a type that works out of the box instead of a plain |Dict|.
There is a lot more you can do with object.vim, such as multiple inheritances.
Although people nearly always frown on madly complicated class hierarchy,
object.vim makes it possible for you to make people mad :). Powered by
C3-linearization, you get exactly the same MRO as exemplified by
|https://rhettinger.wordpress.com/2011/05/26/super-considered-super/|:
>
let s:LoggingDict = object#class('LoggingDict', somedict)
let s:LoggingOD = object#class('LoggingOD', [s:LoggingDict, s:OrderedDict)
echo object#repr(s:LoggingOD.__mro__)
[<type 'LoggingOD'>,
<type 'LoggingDict'>,
<type 'OrderedDict'>,
<type, 'somedict'>,
<type, 'object'>]
<
FEATURES
object.vim implements its features in the following modules:
* class: inheritance and instantiation.
* iter: iterator for |List| and |String| and helper functions.
* file: plain old file object for line-oriented I/O.
* lambda: create one-liner easily and `for()` loop construct.
* mapping: hash arbitrary object and generic `getitem()`, `setitem()`.
* types: top-level classes like `object`, `type`, and conversion protocols
like `bool()`.
Note that although these features are implemented in separate files, they are
kind-of imported into a shallow namespace for ease of use so please use
`object#class()` instead of `object#class#class()`. Please consider everything
in namespaces deeper than `object` as implementation details and avoid using
them as much as you can. However, each function is still documented
with its full name, as found in |object.vim-functions|.
TESTING
I use `vader.vim` for unit tests. A comprehensive test suite for each module
can be found in `object.vim/test`. To run all the tests, use:
>
object.vim/test/run-tests.sh
<
DEPENDENCY
* `vim-maktaba`: |https://github.com/google/vim-maktaba|
* `vader.vim`: |https://github.com/junegunn/vader.vim|
* `vimdoc`: |https://github.com/google/vimdoc| (developers)
* `Vim`: version >= 7.4
AUTHOR
* Author: Cong Feng
* Email: [email protected]
==============================================================================
CLASS *object.vim-class*
This module provides functions for the creation and manipulation of classes and instances. Below, the term "class" is used interchangeably with "type" to refer to the object representing a class, since there is no "old-style" class in object.vim. Every class is derived from `object` (except `object`). The term "class object" is avoided since it reminds people of the "old-style" class.
COMPARED-WITH-RELATED-APPROACHES
There are different approaches to creating classes in Vimscript. To get the best of them, we compare them and show the design rationales of object.vim at the same time.
The most common approach is via a simple assignment:
>
let s:MyClass = {}
function! s:MyClass.some_method()
" some code
endfunction
let var = deepcopy(s:MyClass)
<
This approach has the virtue of being brief, but a plain `{}` can't have too many features.
Here is a command-based approach:
>
Class MyClass, some_bases
" some methods
EndClass
<
This approach introduces new commands that begin and ends the class definition. It looks very like a DSL, which goes against the aim of object.vim, which says no new syntax is required.
Another approach defines all the methods inside a function that creates the class:
>
function! s:GetMyClass()
let s:MyClass = {}
function! s:MyClass.some_method()
" some code
endfunction
" more methods
return deepcopy(s:MyClass)
endfunction
<
This approach looks nice as it bundles all the methods together. However, it mixes the definition of a class and the instantiation of it, making both aspects less flexible.
With these limitations in mind, object.vim is designed to be intuitively usable yet very flexible:
>
let s:Logger = object#class('Logger')
function! s:Logger.info(...)
return self.log('info', a:000)
endfunction
<
MULTIPLE-INHERITANCE
Many people go against MI (Multiple Inheritance) because it complicates the
program. Nonetheless, it is more expressive than single inheritance. That's
why it is supported.
The functions that deal with MI are `class()`, `type()`, and `super()`. Both
`class()` and `type()` take an optional `bases` argument which can be:
* omitted: derived from `object`.
* a single class: derived from that.
* a |List| of classes: derived from all those classes.
* an empty list: the same as omitted.
Note that the resulting class takes a copy of the base list so you are free to
modify it after `class()` returns.
With MI comes MRO (Method Resolution Order) and the C3 algorithm is used to
construct the `__mro__` attribute for each class. Methods are resolved
statically based on `__mro__`, which means the changes to `__bases__` will not
cause a rerun of method resolution. All the attributes from parents are added
to their child respecting its `__mro__`, which can be overridden naturally by
adding methods with the same names. This means you can call parents' methods
in several ways:
>
let s:Animal = object#class('Animal')
function! s:Animal.make_sound()
echo 'Animal makes sound'
endfunction
let s:Dog = object#class('Dog', s:Animal)
function! s:Dog.bark()
call self.make_sound()
echo 'Dog barks'
endfunction
let dog = object#new(s:Dog)
call dog.make_sound()
Animal makes sound
echo has_key(dog, 'make_sound')
1
<
However, if the child is overriding a method of its parents, it can only call
the parents' version with `super()`. See |object.vim-super| for more
information.
SPECIAL-ATTRIBUTES
Like Python, object.vim uses double-underscored names for special attributes.
The use of such attributes in the class modules aims to be minimal, as it
takes space off every class and instance. Currently, these are:
Class:
* __name__: the name of the class, a valid identifier.
* __base__: the first direct base.
* __bases__: the list of direct bases.
* __mro__: the list of method resolution order.
* __class__: currently always the `type` class.
Instance:
* __class__: the type of this instance.
ATTRIBUTES
We have been talking about attributes, but what are they in the context of object.vim? Basically everything inside a |Dict| with its name as an identifier is an attribute. Particularly, if the attribute is a |Funcref|, it is treated as instance methods. This is important since when an instance is created, it will have all the |Funcref| attributes of its class as its methods. Anything other than |Funcref| stays in the class as it is, which implies:
* A class cannot have `classmethod`. You should not call methods of a class object.
* A class can have its own attributes, as long as they are not |Funcref|.
The lack of `classmethod` sounds discouraging because classes are no longer first-class objects and they will fail with some protocols. That may be improved in the future.
CLASS-NAME-AND-IDENTITY
There is no notion of class-registry in object.vim and the `name` argument got
passed to `class()` is not checked for uniqueness. This means it is possible
for two different class to have the same name. However, as long as the
variables holding the classes have distinct names, there won't be name
crashes. What's more, every class will have different identities testable by
`is#` since `class()` always creates new class. As currently the name of a
class is only used to provide its `repr()` (not as the key to anything), you
are free to crash your class names with other's without a doubt :-).
EXPOSING-CLASS
As you write plugins you may wish to let others extend or instantiate your
classes. Here are the ways to do so:
>
" You can do this:
function! useful#Formatter_()
return s:Formatter
endfunction
" so that user can inherit your class
let s:useful_Formater = useful#Formatter_()
let s:MyFormatter = object#class('MyFormatter', s:useful_Formater)
" and instantiate it.
let formatter = object#new(s:useful_Formater)
" You can also do this:
function! useful#Formatter(...) abort
return object#new_(s:Formatter, a:000)
endfunction
" to feel more like a constructor:
let formatter = useful#Formatter()
<
==============================================================================
SUPER *object.vim-super*
`super()` is a way for a class to call methods of their parents and siblings
while overriding them. In this section you will learn how to use the two forms
of `super()` provided by object.vim.
USAGE
Most typically, you can initialize base class via `super()`:
>
let s:Shape = object#class('Shape')
function! s:Shape.__init__(kwdict)
let self.shapename = get(a:kwdict, 'shapename')
call object#super(s:Shape, self).__init__(a:kwdict)
endfunction
let s:ColoredShape = object#class('ColoredShape', s:Shape)
function! s:ColoredShape.__init__(kwdict)
let self.color = get(a:kwdict, 'color')
call object#super(s:ColoredShape, self).__init__(a:kwdict)
endfunction
let c = object#new(s:ColoredShape, {'color':'red', 'shapename':'circle'})
<
What `super()` does is locating the next type in the MRO and returns an object
that has all the methods of this type bound to the invoking object. The proxy
object is further cached in the invoking object, which makes following access
to it faster.
USE-CASES-OF-TWO-SUPERS
Currently two ways to call methods of parents and siblings are provided and
let's talk about the cases when you may use one of them.
>
super(type, obj)
<
It creates a proxy object delegating almost all the method calls to parents
and siblings. The super objects are cached in the the invoking object, i.e.,
`__self__` so later calls to `super()` with specific `type` and `obj`
effectively retrieves the cached objects. That means if you use lots of
methods from parents in a class, you can use `super()` to speed up. However,
since the nature of static method resolution, the number of methods of one
super object grows linearly to the size of the MRO. Since all the classes in
the MRO except the first one may result in a distinct super object, the total
number of methods of those super objects is ordered by O(len(MRO)^2), which is
always the case when cooperative inheritance is in used. Therefore, if you
have a somehow deep class hierarchy, be careful with the space overhead with
the instances of those leaf classes, especially when each of your classes has
a non-trivial number of methods. In short, use `super()` if you densely call
different methods of parents and siblings while the depth of your class
hierarchy is modest.
>
super_(type, obj, name)
<
It searches the MRO started from the next of `type` and returns the first
method matching `name`. There isn't any caching behind the sense so
`__super__` is not created. However, when cooperative inheritance is used, a
sinle chained call to `super_()` results in O(len(MRO)^2) time to resolve all
the methods along the way. Therefore, if you make sparse calls to the methods
of parents and you want to minimize the space of your instances, you may use
`super_()` since the time won't be a problem. However, in present of a long
MRO and frequent calls to `super_()`, you may prefer `super()`.
You are recommended to use `super()` at first and only when "Out Of Memory"
arises should you turn some `super()` to `super_()` because not only the
syntax of `super()` looks more nature (more like Python), but the attributes
of super objects aid inspection. Mixing both of them in one single class is
not recommended, since both of their benefits may be lost (you asked for a
cache but you didn't use it). However, you can mix them in different classes
of one hierarchy, especially using `super_()` in those leaf classes whose MRO
is long.
CACHING-SUPER
To save time, `super()` caches the super objects of each `type` in each `obj`
with a special attribute `__super__`. Unlike other special attribute like
`__mro__`, the structure of this one is kept private, which means you should
not count on it. In the future, inspection of it may be provided.
The current `__super__` keeps a dictionary of all the created super objects
hashed with the name of their `__thisclass__`. Since different classes can
have the same name, conflicts are handled by having a list of super objects
for each name. When the `type` and `obj` have been validated, `super()`
consults the cache before going through the MRO. When the cache misses, it
goes all the way to create a super object and fill in the cache.
==============================================================================
PROTOCOLS *object.vim-protocols*
A set of basic hookable functions that inspect and operate on different
properties of an object. A protocol in this context means an global function
that has well defined behaviours for built-in types and can be overriden by
the corresponding methods with double underscores names.
==============================================================================
MAPPING *object.vim-mapping*
An interface to key-value containers. A mapping is an object that supports
accessing its values through a set of keys or in short, the subscription
operator. The built-in |String|, |Dict| and |List| can all be viewed as
mapping. This idea is generalized by the functions provided.
Features:
* Hookable hash() works for built-in types.
* Hookable getitem() and setitem() functions works built in types.
==============================================================================
ITERATOR *object.vim-iter*
Iterator protocol.
Features:
* Vim-compatible map() and filter() that works with iterators.
* filter() evaluates lambda using |object#types#bool()|.
* Provide iterators for |String| and |List| that works transparently.
* Helpers like sum(), all(), any(), zip() and enumerate() all work as
expected.
Examples:
>
:echo object#all(range(10))
0
:echo object#list(object#enumerate('abc'))
[[0, 'a'], [1, 'b'], [2,'c']]
:echo object#dict(object#zip('abc', range(3)))
{'a': 0, 'b': 1, 'c': 2}
:echo object#sum(range(1, 100))
5050
:echo object#filter(['1', '2', ''])
['1', '2']
:echo object#list('abc')
['a', 'b', 'c']
<
Limitations:
* No generator and yield() supported.
==============================================================================
FILE *object.vim-file*
A simple interface to the |readfile()| and |writefile()| functions. Features:
* Lazy reading and writing.
* Line-oriented I/O.
* Handle errors with IOError.
* Mode string syntax like 'a', 'w' or '+', 'b'.
Limitations:
* The file is always buffered.
* The content of the file object is not synchronized with external changes
to the underlying file.
* The file is unseekable. All reading or writing happens essentially at the
current line number.
* No context manager available. Must call f.close() explicitly or you may
lost written data.
Note:
* Unlike the counterparts from Python, readlines() always strips tailing
newlines and
* writelines() always adds tailing newlines.
Examples:
>
Your file is
1
2
3
:echo f.readlines()
['1', '2', '3']
:call f.writelines(range(3))
:call f.close()
Your file becomes
1
2
3
<
This is rooted at the nature of |readfile()| and |writefile()|.
==============================================================================
TYPES *object.vim-types*
Define a minimal set of fundamental types as the basic of the type hierarchy.
They are:
* object(None): The base class of all the rest of classes. The base class of
it is None, the only instance of the NoneType.
* type(object): The class of all the types for both built-in and user
definded ones. In other words, every class is an instance of type.
* NoneType(type): The class of the None object, the place holder for absence
of sensible values, such as the base class of object.
==============================================================================
LAMBDA *object.vim-lambda*
Create a function in one line of code. It is an enhanced version of
|maktaba#function#FromExpr()|.
Features:
* `lambda()` returns a |Funcref| rather than a |Dict|, which can be used
directly in situation such as |sort()|.
* The created lambda uses named arguments rather than numbered arguments
like `a:1`, improving readability.
* Provide interface to the underlying lambda object via `_lambda()`.
* lambda can create closure if one want to.
* `for()` function let you execute nearly arbitrary code while iterating.
Limitations:
* Only one dictionary can be captured as closure at most, which means you
cannot access both `s:` and `l:` from the lambda at once. But there is a
simple workaround for this: > :let both_s_and_l = { 's': s:, 'l': l: }
:echo object#lambda('x', 'x > 1 ? c.s.var : c.l.var')(1) <
* The number of arguments to the lambda is limited by the maximum number
allowed by Vim.
Examples:
>
:echo object#lambda('x y', 'x + y')(1, 2)
3
:echo sort(range(10), object#lambda('x y', 'y - x'))
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
:echo object#map('aaa', object#lambda('s', 'toupper(s)'))
'AAA'
:call object#for('key val', object#enumerate([1, 2]), 'echo key val')
0 1
1 2
:let f = object#_lambda('x y', 'x + y')
:echo object#repr(f)
<'lambda' object>
:echo f.__call__(1, 2)
3
<
==============================================================================
INT *object.vim-int*
The `int()` converter and the wrapper type `int`.
CHECKED-CONVERSION-TO-INT
The built-in `str2nr()` does no checking to the string to be converted while
with simple regex it can be achieved. `int()` ensures that the base and the
string literal are valid and it can handle |Float| much like |float2nr()|
does. When called with no argument, it returns the constant `0`, which can be
useful to supply default value. It also hooks into `__int__()`. Very nice. See
some examples:
>
>>> object#int()
0
>>> object#int(1.2)
1
>>> object#int('0b101', 2)
5
>>> object#int('1234')
1234
>>> object#int('0xg', 16)
ValueError: invalid literal for int() with base 16: '0xg'
<
HANDY-FORMATTER-OF-VARIOUS-BASES
You can use `bin()`, `oct()` and `hex()` to get a |String| representations of
various bases from an integer. What was return can be parsed back to an `int`
with `int()`. Different from `printf()` with specifiers, these do not pull out
the 2-complementary digits when the argument is negative. Rather, they prefix
it with a negative sign:
>
>>> object#bin(-1)
-0b1
>>> printf('%b', -1)
11111111111111111111111111111111
>>> object#hex(-1)
-0x1
>>> printf('%x', -1)
ffffffff
<
WRAPPER-TYPE-INT
A wrapper type `int` is defined for the cases when object-oriented interface
is handy. `int` can be extended just as any other built-in type can. Just
rememebr keeping it at the very end of your base list since for efficiency,
`__init__()` of it does not call `super()`.
Data descriptor for `int`:
`INT_MAX`: maximum value of |Number|.
`INT_MIN`: minimum value of |Number|.
`INT_WIDTH`: bit-width of |Number|.
Here are some examples:
>
>>> let i = object#_int(1)
>>> i
1
>>> i.numerator
1
>>> i.real
1
>>> i.imag
0
>>> object#hash(i)
1
>>> object#abs(i)
1
>>> object#int_()
<type 'int'>
<
==============================================================================
DICTIONARIES *object.vim-dicts*
*object.vim.file*
A file object for line-oriented I/O.
*object.vim.list*
A wrapper class of built-in |List|.
*object.vim.super*
An object that forwards method calls to parents or siblings of a type.
Special attributes:
* __self__: the bound object.
* __self_class__: type of the bound object.
* __thisclass__: type that got passed to `super_()`.
==============================================================================
FUNCTIONS *object.vim-functions*
class(...) *object#class#class()*
Define a class that has a {name} and [bases].
>
class(name) -> inherited from object
class(name, bases) -> inherited from bases
<
{name} should be a |String| of valid identifier. [bases] should be a class
or a |List| of classes. If no [bases] are given or [bases] is an empty
|List|, the new class will subclass `object`.
new(...) *object#class#new()*
Create a new instance of {cls}.
>
new(cls[, args]) -> a new instance of cls
<
new_(...) *object#class#new_()*
Create a new instance of {cls}.
>
new_(cls, args) -> a new instance of cls
<
type(...) *object#class#type()*
Return the type of an object or create a new type.
>
type(obj) -> the type of obj
type(name, bases, dict) -> a new type.
<
isinstance(...) *object#class#isinstance()*
Return whether {obj} is an instance of {cls}.
>
isinstance(obj, cls) -> if obj is an instance of cls
<
issubclass(...) *object#class#issubclass()*
Return whether {cls} is a subclass of {base}.
>
issubclass(cls, base) -> if cls is a subclass of base
<
object#cmp#cmp({a}) *object#cmp#cmp()*
{a}
dict(...) *object#dict#dict()*
Create a plain |Dict|.
>
dict() -> an empty dictionary.
dict(iterable) -> initiazed with 2-list items.
dict(plain dictionary) -> a copy of the argument.
dict(dict object) -> a copy of the underlying dictionary.
<
_dict(...) *object#dict#_dict()*
Create a dict object. See |dict()|.
dict_() *object#dict#dict_()*
Return the dict type.
BaseException(...) *object#except#BaseException()*
User can use `BaseException()` to define their own exception functions.
>
BaseException(type) -> type:
BaseException(type, [msg]) -> type: msg
BaseException(type, [msg, *args] -> type: printf(msg, *args)
<
Examples:
>
function! MyException(...)
return object#BaseException('MyException', a:000)
endfunction
<
Exception(...) *object#except#Exception()*
Generic exception.
ValueError(...) *object#except#ValueError()*
The value of function arguments went wrong.
TypeError(...) *object#except#TypeError()*
Unsupported operation for a type or wrong number of arguments passed to a
function.
AttributeError(...) *object#except#AttributeError()*
The object has no such attribute or the attribute is readonly.
StopIteration(...) *object#except#StopIteration()*
Iteration stops.
IndexError(...) *object#except#IndexError()*
Index out of range for sequences.
KeyError(...) *object#except#KeyError()*
Key out of range for sequences.
IOError(...) *object#except#IOError()*
File not writable or readable. Operation on a closed file. Thrown by file
objects usually.
open(...) *object#file#open()*
Open a file.
>
open(filename) -> open for reading.
open(filename, mode) -> open for mode.
<
The [mode] can be 'r', 'w' or 'a' for reading (default), writing or
appending, respectively. The file will be created if it doesn't exist when
opened for writing or appending. It will be truncated when opened for
writing. Add a 'b' to the [mode] for binary files. See |readfile()| and
|writefile()|. Add a '+' to the [mode] to allow simultaneous reading and
writing.
object#file#file_() *object#file#file_()*
Return the file class object.
int(...) *object#int#int()*
Convert [args] to a |Number|, i.e., an int.
>
int() -> 0
int(Number) -> returned as it
int(Float) -> truncated towards zero as float2nr() does
int(String, base=10) -> convert to Number as str2nr() does
<
Valid bases are 2, 8, 10, 16 as accepted by |str2nr()|.
bin(...) *object#int#bin()*
Return |String| representation for |Number| in base 2.
>
bin(3) -> '0b11'
bin(-3) -> '-0b11'
<
hex(...) *object#int#hex()*
Return |String| representation for |Number| in base 16.
>
hex(11) -> '0xb'
hex(-11) -> '-0xb'
<
oct(...) *object#int#oct()*
Return |String| representation for |Number| in base 8.
>
oct(8) -> '010'
oct(-8) -> '-010'
<
abs(...) *object#int#abs()*
Return the absolute value of an object.
>
abs(Number or Float) -> abs(num)
abs(obj) -> obj.__abs__()
<
_int(...) *object#int#_int()*
Create an int object.
int_(...) *object#int#int_()*
Return the int type.
iter(...) *object#iter#iter()*
Return an iterator from {obj}.
>
iter(List) -> list_iter
iter(String) -> str_iter
iter(iterator) -> returned as it
iter(obj) -> obj.__iter__()
<
next(...) *object#iter#next()*
Retrieve the next item from an iterator.
>
next(iter) -> next item from iter
<
any(...) *object#iter#any()*
If any of the items is True.
>
any(iterable) -> if any of the items is True
<
all(...) *object#iter#all()*
If all of the items is True.
>
all(iterable) -> if all of the items is True
<
enumerate(...) *object#iter#enumerate()*
Return an iterator for index, value of {iter}.
>
enumerate(iterable, start=0) -> [start, item_0], ..., [N, item_N]
<
zip(...) *object#iter#zip()*
Return an iterator that zips a list of sequences.
>
zip(iter[,*iters]) -> [seq1[0], seq2[0], ...], ...
<
The iterator stops at the shortest sequence.
map(...) *object#iter#map()*
Tranform the iterable with lambda (String).
>
map(iter, lambda) -> a new list mapped from iter
<
filter(...) *object#iter#filter()*
Create a new list filtering {iter} using a lambda (String).
>
filter(iter) -> a new list without falsy items.
filter(iter, lambda) -> a new list filtered from iter.
<
Truthness is tested by `bool()`.
sum(...) *object#iter#sum()*
Return the sum of items from {iter} plus [start], which defaults to 0.
>
sum(iter, start=0) -> start + the sum of items.
<
Items must be numeric.
lambda(...) *object#lambda#lambda()*
Create a one-line |Funcref| that takes [vars] as arguments and returns the
result of evaluation of [expr].
>
lambda(vars, expr[,closure]) -> Funcref
<
If a [closure] argument is given, the variables `var` living inside the
closure are available as `c.var` from the lambda expression.
_lambda(...) *object#lambda#_lambda()*
Create a `lambda` object. See |lambda()|.
>
_lambda(vars, expr[,closure]).__call__
<
lambda_(...) *object#lambda#lambda_()*
Return the lambda class.
object#lambda#for({iterable}, {names}, {cmd}, [closure]) *object#lambda#for()*
Execute a |List| of commands while iterating over {iterable}. {names} is a
space-separated |String|s that contains the variable names used as the items
in the {iterable}. If a [closure] is given, it is available as `c.var`
inside the code.
{cmd} is a |String| of Ex command or a |List| of such strings. During each
iteration, the commands are executed in the order that they are specified in
the list. Examples:
>
call object#for('x', range(10), ['if x > 0', 'echo x', 'endif'])
call object#for('f', files, 'call f.close()')
call object#for('key val', items(dict), 'echo key val')
<
_list(...) *object#list#_list()*
Create a list object.
list_(...) *object#list#list_()*
Return the list type.
list(...) *object#list#list()*
Create a plain |List|.
>
list() -> an empty list.
list(plain list) -> a shallow copy of it.
list(iterable) -> initiazed with items of iterable.
list(list object) -> a copy of the underlying list.
<
hash(...) *object#mapping#hash()*
Return the hash value of {obj}.
{obj} can be a |Number|, a |String| a |Funcref| or special variables like
|v:none| and |v:false| (if present), or an object with __hash__() defined.
Throws ERROR(TypeError) if hash() is not possible for {obj}.
Throws ERROR(WrongType) if __hash__ is not a |Funcref| or returns
something NAN (Not A Number).
getitem(...) *object#mapping#getitem()*
Return the value at {key} in {obj} as if {obj} is a mapping.
>
getitem(obj, key) -> obj[key]
<
If {obj} is a |List|, |String| or plain |Dict|, checked-version of built-in
subscription will be called. Vim error about |List| index will translate to
@exception(IndexError). Vim's ignorance about the index to |String| will be
augmented by checking the emptiness of the value.
Throws ERROR(WrongType) if {obj} is a |String| or |List| but {key} is not a
|Number| or {obj} is a |Dict| but {key} is not a |String|.
Throws ERROR(IndexError) if {key} is out of range for |String| or |List|.
Throws ERROR(KeyError) if {key} is not present in the |Dict|.
setitem(...) *object#mapping#setitem()*
Set the value at {key} of {obj} to {val}.
>
setitem(obj, key, val) -> let obj[key] = val
<
If {obj} is a |List|, |String| or a |Dict|, subscription version of |let|
will be uesd. Otherwise, __setitem__ of {obj} will be used.
getattr(...) *object#protocols#getattr()*
Get the attribute {name} from {obj}.
>
getattr(obj, name[,default]) -> attribute of obj
<
`getattr()` goes through three stages to lookup an attribute:
1. Dictionary lookup `obj[name]`. If `__getattribute__()` is defined for
{obj}, it will be called instead.
2. If 1 fails with `AttributeError` and if `__getattr__()` is defined for
{obj}, it will be tried. Otherwise, 2 fails.
3. If 2 fails, and if [default] is given, it will be returned. Otherwise,
the latest `AttributeError` is thrown.
setattr(...) *object#protocols#setattr()*
Set the {name} attribute of {obj} to {val}.
>
setattr(plain dict, name, val) -> let d[name] = val
setattr(obj, name, val) -> obj.__setattr__(name, val)
<
hasattr(...) *object#protocols#hasattr()*
Test whether {obj} has attribute {name}.
>
hasattr(obj, name) -> getattr(obj, name) succeeds or not.
<
Throws ERROR(WrongType) if {name} is not a String.
Throws ERROR(WrongType) if {obj} is not a Dict.
repr(...) *object#protocols#repr()*
Generate string representation for {obj}.
>
repr(obj) -> String
<
Fail back on |string()|.
len(...) *object#protocols#len()*
Return the length of {obj}.
>
len(String, List or Dict) -> len(obj)
len(obj) -> obj.__len__()
<
dir(...) *object#protocols#dir()*
Return a |List| of names of all attributes from {obj}. If {obj} defines
__dir__(), it is called instead.
>
dir(obj) -> a list of names of attributes of obj.
<
contains(...) *object#protocols#contains()*
Test whether {item} is in {obj}.
>
contains(item, obj) -> item in obj.
<
super(...) *object#super#super()*
Return a super object bound to {obj} that delegates method calls to the
parents and siblings of {type}.
>
super(type, obj) -> bound super object
<
Throws ERROR(TypeError) if object#isinstance({obj}, {type}) is false.
Throws ERROR(TypeError) if {type} is at the end of the MRO of {obj}.
super_(...) *object#super#super_()*
Retrieve method {name} bound to {obj} from the parent or sibling of {type}.
>
super_(type, obj, name) -> Funcref
<
The MRO of {obj} is visited started from {type} and the first attribute with
{name} that is a |Funcref|, i.e., the first method, is returned.
Throws ERROR(TypeError) if object#isinstance({obj}, {type}) is false.
Throws ERROR(TypeError) if {type} is at the end of the MRO of {obj}.
Throws ERROR(AttributeError) if {name} cannot be resolved.
object() *object#types#object()*
Create a plain object.
object_() *object#types#object_()*
Return the object class
type_() *object#types#type_()*
Return the type class
NoneType() *object#types#NoneType()*
Return the NoneType class
None() *object#types#None()*
Return the None object
bool(...) *object#types#bool()*
Convert [args] to a Bool, i.e., 0 or 1.
>
bool() -> False
bool(Funcref) -> True
bool(List, String or plain Dict) -> not empty
bool(Number) -> non-zero
bool(Float) -> non-zero
bool(v:false, v:null, v:none) -> False
bool(v:true) -> True
bool(obj) -> obj.__bool__()