polars-df 0.10.0-x86_64-linux-musl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +3 -0
  3. data/CHANGELOG.md +175 -0
  4. data/Cargo.lock +2536 -0
  5. data/Cargo.toml +6 -0
  6. data/LICENSE-THIRD-PARTY.txt +38726 -0
  7. data/LICENSE.txt +20 -0
  8. data/README.md +437 -0
  9. data/lib/polars/3.1/polars.so +0 -0
  10. data/lib/polars/3.2/polars.so +0 -0
  11. data/lib/polars/3.3/polars.so +0 -0
  12. data/lib/polars/array_expr.rb +537 -0
  13. data/lib/polars/array_name_space.rb +423 -0
  14. data/lib/polars/batched_csv_reader.rb +98 -0
  15. data/lib/polars/binary_expr.rb +77 -0
  16. data/lib/polars/binary_name_space.rb +66 -0
  17. data/lib/polars/cat_expr.rb +72 -0
  18. data/lib/polars/cat_name_space.rb +125 -0
  19. data/lib/polars/config.rb +530 -0
  20. data/lib/polars/convert.rb +93 -0
  21. data/lib/polars/data_frame.rb +5418 -0
  22. data/lib/polars/data_types.rb +466 -0
  23. data/lib/polars/date_time_expr.rb +1444 -0
  24. data/lib/polars/date_time_name_space.rb +1484 -0
  25. data/lib/polars/dynamic_group_by.rb +52 -0
  26. data/lib/polars/exceptions.rb +31 -0
  27. data/lib/polars/expr.rb +6105 -0
  28. data/lib/polars/expr_dispatch.rb +22 -0
  29. data/lib/polars/functions/aggregation/horizontal.rb +246 -0
  30. data/lib/polars/functions/aggregation/vertical.rb +282 -0
  31. data/lib/polars/functions/as_datatype.rb +248 -0
  32. data/lib/polars/functions/col.rb +47 -0
  33. data/lib/polars/functions/eager.rb +182 -0
  34. data/lib/polars/functions/lazy.rb +1280 -0
  35. data/lib/polars/functions/len.rb +49 -0
  36. data/lib/polars/functions/lit.rb +35 -0
  37. data/lib/polars/functions/random.rb +16 -0
  38. data/lib/polars/functions/range/date_range.rb +103 -0
  39. data/lib/polars/functions/range/int_range.rb +51 -0
  40. data/lib/polars/functions/repeat.rb +144 -0
  41. data/lib/polars/functions/whenthen.rb +96 -0
  42. data/lib/polars/functions.rb +57 -0
  43. data/lib/polars/group_by.rb +548 -0
  44. data/lib/polars/io.rb +890 -0
  45. data/lib/polars/lazy_frame.rb +2833 -0
  46. data/lib/polars/lazy_group_by.rb +84 -0
  47. data/lib/polars/list_expr.rb +791 -0
  48. data/lib/polars/list_name_space.rb +445 -0
  49. data/lib/polars/meta_expr.rb +222 -0
  50. data/lib/polars/name_expr.rb +198 -0
  51. data/lib/polars/plot.rb +109 -0
  52. data/lib/polars/rolling_group_by.rb +37 -0
  53. data/lib/polars/series.rb +4527 -0
  54. data/lib/polars/slice.rb +104 -0
  55. data/lib/polars/sql_context.rb +194 -0
  56. data/lib/polars/string_cache.rb +75 -0
  57. data/lib/polars/string_expr.rb +1519 -0
  58. data/lib/polars/string_name_space.rb +810 -0
  59. data/lib/polars/struct_expr.rb +98 -0
  60. data/lib/polars/struct_name_space.rb +96 -0
  61. data/lib/polars/testing.rb +507 -0
  62. data/lib/polars/utils.rb +422 -0
  63. data/lib/polars/version.rb +4 -0
  64. data/lib/polars/whenthen.rb +83 -0
  65. data/lib/polars-df.rb +1 -0
  66. data/lib/polars.rb +72 -0
  67. metadata +125 -0
@@ -0,0 +1,445 @@
1
+ module Polars
2
+ # Series.list namespace.
3
+ class ListNameSpace
4
+ include ExprDispatch
5
+
6
+ self._accessor = "list"
7
+
8
+ # @private
9
+ def initialize(series)
10
+ self._s = series._s
11
+ end
12
+
13
+ # Evaluate whether all boolean values in a list are true.
14
+ #
15
+ # @return [Series]
16
+ #
17
+ # @example
18
+ # s = Polars::Series.new(
19
+ # [[true, true], [false, true], [false, false], [nil], [], nil],
20
+ # dtype: Polars::List.new(Polars::Boolean)
21
+ # )
22
+ # s.list.all
23
+ # # =>
24
+ # # shape: (6,)
25
+ # # Series: '' [bool]
26
+ # # [
27
+ # # true
28
+ # # false
29
+ # # false
30
+ # # true
31
+ # # true
32
+ # # null
33
+ # # ]
34
+ def all
35
+ super
36
+ end
37
+
38
+ # Evaluate whether any boolean value in a list is true.
39
+ #
40
+ # @return [Series]
41
+ #
42
+ # @example
43
+ # s = Polars::Series.new(
44
+ # [[true, true], [false, true], [false, false], [nil], [], nil],
45
+ # dtype: Polars::List.new(Polars::Boolean)
46
+ # )
47
+ # s.list.any
48
+ # # =>
49
+ # # shape: (6,)
50
+ # # Series: '' [bool]
51
+ # # [
52
+ # # true
53
+ # # true
54
+ # # false
55
+ # # false
56
+ # # false
57
+ # # null
58
+ # # ]
59
+ def any
60
+ super
61
+ end
62
+
63
+ # Get the length of the arrays as UInt32.
64
+ #
65
+ # @return [Series]
66
+ #
67
+ # @example
68
+ # s = Polars::Series.new([[1, 2, 3], [5]])
69
+ # s.list.lengths
70
+ # # =>
71
+ # # shape: (2,)
72
+ # # Series: '' [u32]
73
+ # # [
74
+ # # 3
75
+ # # 1
76
+ # # ]
77
+ def lengths
78
+ super
79
+ end
80
+
81
+ # Drop all null values in the list.
82
+ #
83
+ # The original order of the remaining elements is preserved.
84
+ #
85
+ # @return [Series]
86
+ #
87
+ # @example
88
+ # s = Polars::Series.new("values", [[nil, 1, nil, 2], [nil], [3, 4]])
89
+ # s.list.drop_nulls
90
+ # # =>
91
+ # # shape: (3,)
92
+ # # Series: 'values' [list[i64]]
93
+ # # [
94
+ # # [1, 2]
95
+ # # []
96
+ # # [3, 4]
97
+ # # ]
98
+ def drop_nulls
99
+ super
100
+ end
101
+
102
+ # Sample from this list.
103
+ #
104
+ # @param n [Integer]
105
+ # Number of items to return. Cannot be used with `fraction`. Defaults to 1 if
106
+ # `fraction` is nil.
107
+ # @param fraction [Float]
108
+ # Fraction of items to return. Cannot be used with `n`.
109
+ # @param with_replacement [Boolean]
110
+ # Allow values to be sampled more than once.
111
+ # @param shuffle [Boolean]
112
+ # Shuffle the order of sampled data points.
113
+ # @param seed [Integer]
114
+ # Seed for the random number generator. If set to nil (default), a
115
+ # random seed is generated for each sample operation.
116
+ #
117
+ # @return [Series]
118
+ #
119
+ # @example
120
+ # s = Polars::Series.new("values", [[1, 2, 3], [4, 5]])
121
+ # s.list.sample(n: Polars::Series.new("n", [2, 1]), seed: 1)
122
+ # # =>
123
+ # # shape: (2,)
124
+ # # Series: 'values' [list[i64]]
125
+ # # [
126
+ # # [2, 1]
127
+ # # [5]
128
+ # # ]
129
+ def sample(n: nil, fraction: nil, with_replacement: false, shuffle: false, seed: nil)
130
+ super
131
+ end
132
+
133
+ # Sum all the arrays in the list.
134
+ #
135
+ # @return [Series]
136
+ def sum
137
+ super
138
+ end
139
+
140
+ # Compute the max value of the arrays in the list.
141
+ #
142
+ # @return [Series]
143
+ def max
144
+ super
145
+ end
146
+
147
+ # Compute the min value of the arrays in the list.
148
+ #
149
+ # @return [Series]
150
+ def min
151
+ super
152
+ end
153
+
154
+ # Compute the mean value of the arrays in the list.
155
+ #
156
+ # @return [Series]
157
+ def mean
158
+ super
159
+ end
160
+
161
+ # Sort the arrays in the list.
162
+ #
163
+ # @return [Series]
164
+ def sort(reverse: false)
165
+ super
166
+ end
167
+
168
+ # Reverse the arrays in the list.
169
+ #
170
+ # @return [Series]
171
+ def reverse
172
+ super
173
+ end
174
+
175
+ # Get the unique/distinct values in the list.
176
+ #
177
+ # @return [Series]
178
+ def unique
179
+ super
180
+ end
181
+
182
+ # Concat the arrays in a Series dtype List in linear time.
183
+ #
184
+ # @param other [Object]
185
+ # Columns to concat into a List Series
186
+ #
187
+ # @return [Series]
188
+ def concat(other)
189
+ super
190
+ end
191
+
192
+ # Get the value by index in the sublists.
193
+ #
194
+ # So index `0` would return the first item of every sublist
195
+ # and index `-1` would return the last item of every sublist
196
+ # if an index is out of bounds, it will return a `None`.
197
+ #
198
+ # @param index [Integer]
199
+ # Index to return per sublist
200
+ #
201
+ # @return [Series]
202
+ def get(index)
203
+ super
204
+ end
205
+
206
+ # Get the value by index in the sublists.
207
+ #
208
+ # @return [Series]
209
+ def [](item)
210
+ get(item)
211
+ end
212
+
213
+ # Join all string items in a sublist and place a separator between them.
214
+ #
215
+ # This errors if inner type of list `!= Utf8`.
216
+ #
217
+ # @param separator [String]
218
+ # string to separate the items with
219
+ #
220
+ # @return [Series]
221
+ #
222
+ # @example
223
+ # s = Polars::Series.new([["foo", "bar"], ["hello", "world"]])
224
+ # s.list.join("-")
225
+ # # =>
226
+ # # shape: (2,)
227
+ # # Series: '' [str]
228
+ # # [
229
+ # # "foo-bar"
230
+ # # "hello-world"
231
+ # # ]
232
+ def join(separator)
233
+ super
234
+ end
235
+
236
+ # Get the first value of the sublists.
237
+ #
238
+ # @return [Series]
239
+ def first
240
+ super
241
+ end
242
+
243
+ # Get the last value of the sublists.
244
+ #
245
+ # @return [Series]
246
+ def last
247
+ super
248
+ end
249
+
250
+ # Check if sublists contain the given item.
251
+ #
252
+ # @param item [Object]
253
+ # Item that will be checked for membership.
254
+ #
255
+ # @return [Series]
256
+ def contains(item)
257
+ super
258
+ end
259
+
260
+ # Retrieve the index of the minimal value in every sublist.
261
+ #
262
+ # @return [Series]
263
+ def arg_min
264
+ super
265
+ end
266
+
267
+ # Retrieve the index of the maximum value in every sublist.
268
+ #
269
+ # @return [Series]
270
+ def arg_max
271
+ super
272
+ end
273
+
274
+ # Calculate the n-th discrete difference of every sublist.
275
+ #
276
+ # @param n [Integer]
277
+ # Number of slots to shift.
278
+ # @param null_behavior ["ignore", "drop"]
279
+ # How to handle null values.
280
+ #
281
+ # @return [Series]
282
+ #
283
+ # @example
284
+ # s = Polars::Series.new("a", [[1, 2, 3, 4], [10, 2, 1]])
285
+ # s.list.diff
286
+ # # =>
287
+ # # shape: (2,)
288
+ # # Series: 'a' [list[i64]]
289
+ # # [
290
+ # # [null, 1, … 1]
291
+ # # [null, -8, -1]
292
+ # # ]
293
+ def diff(n: 1, null_behavior: "ignore")
294
+ super
295
+ end
296
+
297
+ # Shift values by the given period.
298
+ #
299
+ # @param periods [Integer]
300
+ # Number of places to shift (may be negative).
301
+ #
302
+ # @return [Series]
303
+ #
304
+ # @example
305
+ # s = Polars::Series.new("a", [[1, 2, 3, 4], [10, 2, 1]])
306
+ # s.list.shift
307
+ # # =>
308
+ # # shape: (2,)
309
+ # # Series: 'a' [list[i64]]
310
+ # # [
311
+ # # [null, 1, … 3]
312
+ # # [null, 10, 2]
313
+ # # ]
314
+ def shift(periods = 1)
315
+ super
316
+ end
317
+
318
+ # Slice every sublist.
319
+ #
320
+ # @param offset [Integer]
321
+ # Start index. Negative indexing is supported.
322
+ # @param length [Integer]
323
+ # Length of the slice. If set to `nil` (default), the slice is taken to the
324
+ # end of the list.
325
+ #
326
+ # @return [Series]
327
+ #
328
+ # @example
329
+ # s = Polars::Series.new("a", [[1, 2, 3, 4], [10, 2, 1]])
330
+ # s.list.slice(1, 2)
331
+ # # =>
332
+ # # shape: (2,)
333
+ # # Series: 'a' [list[i64]]
334
+ # # [
335
+ # # [2, 3]
336
+ # # [2, 1]
337
+ # # ]
338
+ def slice(offset, length = nil)
339
+ super
340
+ end
341
+
342
+ # Slice the first `n` values of every sublist.
343
+ #
344
+ # @param n [Integer]
345
+ # Number of values to return for each sublist.
346
+ #
347
+ # @return [Series]
348
+ #
349
+ # @example
350
+ # s = Polars::Series.new("a", [[1, 2, 3, 4], [10, 2, 1]])
351
+ # s.list.head(2)
352
+ # # =>
353
+ # # shape: (2,)
354
+ # # Series: 'a' [list[i64]]
355
+ # # [
356
+ # # [1, 2]
357
+ # # [10, 2]
358
+ # # ]
359
+ def head(n = 5)
360
+ super
361
+ end
362
+
363
+ # Slice the last `n` values of every sublist.
364
+ #
365
+ # @param n [Integer]
366
+ # Number of values to return for each sublist.
367
+ #
368
+ # @return [Series]
369
+ #
370
+ # @example
371
+ # s = Polars::Series.new("a", [[1, 2, 3, 4], [10, 2, 1]])
372
+ # s.list.tail(2)
373
+ # # =>
374
+ # # shape: (2,)
375
+ # # Series: 'a' [list[i64]]
376
+ # # [
377
+ # # [3, 4]
378
+ # # [2, 1]
379
+ # # ]
380
+ def tail(n = 5)
381
+ super
382
+ end
383
+
384
+ # Convert the series of type `List` to a series of type `Struct`.
385
+ #
386
+ # @param n_field_strategy ["first_non_null", "max_width"]
387
+ # Strategy to determine the number of fields of the struct.
388
+ # @param name_generator [Object]
389
+ # A custom function that can be used to generate the field names.
390
+ # Default field names are `field_0, field_1 .. field_n`
391
+ #
392
+ # @return [Series]
393
+ #
394
+ # @example
395
+ # df = Polars::DataFrame.new({"a" => [[1, 2, 3], [1, 2]]})
396
+ # df.select([Polars.col("a").list.to_struct])
397
+ # # =>
398
+ # # shape: (2, 1)
399
+ # # ┌────────────┐
400
+ # # │ a │
401
+ # # │ --- │
402
+ # # │ struct[3] │
403
+ # # ╞════════════╡
404
+ # # │ {1,2,3} │
405
+ # # │ {1,2,null} │
406
+ # # └────────────┘
407
+ def to_struct(n_field_strategy: "first_non_null", name_generator: nil)
408
+ super
409
+ end
410
+
411
+ # Run any polars expression against the lists' elements.
412
+ #
413
+ # @param expr [Expr]
414
+ # Expression to run. Note that you can select an element with `Polars.first`, or
415
+ # `Polars.col`
416
+ # @param parallel [Boolean]
417
+ # Run all expression parallel. Don't activate this blindly.
418
+ # Parallelism is worth it if there is enough work to do per thread.
419
+ #
420
+ # This likely should not be use in the group by context, because we already
421
+ # parallel execution per group
422
+ #
423
+ # @return [Series]
424
+ #
425
+ # @example
426
+ # df = Polars::DataFrame.new({"a" => [1, 8, 3], "b" => [4, 5, 2]})
427
+ # df.with_column(
428
+ # Polars.concat_list(["a", "b"]).list.eval(Polars.element.rank).alias("rank")
429
+ # )
430
+ # # =>
431
+ # # shape: (3, 3)
432
+ # # ┌─────┬─────┬────────────┐
433
+ # # │ a ┆ b ┆ rank │
434
+ # # │ --- ┆ --- ┆ --- │
435
+ # # │ i64 ┆ i64 ┆ list[f64] │
436
+ # # ╞═════╪═════╪════════════╡
437
+ # # │ 1 ┆ 4 ┆ [1.0, 2.0] │
438
+ # # │ 8 ┆ 5 ┆ [2.0, 1.0] │
439
+ # # │ 3 ┆ 2 ┆ [2.0, 1.0] │
440
+ # # └─────┴─────┴────────────┘
441
+ def eval(expr, parallel: false)
442
+ super
443
+ end
444
+ end
445
+ end
@@ -0,0 +1,222 @@
1
+ module Polars
2
+ # Namespace for expressions on a meta level.
3
+ class MetaExpr
4
+ # @private
5
+ attr_accessor :_rbexpr
6
+
7
+ # @private
8
+ def initialize(expr)
9
+ self._rbexpr = expr._rbexpr
10
+ end
11
+
12
+ # Equal.
13
+ #
14
+ # @return [Boolean]
15
+ def ==(other)
16
+ _rbexpr.meta_eq(other._rbexpr)
17
+ end
18
+
19
+ # Not equal.
20
+ #
21
+ # @return [Boolean]
22
+ def !=(other)
23
+ !(self == other)
24
+ end
25
+
26
+ # Indicate if this expression is the same as another expression.
27
+ #
28
+ # @return [Boolean]
29
+ #
30
+ # @example
31
+ # foo_bar = Polars.col("foo").alias("bar")
32
+ # foo = Polars.col("foo")
33
+ # foo_bar.meta.eq(foo)
34
+ # # => false
35
+ # foo_bar2 = Polars.col("foo").alias("bar")
36
+ # foo_bar.meta.eq(foo_bar2)
37
+ # # => true
38
+ def eq(other)
39
+ _rbexpr.meta_eq(other._rbexpr)
40
+ end
41
+
42
+ # Indicate if this expression is NOT the same as another expression.
43
+ #
44
+ # @return [Boolean]
45
+ #
46
+ # @example
47
+ # foo_bar = Polars.col("foo").alias("bar")
48
+ # foo = Polars.col("foo")
49
+ # foo_bar.meta.ne(foo)
50
+ # # => true
51
+ # foo_bar2 = Polars.col("foo").alias("bar")
52
+ # foo_bar.meta.ne(foo_bar2)
53
+ # # => false
54
+ def ne(other)
55
+ !eq(other)
56
+ end
57
+
58
+ # Indicate if this expression expands into multiple expressions.
59
+ #
60
+ # @return [Boolean]
61
+ #
62
+ # @example
63
+ # e = Polars.col(["a", "b"]).alias("bar")
64
+ # e.meta.has_multiple_outputs
65
+ # # => true
66
+ def has_multiple_outputs
67
+ _rbexpr.meta_has_multiple_outputs
68
+ end
69
+
70
+ # Indicate if this expression is a basic (non-regex) unaliased column.
71
+ #
72
+ # @return [Boolean]
73
+ #
74
+ # @example
75
+ # e = Polars.col("foo")
76
+ # e.meta.is_column
77
+ # # => true
78
+ # e = Polars.col("foo") * Polars.col("bar")
79
+ # e.meta.is_column
80
+ # # => false
81
+ # e = Polars.col("^col.*\d+$")
82
+ # e.meta.is_column
83
+ # # => false
84
+ def is_column
85
+ _rbexpr.meta_is_column
86
+ end
87
+
88
+ # Indicate if this expression expands to columns that match a regex pattern.
89
+ #
90
+ # @return [Boolean]
91
+ #
92
+ # @example
93
+ # e = Polars.col("^.*$").alias("bar")
94
+ # e.meta.is_regex_projection
95
+ # # => true
96
+ def is_regex_projection
97
+ _rbexpr.meta_is_regex_projection
98
+ end
99
+
100
+ # Get the column name that this expression would produce.
101
+ #
102
+ # @return [String]
103
+ #
104
+ # @example
105
+ # e = Polars.col("foo") * Polars.col("bar")
106
+ # e.meta.output_name
107
+ # # => "foo"
108
+ # e_filter = Polars.col("foo").filter(Polars.col("bar") == 13)
109
+ # e_filter.meta.output_name
110
+ # # => "foo"
111
+ # e_sum_over = Polars.sum("foo").over("groups")
112
+ # e_sum_over.meta.output_name
113
+ # # => "foo"
114
+ # e_sum_slice = Polars.sum("foo").slice(Polars.len - 10, Polars.col("bar"))
115
+ # e_sum_slice.meta.output_name
116
+ # # => "foo"
117
+ # Polars.len.meta.output_name
118
+ # # => "len"
119
+ def output_name
120
+ _rbexpr.meta_output_name
121
+ end
122
+
123
+ # Pop the latest expression and return the input(s) of the popped expression.
124
+ #
125
+ # @return [Array]
126
+ #
127
+ # @example
128
+ # e = Polars.col("foo").alias("bar")
129
+ # first = e.meta.pop[0]
130
+ # _ = first.meta == Polars.col("foo")
131
+ # # => true
132
+ # _ = first.meta == Polars.col("bar")
133
+ # # => false
134
+ def pop
135
+ _rbexpr.meta_pop.map { |e| Utils.wrap_expr(e) }
136
+ end
137
+
138
+ # Get a list with the root column name.
139
+ #
140
+ # @return [Array]
141
+ #
142
+ # @example
143
+ # e = Polars.col("foo") * Polars.col("bar")
144
+ # e.meta.root_names
145
+ # # => ["foo", "bar"]
146
+ # e_filter = Polars.col("foo").filter(Polars.col("bar") == 13)
147
+ # e_filter.meta.root_names
148
+ # # => ["foo", "bar"]
149
+ # e_sum_over = Polars.sum("foo").over("groups")
150
+ # e_sum_over.meta.root_names
151
+ # # => ["foo", "groups"]
152
+ # e_sum_slice = Polars.sum("foo").slice(Polars.len - 10, Polars.col("bar"))
153
+ # e_sum_slice.meta.root_names
154
+ # # => ["foo", "bar"]
155
+ def root_names
156
+ _rbexpr.meta_roots
157
+ end
158
+
159
+ # Undo any renaming operation like `alias` or `keep_name`.
160
+ #
161
+ # @return [Expr]
162
+ #
163
+ # @example
164
+ # e = Polars.col("foo").alias("bar")
165
+ # _ = e.meta.undo_aliases.meta == Polars.col("foo")
166
+ # # => true
167
+ # e = Polars.col("foo").sum.over("bar")
168
+ # _ = e.name.keep.meta.undo_aliases.meta == e
169
+ # # => true
170
+ def undo_aliases
171
+ Utils.wrap_expr(_rbexpr.meta_undo_aliases)
172
+ end
173
+
174
+ # Turn this expression in a selector.
175
+ #
176
+ # @return [Expr]
177
+ def _as_selector
178
+ Utils.wrap_expr(_rbexpr._meta_as_selector)
179
+ end
180
+
181
+ # Add selectors.
182
+ #
183
+ # @return [Expr]
184
+ def _selector_add(other)
185
+ Utils.wrap_expr(_rbexpr._meta_selector_add(other._rbexpr))
186
+ end
187
+
188
+ # Subtract selectors.
189
+ #
190
+ # @return [Expr]
191
+ def _selector_sub(other)
192
+ Utils.wrap_expr(_rbexpr._meta_selector_sub(other._rbexpr))
193
+ end
194
+
195
+ # & selectors.
196
+ #
197
+ # @return [Expr]
198
+ def _selector_and(other)
199
+ Utils.wrap_expr(_rbexpr._meta_selector_and(other._rbexpr))
200
+ end
201
+
202
+ # Format the expression as a tree.
203
+ #
204
+ # @param return_as_string [Boolean]
205
+ # If true, return as string rather than printing to stdout.
206
+ #
207
+ # @return [String]
208
+ #
209
+ # @example
210
+ # e = (Polars.col("foo") * Polars.col("bar")).sum.over(Polars.col("ham")) / 2
211
+ # e.meta.tree_format(return_as_string: true)
212
+ def tree_format(return_as_string: false)
213
+ s = _rbexpr.meta_tree_format
214
+ if return_as_string
215
+ s
216
+ else
217
+ puts s
218
+ nil
219
+ end
220
+ end
221
+ end
222
+ end