OILS / doc / ref / chap-builtin-func.md View on Github | oils.pub

558 lines, 328 significant
1---
2title: Builtin Functions (Oils Reference)
3all_docs_url: ..
4body_css_class: width40
5default_highlighter: oils-sh
6preserve_anchor_case: yes
7---
8
9<div class="doc-ref-header">
10
11[Oils Reference](index.html) &mdash;
12Chapter **Builtin Functions**
13
14</div>
15
16This chapter describes builtin functions (as opposed to [builtin
17commands](chap-builtin-cmd.html).)
18
19<span class="in-progress">(in progress)</span>
20
21<div id="dense-toc">
22</div>
23
24## Values
25
26### len()
27
28Returns the
29
30- number of entries in a `List`
31- number of pairs in a `Dict`
32- number of bytes in a `Str`
33 - TODO: `countRunes()` can return the number of UTF-8 encoded code points.
34
35### func/type()
36
37Given an arbitrary value, returns a string representing the value's runtime
38type.
39
40For example:
41
42 var d = {'foo': 'bar'}
43 var n = 42
44
45 = type(d) # => (Str) 'Dict'
46 = type(n) # => (Str) 'Int'
47
48Similar names: [type][]
49
50[type]: chap-index.html#type
51
52
53## Conversions
54
55### bool()
56
57Returns the truth value of its argument. Similar to `bool()` in python, it
58returns `false` for:
59
60- `false`, `0`, `0.0`, `''`, `{}`, `[]`, and `null`.
61
62Returns `true` for all other values.
63
64### int()
65
66Given a float, returns the largest integer that is less than its argument (i.e. `floor()`).
67
68 = int(1.99) # => (Int) 1
69
70Given a string, `Int()` will attempt to convert the string to a base-10
71integer.
72
73 = int('10') # => (Int) 10
74
75<!-- TODO
76The base can be overridden by calling with a second argument.
77 = int('10', base=2) # => (Int) 2
78-->
79
80```raw
81= int('not_an_integer') # fails with an expression error
82```
83
84### float()
85
86Given an integer, returns the corresponding floating point representation.
87
88 = float(1) # => (Float) 1.0
89
90Given a string, `Float()` will attempt to convert the string to float.
91
92 = float('1.23') # => (Float) 1.23
93
94```raw
95= float('bar') # fails with an expression error
96```
97
98### str()
99
100Converts a `Float` or `Int` to a string.
101
102### list()
103
104Given a list, returns a shallow copy of the original.
105
106 = list({'a': 1, 'b': 2}) # => (List) ['a', 'b']
107
108Given an iterable value (e.g. a range or dictionary), returns a list containing
109one element for each item in the original collection.
110
111 = list(1 ..= 5) # => (List) [1, 2, 3, 4, 5]
112
113### dict()
114
115Given a dictionary, returns a shallow copy of the original.
116
117### runes()
118
119TODO
120
121Given a string, decodes UTF-8 into a List of integer "runes" (aka code points).
122
123Each rune is in the range `U+0` to `U+110000`, and **excludes** the surrogate
124range.
125
126```raw
127runes(s, start=-1, end=-1)
128```
129
130TODO: How do we signal errors?
131
132(`runes()` can be used to implement implemented Python's `ord()`.)
133
134### encodeRunes()
135
136TODO
137
138Given a List of integer "runes" (aka code points), return a string.
139
140(`encodeRunes()` can be used to implement implemented Python's `chr()`.)
141
142### bytes()
143
144TODO
145
146Given a string, return a List of integer byte values.
147
148Each byte is in the range 0 to 255.
149
150### encodeBytes()
151
152TODO
153
154Given a List of integer byte values, return a string.
155
156## Str
157
158### strcmp()
159
160Compare 2 strings, using lexicographic order on bytes.
161
162Returns 0 if the strings are equal:
163
164 = strcmp('z', 'z') # => (Int) 0
165
166Or -1 if the first is less than the second:
167
168 = strcmp('a', 'aa') # => (Int) -1
169
170Or 1 if the first is greater than the second:
171
172 = strcmp('z', 'a') # => (Int) 1
173
174### shSplit()
175
176Split a string into a List of strings, using the shell algorithm that respects
177`$IFS`.
178
179Prefer [split()][split] to `shSplit()`.
180
181[split]: chap-type-method.html#split
182
183## List
184
185### join()
186
187Given a List, stringify its items, and join them by a separator. The default
188separator is the empty string.
189
190 var x = ['a', 'b', 'c']
191
192 echo $[join(x)] # => abc
193
194 # optional separator
195 echo $[join(x, ' ')] # => a b c
196
197As a reminder, you can call it with the [fat-arrow][] operator `=>` for function chaining:
198
199 var items = [1, 2, 3]
200
201 json write (items => join()) # => "123"
202 json write (items => join(' ')) # => "1 2 3"
203 json write (items => join(', ')) # => "1, 2, 3"
204
205[fat-arrow]: chap-expr-lang.html#fat-arrow
206
207## Dict
208
209### keys()
210
211Returns all existing keys from a dict as a list of strings.
212
213 var en2fr = {
214 hello: "bonjour",
215 friend: "ami",
216 cat: "chat"
217 }
218 = keys(en2fr)
219 # => (List 0x4689) ["hello","friend","cat"]
220
221### values()
222
223Similar to `keys()`, but returns the values of the dictionary.
224
225 var person = {
226 name: "Foo",
227 age: 25,
228 hobbies: :|walking reading|
229 }
230 = values(en2fr)
231 # => (List 0x4689) ["Foo",25,["walking","reading"]]
232
233### get()
234
235Return value for given key, falling back to the default value if the key
236doesn't exist.
237
238 var book = {
239 title: "Hitchhiker's Guide",
240 published: 1979,
241 }
242
243 var published = get(book, 'published', null)
244 = published
245 # => (Int) 1979
246
247 var author = get(book, 'author', "???")
248 = author
249 # => (Str) "???"
250
251If not specified, the default value is `null`:
252
253 var author = get(book, 'author')
254 = author
255 # => (Null) null
256
257## Float
258
259### floatsEqual()
260
261Check if two floating point numbers are equal.
262
263 = floatsEqual(42.0, 42.0) # => (Bool) true
264
265It's usually better to make an approximate comparison:
266
267 use $LIB_YSH/math.ysh --pick abs
268 var f1 = 0.3
269 var f2 = 0.4
270 = abs(f1 - f2) < 0.001 # => (Bool) false
271
272## Obj
273
274Let's use this definition:
275
276 var fields = {x: 42}
277 var obj = Obj.new(fields, null)
278
279### first()
280
281Get the Dict that contains an object's properties.
282
283 = first(obj) # => (Dict) {x: 42}
284
285The Dict and Obj share the same storage. So if the Dict is modified, the
286object is too.
287
288If you want a copy, use `dict(obj)`.
289
290### rest()
291
292Get the "prototype" of an Obj, which is another Obj, or null:
293
294 = rest(obj) # => (Null) null
295
296## Word
297
298### glob()
299
300Return a list of of files that much a glob pattern.
301
302 = glob('*.py') # => (List) ['__init__.py']
303
304<!--
305TODO: the shopt options like GLOBIGNORE should be exposed as params?
306-->
307
308See [glob-pat][] for syntax.
309
310[glob-pat]: chap-mini-lang.html#glob-pat
311
312### maybe()
313
314Turn a string into a list, based on its emptiness.
315
316It's designed to be used to construct `argv` arrays, along with
317[expr-splice][].
318
319 var empty = ''
320 write -- ale @[maybe(empty)] corn # => ale corn
321
322 var s = 'bean'
323 write -- ale @[maybe(s)] corn # => ale bean corn
324
325[expr-splice]: chap-word-lang.html#expr-splice
326
327## Serialize
328
329### toJson()
330
331Convert an object in memory to JSON text:
332
333 = toJson({name: "alice"}) # => (Str) '{"name":"alice"}'
334
335Add indentation by passing the `space` param:
336
337 = toJson([42], space=2) # => (Str) "[\n 42\n]"
338
339Turn non-serializable types into `null`, instead of raising an error:
340
341 = toJson(/d+/, type_errors=false) # => (Str) 'null'
342
343The `toJson()` function is to `json write (x)`, except the default value of
344`space` is 0.
345
346See [err-json-encode][] for errors.
347
348[err-json-encode]: chap-errors.html#err-json-encode
349
350### fromJson()
351
352Convert JSON text to an object in memory:
353
354 = fromJson('{"name":"alice"}') # => (Dict) {"name": "alice"}
355
356Similar to `json read <<< '{"name": "alice"}'`.
357
358See [err-json-decode][] for errors.
359
360[err-json-decode]: chap-errors.html#err-json-decode
361
362### toJson8()
363
364Like `toJson()`, but it also converts binary data (non-Unicode strings) to
365J8-style `b'foo \yff'` strings.
366
367In contrast, `toJson()` will do a lossy conversion with the Unicode replacement
368character.
369
370See [err-json8-encode][] for errors.
371
372[err-json8-encode]: chap-errors.html#err-json8-encode
373
374### fromJson8()
375
376Like `fromJson()`, but it also accepts binary data denoted by J8-style `b'foo
377\yff'` strings.
378
379See [err-json8-decode][] for errors.
380
381[err-json8-decode]: chap-errors.html#err-json8-decode
382
383## Pattern
384
385### `_group()`
386
387Like `Match.group()`, but accesses the global match created by `~`:
388
389 if ('foo42' ~ / d+ /) {
390 echo $[_group(0)] # => 42
391 }
392
393### `_start()`
394
395Like `Match.start()`, but accesses the global match created by `~`:
396
397 if ('foo42' ~ / d+ /) {
398 echo $[_start(0)] # => 3
399 }
400
401### `_end()`
402
403Like `Match.end()`, but accesses the global match created by `~`:
404
405 if ('foo42' ~ / d+ /) {
406 echo $[_end(0)] # => 5
407 }
408
409## Reflection
410
411### func/eval()
412
413This function is like [`io->eval()`][io/eval], but it disallows I/O.
414
415Example:
416
417 var cmd = ^(const x = 42; )
418 = eval(cmd, to_dict=true) # => (Dict) {x: 42}
419
420[io/eval]: chap-type-method.html#io/eval
421
422### func/evalExpr()
423
424This function is like [`io->evalExpr()`][io/evalExpr], but it disallows I/O.
425
426Example:
427
428 var x = 42
429 var expr = ^[x + 1]
430 var val = evalExpr(expr) # 43
431
432[io/evalExpr]: chap-type-method.html#io/evalExpr
433
434## Introspect
435
436### `shvarGet()`
437
438Given a variable name, return its value. It uses the "dynamic scope" rule,
439which looks up the stack for a variable.
440
441It's meant to be used with `shvar`:
442
443 proc proc1 {
444 shvar PATH=/tmp { # temporarily set PATH in this stack frame
445 echo
446 }
447
448 proc2
449 }
450
451 proc proc2 {
452 proc3
453 }
454
455 proc proc3 {
456 var path = shvarGet('PATH') # Look up the stack (dynamic scoping)
457 echo $path # => /tmp
458 }
459
460 proc1
461
462Note that `shvar` is usually for string variables, and is analogous to `shopt`
463for "booleans".
464
465If the variable isn't defined, `shvarGet()` returns `null`. So there's no way
466to distinguish an undefined variable from one that's `null`.
467
468### `getVar()`
469
470Given a variable name, return its value.
471
472 var x = 42
473 = getVar('x') # => (Int) 42
474
475The variable may be local or global. (Compare with `shvarGet()`.) the "dynamic
476scope" rule.)
477
478If the variable isn't defined, `getVar()` returns `null`. So there's no way to
479distinguish an undefined variable from one that's `null`.
480
481### `setVar()`
482
483Bind a name to a value, in the local scope. Returns nothing.
484
485 call setVar('myname', 42)
486
487This is like
488
489 setvar myname = 42
490
491except the name can is a string, which can be constructed at runtime.
492
493---
494
495You can also bind globals:
496
497 call setVar('myname', 42, global=true)
498
499which is like
500
501 setglobal myname = 42
502
503### `getShFunction`
504
505Given the name of a shell function, return the corresponding [Proc][] value, or
506`null` if it's not found.
507
508[Proc]: chap-type-method.html#Proc
509
510### `parseCommand()`
511
512Given a code string, parse it as a command (with the current parse options).
513
514Returns a `value.Command` instance, or raises an error.
515
516### `parseExpr()`
517
518TODO:
519
520Given a code string, parse it as an expression.
521
522Returns a `value.Expr` instance, or raises an error.
523
524### `bindFrame()`
525
526TODO
527
528## Hay Config
529
530### parseHay()
531
532### evalHay()
533
534
535## Hashing
536
537### sha1dc()
538
539Git's algorithm.
540
541### sha256()
542
543
544<!--
545
546### Better Syntax
547
548These functions give better syntax to existing shell constructs.
549
550- `shQuote()` for `printf %q` and `${x@Q}`
551- `trimLeft()` for `${x#prefix}` and `${x##prefix}`
552- `trimRight()` for `${x%suffix}` and `${x%%suffix}`
553- `trimLeftGlob()` and `trimRightGlob()` for slow, legacy glob
554- `upper()` for `${x^^}`
555- `lower()` for `${x,,}`
556- `strftime()`: hidden in `printf`
557
558-->