yerba 0.9.2-arm-linux-gnu → 0.10.1-arm-linux-gnu

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +53 -17
  3. data/exe/arm-linux-gnu/yerba +0 -0
  4. data/ext/yerba/include/yerba.h +58 -35
  5. data/ext/yerba/yerba.c +281 -187
  6. data/lib/yerba/3.2/yerba.so +0 -0
  7. data/lib/yerba/3.3/yerba.so +0 -0
  8. data/lib/yerba/3.4/yerba.so +0 -0
  9. data/lib/yerba/4.0/yerba.so +0 -0
  10. data/lib/yerba/collection.rb +4 -4
  11. data/lib/yerba/document.rb +134 -0
  12. data/lib/yerba/formatting.rb +1 -0
  13. data/lib/yerba/location.rb +8 -1
  14. data/lib/yerba/map.rb +16 -6
  15. data/lib/yerba/node.rb +41 -0
  16. data/lib/yerba/query_result.rb +33 -10
  17. data/lib/yerba/scalar.rb +29 -0
  18. data/lib/yerba/selector.rb +3 -1
  19. data/lib/yerba/sequence.rb +38 -33
  20. data/lib/yerba/version.rb +1 -1
  21. data/rust/Cargo.lock +1 -1
  22. data/rust/Cargo.toml +1 -1
  23. data/rust/src/commands/get.rs +12 -12
  24. data/rust/src/commands/init.rs +8 -8
  25. data/rust/src/commands/insert.rs +4 -18
  26. data/rust/src/commands/location.rs +2 -0
  27. data/rust/src/commands/mod.rs +34 -6
  28. data/rust/src/commands/move_item.rs +1 -1
  29. data/rust/src/commands/move_key.rs +8 -8
  30. data/rust/src/commands/rename.rs +1 -1
  31. data/rust/src/commands/selectors.rs +1 -1
  32. data/rust/src/commands/set.rs +14 -6
  33. data/rust/src/commands/sort.rs +5 -1
  34. data/rust/src/document/condition.rs +25 -25
  35. data/rust/src/document/delete.rs +57 -43
  36. data/rust/src/document/get.rs +91 -82
  37. data/rust/src/document/insert.rs +77 -77
  38. data/rust/src/document/mod.rs +202 -76
  39. data/rust/src/document/nodes.rs +162 -0
  40. data/rust/src/document/schema.rs +8 -8
  41. data/rust/src/document/set.rs +49 -26
  42. data/rust/src/document/sort.rs +105 -60
  43. data/rust/src/document/style.rs +50 -49
  44. data/rust/src/document/unique.rs +5 -5
  45. data/rust/src/error.rs +8 -4
  46. data/rust/src/ffi.rs +234 -107
  47. data/rust/src/json.rs +62 -2
  48. data/rust/src/lib.rs +4 -2
  49. data/rust/src/main.rs +2 -1
  50. data/rust/src/selector.rs +48 -7
  51. data/rust/src/syntax.rs +449 -56
  52. data/rust/src/validation.rs +5 -3
  53. data/rust/src/yerbafile.rs +168 -94
  54. metadata +3 -2
data/ext/yerba/yerba.c CHANGED
@@ -1,5 +1,6 @@
1
1
  #include <ruby.h>
2
2
  #include <ruby/encoding.h>
3
+ #include <math.h>
3
4
  #include <string.h>
4
5
  #include "include/yerba.h"
5
6
 
@@ -48,9 +49,9 @@ static void check_result(YerbaResult result) {
48
49
  VALUE message = make_utf8_string(result.error);
49
50
  VALUE error_class = rb_eError;
50
51
 
51
- if (strstr(result.error, "invalid path")) {
52
+ if (strstr(result.error, "invalid selector")) {
52
53
  error_class = rb_ePathValidationError;
53
- } else if (strstr(result.error, "path not found") || strstr(result.error, "not a sequence")) {
54
+ } else if (strstr(result.error, "selector not found") || strstr(result.error, "not a sequence")) {
54
55
  error_class = rb_ePathNotFoundError;
55
56
  } else if (strstr(result.error, "parse error")) {
56
57
  error_class = rb_eParseError;
@@ -72,21 +73,23 @@ static VALUE typed_value_to_ruby(YerbaTypedValue typed_value) {
72
73
  break;
73
74
 
74
75
  case YERBA_VALUE_TYPE_BOOLEAN:
75
- result = (strcmp(typed_value.text, "true") == 0 || strcmp(typed_value.text, "True") == 0 ||
76
- strcmp(typed_value.text, "TRUE") == 0 || strcmp(typed_value.text, "yes") == 0 ||
77
- strcmp(typed_value.text, "Yes") == 0 || strcmp(typed_value.text, "YES") == 0 ||
78
- strcmp(typed_value.text, "on") == 0 || strcmp(typed_value.text, "On") == 0 ||
79
- strcmp(typed_value.text, "ON") == 0 || strcmp(typed_value.text, "y") == 0 ||
80
- strcmp(typed_value.text, "Y") == 0)
81
- ? Qtrue : Qfalse;
76
+ result = strcmp(typed_value.text, "true") == 0 ? Qtrue : Qfalse;
82
77
  break;
83
78
 
84
79
  case YERBA_VALUE_TYPE_INTEGER:
85
- result = rb_cstr_to_inum(typed_value.text, 0, 0);
80
+ result = rb_cstr_to_inum(typed_value.text, 10, 0);
86
81
  break;
87
82
 
88
83
  case YERBA_VALUE_TYPE_FLOAT:
89
- result = rb_float_new(rb_cstr_to_dbl(typed_value.text, 0));
84
+ if (strcmp(typed_value.text, ".inf") == 0) {
85
+ result = rb_float_new(HUGE_VAL);
86
+ } else if (strcmp(typed_value.text, "-.inf") == 0) {
87
+ result = rb_float_new(-HUGE_VAL);
88
+ } else if (strcmp(typed_value.text, ".nan") == 0) {
89
+ result = rb_float_new(nan(""));
90
+ } else {
91
+ result = rb_float_new(rb_cstr_to_dbl(typed_value.text, 0));
92
+ }
90
93
  break;
91
94
 
92
95
  case YERBA_VALUE_TYPE_STRING:
@@ -116,12 +119,12 @@ static int should_proceed(struct Document *document, VALUE opts) {
116
119
  VALUE v_condition = rb_hash_aref(opts, ID2SYM(rb_intern("condition")));
117
120
  if (NIL_P(v_condition)) return 1;
118
121
 
119
- VALUE v_path = rb_hash_aref(opts, ID2SYM(rb_intern("condition_path")));
120
- const char *parent_path = NIL_P(v_path) ? "" : StringValueCStr(v_path);
122
+ VALUE v_selector = rb_hash_aref(opts, ID2SYM(rb_intern("condition_path")));
123
+ const char *parent_selector = NIL_P(v_selector) ? "" : StringValueCStr(v_selector);
121
124
 
122
- check_condition(StringValueCStr(v_condition), parent_path[0] != '\0');
125
+ check_condition(StringValueCStr(v_condition), parent_selector[0] != '\0');
123
126
 
124
- return yerba_document_evaluate_condition(document, parent_path, StringValueCStr(v_condition));
127
+ return yerba_document_evaluate_condition(document, parent_selector, StringValueCStr(v_condition));
125
128
  }
126
129
 
127
130
  /* Document.new(path) */
@@ -199,19 +202,21 @@ static VALUE document_s_parse(VALUE klass, VALUE content) {
199
202
  static VALUE location_to_ruby(YerbaLocation location) {
200
203
  VALUE klass = rb_path2class("Yerba::Location");
201
204
 
202
- return rb_funcall(klass, rb_intern("new"), 6,
205
+ return rb_funcall(klass, rb_intern("new"), 8,
203
206
  SIZET2NUM(location.start_line),
204
207
  SIZET2NUM(location.start_column),
205
208
  SIZET2NUM(location.end_line),
206
209
  SIZET2NUM(location.end_column),
207
210
  SIZET2NUM(location.start_offset),
208
- SIZET2NUM(location.end_offset)
211
+ SIZET2NUM(location.end_offset),
212
+ SIZET2NUM(location.start_character_column),
213
+ SIZET2NUM(location.end_character_column)
209
214
  );
210
215
  }
211
216
 
212
217
  /* Build a Yerba::Scalar, Map, Sequence, or nil from a YerbaGetResult.
213
218
  Frees the result internally. */
214
- static VALUE node_from_get_result(YerbaGetResult result, VALUE self, VALUE path) {
219
+ static VALUE node_from_get_result(YerbaGetResult result, VALUE self, VALUE selector) {
215
220
  if (result.error) {
216
221
  VALUE message = make_utf8_string(result.error);
217
222
  yerba_get_result_free(result);
@@ -239,18 +244,18 @@ static VALUE node_from_get_result(YerbaGetResult result, VALUE self, VALUE path)
239
244
  VALUE kwargs = rb_hash_new();
240
245
  rb_hash_aset(kwargs, ID2SYM(rb_intern("value")), value);
241
246
 
242
- return rb_funcallv_kw(rb_path2class("Yerba::Scalar"), rb_intern("from_document"), 5, (VALUE[]){ self, path, location, key, kwargs }, RB_PASS_KEYWORDS);
247
+ return rb_funcallv_kw(rb_path2class("Yerba::Scalar"), rb_intern("from_document"), 5, (VALUE[]){ self, selector, location, key, kwargs }, RB_PASS_KEYWORDS);
243
248
  }
244
249
 
245
250
  case NODE_TYPE_MAP:
246
251
  yerba_get_result_free(result);
247
252
 
248
- return rb_funcall(rb_path2class("Yerba::Map"), rb_intern("from_document"), 4, self, path, location, key);
253
+ return rb_funcall(rb_path2class("Yerba::Map"), rb_intern("from_document"), 4, self, selector, location, key);
249
254
 
250
255
  case NODE_TYPE_SEQUENCE:
251
256
  yerba_get_result_free(result);
252
257
 
253
- return rb_funcall(rb_path2class("Yerba::Sequence"), rb_intern("from_document"), 4, self, path, location, key);
258
+ return rb_funcall(rb_path2class("Yerba::Sequence"), rb_intern("from_document"), 4, self, selector, location, key);
254
259
 
255
260
  default:
256
261
  yerba_get_result_free(result);
@@ -259,20 +264,20 @@ static VALUE node_from_get_result(YerbaGetResult result, VALUE self, VALUE path)
259
264
  }
260
265
  }
261
266
 
262
- /* document[](path) → Yerba::Scalar, Yerba::Map, Yerba::Sequence, Array, or nil */
263
- static VALUE document_bracket(VALUE self, VALUE path) {
267
+ /* document[](selector) → Yerba::Scalar, Yerba::Map, Yerba::Sequence, Array, or nil */
268
+ static VALUE document_bracket(VALUE self, VALUE selector) {
264
269
  struct Document *document = get_document(self);
265
270
  char index_buffer[32];
266
271
 
267
- if (RB_TYPE_P(path, T_FIXNUM)) {
268
- snprintf(index_buffer, sizeof(index_buffer), "[%ld]", FIX2LONG(path));
269
- path = rb_str_new_cstr(index_buffer);
272
+ if (RB_TYPE_P(selector, T_FIXNUM)) {
273
+ snprintf(index_buffer, sizeof(index_buffer), "[%ld]", FIX2LONG(selector));
274
+ selector = rb_str_new_cstr(index_buffer);
270
275
  }
271
276
 
272
- const char *selector = StringValueCStr(path);
277
+ const char *selector_string = StringValueCStr(selector);
273
278
 
274
- if (yerba_selector_has_wildcard(selector)) {
275
- char *json = yerba_document_resolve_selectors(document, selector);
279
+ if (yerba_selector_has_wildcard(selector_string)) {
280
+ char *json = yerba_document_resolve_selectors(document, selector_string);
276
281
 
277
282
  if (!json) return rb_ary_new();
278
283
 
@@ -284,9 +289,9 @@ static VALUE document_bracket(VALUE self, VALUE path) {
284
289
  VALUE array = rb_ary_new_capa(length);
285
290
 
286
291
  for (long i = 0; i < length; i++) {
287
- VALUE concrete_path = rb_ary_entry(resolved, i);
288
- YerbaGetResult result = yerba_document_get(document, StringValueCStr(concrete_path));
289
- VALUE node = node_from_get_result(result, self, concrete_path);
292
+ VALUE concrete_selector = rb_ary_entry(resolved, i);
293
+ YerbaGetResult result = yerba_document_get(document, StringValueCStr(concrete_selector));
294
+ VALUE node = node_from_get_result(result, self, concrete_selector);
290
295
 
291
296
  if (!NIL_P(node)) rb_ary_push(array, node);
292
297
  }
@@ -294,29 +299,44 @@ static VALUE document_bracket(VALUE self, VALUE path) {
294
299
  return array;
295
300
  }
296
301
 
297
- YerbaGetResult result = yerba_document_get(document, selector);
302
+ VALUE concrete_selector = selector;
303
+
304
+ if (strstr(selector_string, "[-") != NULL) {
305
+ char *json = yerba_document_resolve_selectors(document, selector_string);
306
+
307
+ if (json) {
308
+ VALUE json_string = make_utf8_string(json);
309
+ yerba_string_free(json);
310
+
311
+ VALUE resolved = rb_funcall(rb_path2class("JSON"), rb_intern("parse"), 1, json_string);
312
+
313
+ if (RARRAY_LEN(resolved) > 0) concrete_selector = rb_ary_entry(resolved, 0);
314
+ }
315
+ }
316
+
317
+ YerbaGetResult result = yerba_document_get(document, StringValueCStr(selector));
298
318
 
299
- return node_from_get_result(result, self, path);
319
+ return node_from_get_result(result, self, concrete_selector);
300
320
  }
301
321
 
302
- /* document.exists?(path) */
303
- static VALUE document_exists_p(VALUE self, VALUE path) {
322
+ /* document.exists?(selector) */
323
+ static VALUE document_exists_p(VALUE self, VALUE selector) {
304
324
  struct Document *document = get_document(self);
305
325
 
306
- return yerba_document_exists(document, StringValueCStr(path)) ? Qtrue : Qfalse;
326
+ return yerba_document_exists(document, StringValueCStr(selector)) ? Qtrue : Qfalse;
307
327
  }
308
328
 
309
329
  /* document.valid_selector?(selector) → true/false */
310
- static VALUE document_valid_selector_p(VALUE self, VALUE path) {
330
+ static VALUE document_valid_selector_p(VALUE self, VALUE selector) {
311
331
  struct Document *document = get_document(self);
312
332
 
313
- return yerba_document_valid_selector(document, StringValueCStr(path)) ? Qtrue : Qfalse;
333
+ return yerba_document_valid_selector(document, StringValueCStr(selector)) ? Qtrue : Qfalse;
314
334
  }
315
335
 
316
- /* document.source(path) → raw YAML text of the node at path */
317
- static VALUE document_source(VALUE self, VALUE path) {
336
+ /* document.source(selector) → raw YAML text of the node at selector */
337
+ static VALUE document_source(VALUE self, VALUE selector) {
318
338
  struct Document *document = get_document(self);
319
- char *text = yerba_document_source(document, StringValueCStr(path));
339
+ char *text = yerba_document_source(document, StringValueCStr(selector));
320
340
 
321
341
  if (!text) return Qnil;
322
342
 
@@ -326,17 +346,22 @@ static VALUE document_source(VALUE self, VALUE path) {
326
346
  return result;
327
347
  }
328
348
 
329
- /* document.get_value(path) → parsed Ruby object (Hash/Array/String/Integer/etc) */
330
- static VALUE document_get_value(VALUE self, VALUE path) {
349
+ /* document.get_value(selector) → parsed Ruby object (Hash/Array/String/Integer/etc) */
350
+ static VALUE document_get_value(VALUE self, VALUE selector) {
331
351
  struct Document *document = get_document(self);
332
- char *json = yerba_document_get_value(document, StringValueCStr(path));
352
+ char *json = yerba_document_get_value(document, StringValueCStr(selector));
333
353
 
334
354
  if (!json) return Qnil;
335
355
 
336
356
  VALUE json_string = make_utf8_string(json);
337
357
  yerba_string_free(json);
338
358
 
339
- return rb_funcall(rb_path2class("JSON"), rb_intern("parse"), 1, json_string);
359
+ VALUE options = rb_hash_new();
360
+ rb_hash_aset(options, ID2SYM(rb_intern("allow_nan")), Qtrue);
361
+
362
+ VALUE arguments[] = {json_string, options};
363
+
364
+ return rb_funcallv_kw(rb_path2class("JSON"), rb_intern("parse"), 2, arguments, RB_PASS_KEYWORDS);
340
365
  }
341
366
 
342
367
  /* document.values → the whole document as Ruby objects, cached until the document changes */
@@ -356,6 +381,44 @@ static VALUE document_values(VALUE self) {
356
381
  return values;
357
382
  }
358
383
 
384
+ /* document.native_node_records → [[parent, type, selector, key, value, has_value, location, key_location], ...] */
385
+ static VALUE document_node_records(VALUE self) {
386
+ YerbaNodeList list = yerba_document_nodes(get_document(self));
387
+ VALUE records = rb_ary_new_capa((long)list.length);
388
+
389
+ for (size_t i = 0; i < list.length; i++) {
390
+ YerbaNodeRecord record = list.records[i];
391
+ VALUE type;
392
+
393
+ switch (record.node_type) {
394
+ case NODE_TYPE_SCALAR: type = ID2SYM(rb_intern("scalar")); break;
395
+ case NODE_TYPE_MAP: type = ID2SYM(rb_intern("map")); break;
396
+ case NODE_TYPE_SEQUENCE: type = ID2SYM(rb_intern("sequence")); break;
397
+ default: type = Qnil; break;
398
+ }
399
+
400
+ rb_ary_push(records, rb_ary_new_from_args(8,
401
+ LONG2NUM(record.parent),
402
+ type,
403
+ make_utf8_string(record.selector),
404
+ record.key_name ? make_utf8_string(record.key_name) : Qnil,
405
+ typed_value_to_ruby(record.value),
406
+ record.has_value ? Qtrue : Qfalse,
407
+ location_to_ruby(record.location),
408
+ record.key_name ? location_to_ruby(record.key_location) : Qnil
409
+ ));
410
+ }
411
+
412
+ yerba_node_list_free(list);
413
+
414
+ return records;
415
+ }
416
+
417
+ /* document.native_generation → changes whenever the document is edited */
418
+ static VALUE document_generation(VALUE self) {
419
+ return ULL2NUM(yerba_document_generation(get_document(self)));
420
+ }
421
+
359
422
  /* document.selectors → ["database", "database.host", "tags", "tags[]", ...] */
360
423
  static VALUE document_selectors(VALUE self) {
361
424
  struct Document *document = get_document(self);
@@ -370,9 +433,9 @@ static VALUE document_selectors(VALUE self) {
370
433
  }
371
434
 
372
435
  /* document.keys_at(selector) → ["host", "port", ...] */
373
- static VALUE document_keys_at(VALUE self, VALUE path) {
436
+ static VALUE document_keys_at(VALUE self, VALUE selector) {
374
437
  struct Document *document = get_document(self);
375
- char *json = yerba_document_keys(document, StringValueCStr(path));
438
+ char *json = yerba_document_keys(document, StringValueCStr(selector));
376
439
 
377
440
  if (!json) return rb_ary_new();
378
441
 
@@ -383,9 +446,9 @@ static VALUE document_keys_at(VALUE self, VALUE path) {
383
446
  }
384
447
 
385
448
  /* document.locations(selector) → [Yerba::Location, ...] */
386
- static VALUE document_locations(VALUE self, VALUE path) {
449
+ static VALUE document_locations(VALUE self, VALUE selector) {
387
450
  struct Document *document = get_document(self);
388
- char *json = yerba_document_resolve_selectors(document, StringValueCStr(path));
451
+ char *json = yerba_document_resolve_selectors(document, StringValueCStr(selector));
389
452
 
390
453
  if (!json) return rb_ary_new();
391
454
 
@@ -397,8 +460,8 @@ static VALUE document_locations(VALUE self, VALUE path) {
397
460
  VALUE array = rb_ary_new_capa(length);
398
461
 
399
462
  for (long i = 0; i < length; i++) {
400
- VALUE concrete_path = rb_ary_entry(resolved, i);
401
- YerbaGetResult result = yerba_document_get(document, StringValueCStr(concrete_path));
463
+ VALUE concrete_selector = rb_ary_entry(resolved, i);
464
+ YerbaGetResult result = yerba_document_get(document, StringValueCStr(concrete_selector));
402
465
 
403
466
  if (result.error) {
404
467
  yerba_get_result_free(result);
@@ -418,10 +481,10 @@ static VALUE document_locations(VALUE self, VALUE path) {
418
481
  return array;
419
482
  }
420
483
 
421
- /* document.resolve_selectors(path) → ["[0].speakers[0]", "[0].speakers[1]", ...] */
422
- static VALUE document_resolve_selectors(VALUE self, VALUE path) {
484
+ /* document.resolve_selectors(selector) → ["[0].speakers[0]", "[0].speakers[1]", ...] */
485
+ static VALUE document_resolve_selectors(VALUE self, VALUE selector) {
423
486
  struct Document *document = get_document(self);
424
- char *json = yerba_document_resolve_selectors(document, StringValueCStr(path));
487
+ char *json = yerba_document_resolve_selectors(document, StringValueCStr(selector));
425
488
 
426
489
  if (!json) return rb_ary_new();
427
490
 
@@ -456,10 +519,10 @@ static VALUE yerba_s_quote_scalar(int argc, VALUE *argv, VALUE self) {
456
519
  return result;
457
520
  }
458
521
 
459
- /* document.get_quote_style(path) → :plain, :single, :double, :literal, etc. or nil */
460
- static VALUE document_get_quote_style(VALUE self, VALUE path) {
522
+ /* document.get_quote_style(selector) → :plain, :single, :double, :literal, etc. or nil */
523
+ static VALUE document_get_quote_style(VALUE self, VALUE selector) {
461
524
  struct Document *document = get_document(self);
462
- char *style = yerba_document_get_quote_style(document, StringValueCStr(path));
525
+ char *style = yerba_document_get_quote_style(document, StringValueCStr(selector));
463
526
 
464
527
  if (style == NULL) return Qnil;
465
528
 
@@ -470,8 +533,8 @@ static VALUE document_get_quote_style(VALUE self, VALUE path) {
470
533
  return symbol;
471
534
  }
472
535
 
473
- /* document.set_quote_style(path, style) */
474
- static VALUE document_set_quote_style(VALUE self, VALUE path, VALUE style) {
536
+ /* document.set_quote_style(selector, style) */
537
+ static VALUE document_set_quote_style(VALUE self, VALUE selector, VALUE style) {
475
538
  struct Document *document = get_document(self);
476
539
 
477
540
  const char *style_string;
@@ -484,17 +547,17 @@ static VALUE document_set_quote_style(VALUE self, VALUE path, VALUE style) {
484
547
  rb_raise(rb_eError, "Invalid quote style (expected Symbol or String)");
485
548
  }
486
549
 
487
- YerbaResult result = yerba_document_set_quote_style(document, StringValueCStr(path), style_string);
550
+ YerbaResult result = yerba_document_set_quote_style(document, StringValueCStr(selector), style_string);
488
551
 
489
552
  check_result(result);
490
553
 
491
554
  return self;
492
555
  }
493
556
 
494
- /* document.get_collection_style(path) → :flow, :block, or nil */
495
- static VALUE document_get_collection_style(VALUE self, VALUE path) {
557
+ /* document.get_collection_style(selector) → :flow, :block, or nil */
558
+ static VALUE document_get_collection_style(VALUE self, VALUE selector) {
496
559
  struct Document *document = get_document(self);
497
- char *style = yerba_document_get_collection_style(document, StringValueCStr(path));
560
+ char *style = yerba_document_get_collection_style(document, StringValueCStr(selector));
498
561
 
499
562
  if (style == NULL) return Qnil;
500
563
 
@@ -505,8 +568,8 @@ static VALUE document_get_collection_style(VALUE self, VALUE path) {
505
568
  return symbol;
506
569
  }
507
570
 
508
- /* document.set_collection_style(path, style) */
509
- static VALUE document_set_collection_style(VALUE self, VALUE path, VALUE style) {
571
+ /* document.set_collection_style(selector, style) */
572
+ static VALUE document_set_collection_style(VALUE self, VALUE selector, VALUE style) {
510
573
  struct Document *document = get_document(self);
511
574
 
512
575
  const char *style_string;
@@ -519,17 +582,17 @@ static VALUE document_set_collection_style(VALUE self, VALUE path, VALUE style)
519
582
  rb_raise(rb_eError, "Invalid collection style (expected Symbol or String)");
520
583
  }
521
584
 
522
- YerbaResult result = yerba_document_set_collection_style(document, StringValueCStr(path), style_string);
585
+ YerbaResult result = yerba_document_set_collection_style(document, StringValueCStr(selector), style_string);
523
586
 
524
587
  check_result(result);
525
588
 
526
589
  return self;
527
590
  }
528
591
 
529
- /* document.get_sequence_indent(path) → :compact, :indented, or nil */
530
- static VALUE document_get_sequence_indent(VALUE self, VALUE path) {
592
+ /* document.get_sequence_indent(selector) → :compact, :indented, or nil */
593
+ static VALUE document_get_sequence_indent(VALUE self, VALUE selector) {
531
594
  struct Document *document = get_document(self);
532
- char *style = yerba_document_get_sequence_indent(document, StringValueCStr(path));
595
+ char *style = yerba_document_get_sequence_indent(document, StringValueCStr(selector));
533
596
 
534
597
  if (style == NULL) return Qnil;
535
598
 
@@ -540,8 +603,8 @@ static VALUE document_get_sequence_indent(VALUE self, VALUE path) {
540
603
  return symbol;
541
604
  }
542
605
 
543
- /* document.set_sequence_indent(path, style) */
544
- static VALUE document_set_sequence_indent(VALUE self, VALUE path, VALUE style) {
606
+ /* document.set_sequence_indent(selector, style) */
607
+ static VALUE document_set_sequence_indent(VALUE self, VALUE selector, VALUE style) {
545
608
  struct Document *document = get_document(self);
546
609
 
547
610
  const char *style_string;
@@ -554,38 +617,51 @@ static VALUE document_set_sequence_indent(VALUE self, VALUE path, VALUE style) {
554
617
  rb_raise(rb_eError, "Invalid sequence indent style (expected Symbol or String)");
555
618
  }
556
619
 
557
- YerbaResult result = yerba_document_set_sequence_indent(document, StringValueCStr(path), style_string);
620
+ YerbaResult result = yerba_document_set_sequence_indent(document, StringValueCStr(selector), style_string);
558
621
 
559
622
  check_result(result);
560
623
 
561
624
  return self;
562
625
  }
563
626
 
564
- /* document.condition?(condition, path: "") */
627
+ /* TODO(v1.0): stop reading the deprecated path: keyword. */
628
+ static VALUE selector_option(VALUE opts) {
629
+ VALUE selector = rb_hash_aref(opts, ID2SYM(rb_intern("selector")));
630
+
631
+ if (!NIL_P(selector)) return selector;
632
+
633
+ VALUE path = rb_hash_aref(opts, ID2SYM(rb_intern("path")));
634
+
635
+ if (!NIL_P(path)) rb_warn("Yerba: the path: keyword is deprecated, use selector: instead");
636
+
637
+ return path;
638
+ }
639
+
640
+ /* document.condition?(condition, selector: "") */
565
641
  static VALUE document_condition_p(int argc, VALUE *argv, VALUE self) {
566
642
  VALUE condition, opts;
567
643
  rb_scan_args(argc, argv, "1:", &condition, &opts);
568
644
 
569
- const char *parent_path = "";
645
+ const char *parent_selector = "";
570
646
  if (!NIL_P(opts)) {
571
- VALUE v_path = rb_hash_aref(opts, ID2SYM(rb_intern("path")));
647
+ VALUE v_selector = selector_option(opts);
572
648
 
573
- if (!NIL_P(v_path)) {
574
- parent_path = StringValueCStr(v_path);
649
+ if (!NIL_P(v_selector)) {
650
+ parent_selector = StringValueCStr(v_selector);
575
651
  }
576
652
  }
577
653
 
578
654
  struct Document *document = get_document(self);
579
655
 
580
- check_condition(StringValueCStr(condition), parent_path[0] != '\0');
656
+ check_condition(StringValueCStr(condition), parent_selector[0] != '\0');
581
657
 
582
- return yerba_document_evaluate_condition(document, parent_path, StringValueCStr(condition)) ? Qtrue : Qfalse;
658
+ return yerba_document_evaluate_condition(document, parent_selector, StringValueCStr(condition)) ? Qtrue : Qfalse;
583
659
  }
584
660
 
585
- /* document.find(path, condition: nil, select: nil) */
661
+ /* document.find(selector, condition: nil, select: nil) */
586
662
  static VALUE document_find(int argc, VALUE *argv, VALUE self) {
587
- VALUE path, opts;
588
- rb_scan_args(argc, argv, "1:", &path, &opts);
663
+ VALUE selector, opts;
664
+ rb_scan_args(argc, argv, "1:", &selector, &opts);
589
665
 
590
666
  const char *condition = NULL;
591
667
  const char *select = NULL;
@@ -602,7 +678,7 @@ static VALUE document_find(int argc, VALUE *argv, VALUE self) {
602
678
 
603
679
  check_condition(condition, true);
604
680
 
605
- char *json = yerba_document_find(document, StringValueCStr(path), condition, select);
681
+ char *json = yerba_document_find(document, StringValueCStr(selector), condition, select);
606
682
 
607
683
  if (!json) return rb_ary_new();
608
684
 
@@ -655,10 +731,10 @@ static struct TypedValue ruby_to_typed_value(VALUE value, char *number_buffer) {
655
731
  return result;
656
732
  }
657
733
 
658
- /* document.set(path, value, condition: nil, if_exists: false, if_missing: false, plain: false, all: false) */
734
+ /* document.set(selector, value, condition: nil, if_exists: false, if_missing: false, plain: false, all: false) */
659
735
  static VALUE document_set(int argc, VALUE *argv, VALUE self) {
660
- VALUE path, value, opts;
661
- rb_scan_args(argc, argv, "2:", &path, &value, &opts);
736
+ VALUE selector, value, opts;
737
+ rb_scan_args(argc, argv, "2:", &selector, &value, &opts);
662
738
 
663
739
  struct Document *document = get_document(self);
664
740
 
@@ -668,8 +744,19 @@ static VALUE document_set(int argc, VALUE *argv, VALUE self) {
668
744
  VALUE v_if_exists = rb_hash_aref(opts, ID2SYM(rb_intern("if_exists")));
669
745
  VALUE v_if_missing = rb_hash_aref(opts, ID2SYM(rb_intern("if_missing")));
670
746
 
671
- if (RTEST(v_if_exists) && !yerba_document_exists(document, StringValueCStr(path))) return self;
672
- if (RTEST(v_if_missing) && yerba_document_exists(document, StringValueCStr(path))) return self;
747
+ if (RTEST(v_if_exists) && !yerba_document_exists(document, StringValueCStr(selector))) return self;
748
+
749
+ if (RTEST(v_if_missing)) {
750
+ if (yerba_document_exists(document, StringValueCStr(selector))) return self;
751
+
752
+ VALUE insert_opts = rb_hash_new();
753
+ rb_hash_aset(insert_opts, ID2SYM(rb_intern("plain")), rb_hash_aref(opts, ID2SYM(rb_intern("plain"))));
754
+
755
+ VALUE insert_argv[3] = { selector, value, insert_opts };
756
+ rb_funcallv_kw(self, rb_intern("insert"), 3, insert_argv, RB_PASS_KEYWORDS);
757
+
758
+ return self;
759
+ }
673
760
  }
674
761
 
675
762
  char number_buffer[64];
@@ -685,16 +772,16 @@ static VALUE document_set(int argc, VALUE *argv, VALUE self) {
685
772
  if (RTEST(v_plain)) plain = true;
686
773
  }
687
774
 
688
- YerbaResult result = yerba_document_set(document, StringValueCStr(path), typed_value.text, typed_value.length, typed_value.type, plain, all);
775
+ YerbaResult result = yerba_document_set(document, StringValueCStr(selector), typed_value.text, typed_value.length, typed_value.type, plain, all);
689
776
  check_result(result);
690
777
 
691
778
  return self;
692
779
  }
693
780
 
694
- /* document.insert(path, value, before: nil, after: nil, at: nil, plain: false, style: nil) */
781
+ /* document.insert(selector, value, before: nil, after: nil, at: nil, plain: false, style: nil) */
695
782
  static VALUE document_insert(int argc, VALUE *argv, VALUE self) {
696
- VALUE path, value, opts;
697
- rb_scan_args(argc, argv, "2:", &path, &value, &opts);
783
+ VALUE selector, value, opts;
784
+ rb_scan_args(argc, argv, "2:", &selector, &value, &opts);
698
785
 
699
786
  const char *before = NULL;
700
787
  const char *after = NULL;
@@ -725,17 +812,17 @@ static VALUE document_insert(int argc, VALUE *argv, VALUE self) {
725
812
 
726
813
  struct Document *document = get_document(self);
727
814
  YerbaResult result =
728
- yerba_document_insert(document, StringValueCStr(path), typed_value.text, typed_value.length, typed_value.type, plain, style,
815
+ yerba_document_insert(document, StringValueCStr(selector), typed_value.text, typed_value.length, typed_value.type, plain, style,
729
816
  before, after, at);
730
817
  check_result(result);
731
818
 
732
819
  return self;
733
820
  }
734
821
 
735
- /* document.insert_object(path, object, before: nil, after: nil, at: nil) */
822
+ /* document.insert_object(selector, object, before: nil, after: nil, at: nil) */
736
823
  static VALUE document_insert_object(int argc, VALUE *argv, VALUE self) {
737
- VALUE path, object, opts;
738
- rb_scan_args(argc, argv, "2:", &path, &object, &opts);
824
+ VALUE selector, object, opts;
825
+ rb_scan_args(argc, argv, "2:", &selector, &object, &opts);
739
826
 
740
827
  const char *before = NULL;
741
828
  const char *after = NULL;
@@ -754,51 +841,51 @@ static VALUE document_insert_object(int argc, VALUE *argv, VALUE self) {
754
841
  struct Document *document = get_document(self);
755
842
  VALUE json_string = rb_funcall(rb_path2class("JSON"), rb_intern("generate"), 1, object);
756
843
 
757
- YerbaResult result = yerba_document_insert_object(document, StringValueCStr(path), StringValueCStr(json_string), before, after, at);
844
+ YerbaResult result = yerba_document_insert_object(document, StringValueCStr(selector), StringValueCStr(json_string), before, after, at);
758
845
  check_result(result);
759
846
  return self;
760
847
  }
761
848
 
762
- /* document.insert_objects(path, array) */
763
- static VALUE document_insert_objects(VALUE self, VALUE path, VALUE array) {
849
+ /* document.insert_objects(selector, array) */
850
+ static VALUE document_insert_objects(VALUE self, VALUE selector, VALUE array) {
764
851
  struct Document *document = get_document(self);
765
852
  VALUE json_string = rb_funcall(rb_path2class("JSON"), rb_intern("generate"), 1, array);
766
853
 
767
- YerbaResult result = yerba_document_insert_objects(document, StringValueCStr(path), StringValueCStr(json_string));
854
+ YerbaResult result = yerba_document_insert_objects(document, StringValueCStr(selector), StringValueCStr(json_string));
768
855
  check_result(result);
769
856
 
770
857
  return self;
771
858
  }
772
859
 
773
- /* document.delete(path, condition: nil) */
860
+ /* document.delete(selector, condition: nil) */
774
861
  static VALUE document_delete(int argc, VALUE *argv, VALUE self) {
775
- VALUE path, opts;
776
- rb_scan_args(argc, argv, "1:", &path, &opts);
862
+ VALUE selector, opts;
863
+ rb_scan_args(argc, argv, "1:", &selector, &opts);
777
864
 
778
865
  struct Document *document = get_document(self);
779
866
  if (!should_proceed(document, opts)) return self;
780
867
 
781
- YerbaResult result = yerba_document_delete(document, StringValueCStr(path));
868
+ YerbaResult result = yerba_document_delete(document, StringValueCStr(selector));
782
869
 
783
870
  check_result(result);
784
871
 
785
872
  return self;
786
873
  }
787
874
 
788
- /* document.remove(path, value) */
789
- static VALUE document_remove(VALUE self, VALUE path, VALUE value) {
875
+ /* document.remove(selector, value) */
876
+ static VALUE document_remove(VALUE self, VALUE selector, VALUE value) {
790
877
  struct Document *document = get_document(self);
791
- YerbaResult result = yerba_document_remove(document, StringValueCStr(path), StringValueCStr(value));
878
+ YerbaResult result = yerba_document_remove(document, StringValueCStr(selector), StringValueCStr(value));
792
879
 
793
880
  check_result(result);
794
881
 
795
882
  return self;
796
883
  }
797
884
 
798
- /* document.remove_at(path, index) */
799
- static VALUE document_remove_at(VALUE self, VALUE path, VALUE index) {
885
+ /* document.remove_at(selector, index) */
886
+ static VALUE document_remove_at(VALUE self, VALUE selector, VALUE index) {
800
887
  struct Document *document = get_document(self);
801
- YerbaResult result = yerba_document_remove_at(document, StringValueCStr(path), NUM2SIZET(index));
888
+ YerbaResult result = yerba_document_remove_at(document, StringValueCStr(selector), NUM2SIZET(index));
802
889
 
803
890
  check_result(result);
804
891
 
@@ -815,91 +902,97 @@ static VALUE document_rename(VALUE self, VALUE source, VALUE destination) {
815
902
  return self;
816
903
  }
817
904
 
818
- /* document.sort(path = "", by: nil, order: nil, case_sensitive: false) */
905
+ /* document.sort(selector = "", by: nil, order: nil, case_sensitive: false, missing: nil)
906
+ *
907
+ * by: a field, several fields separated by commas or spaces, or an Array of fields
908
+ * order: :asc, :desc, or an explicit order of values (Array or comma-separated String)
909
+ * missing: :first, :last, :keep or :skip, for items without a value for a sort field
910
+ */
819
911
  static VALUE document_sort(int argc, VALUE *argv, VALUE self) {
820
- VALUE path, opts;
821
- rb_scan_args(argc, argv, "01:", &path, &opts);
912
+ VALUE selector, opts;
913
+ rb_scan_args(argc, argv, "01:", &selector, &opts);
822
914
 
823
- if (NIL_P(path)) path = rb_str_new_cstr("");
915
+ if (NIL_P(selector)) selector = rb_str_new_cstr("");
824
916
 
825
- const char *by = NULL;
917
+ VALUE by_value = Qnil;
918
+ VALUE order_csv = Qnil;
919
+ bool descending = false;
826
920
  bool case_sensitive = false;
827
- VALUE v_order = Qnil;
921
+ VALUE missing_value = Qnil;
828
922
 
829
923
  if (!NIL_P(opts)) {
830
924
  VALUE v_by = rb_hash_aref(opts, ID2SYM(rb_intern("by")));
831
- v_order = rb_hash_aref(opts, ID2SYM(rb_intern("order")));
925
+ VALUE v_order = rb_hash_aref(opts, ID2SYM(rb_intern("order")));
832
926
  VALUE v_case_sensitive = rb_hash_aref(opts, ID2SYM(rb_intern("case_sensitive")));
833
927
 
834
- if (SYMBOL_P(v_by)) {
835
- VALUE by_string = rb_sym2str(v_by);
836
- by = StringValueCStr(by_string);
928
+ if (RB_TYPE_P(v_by, T_ARRAY)) {
929
+ by_value = rb_ary_join(v_by, rb_str_new_cstr(","));
930
+ } else if (SYMBOL_P(v_by)) {
931
+ by_value = rb_sym2str(v_by);
837
932
  } else if (!NIL_P(v_by)) {
838
- by = StringValueCStr(v_by);
933
+ by_value = rb_obj_as_string(v_by);
934
+ }
935
+
936
+ if (RB_TYPE_P(v_order, T_ARRAY)) {
937
+ order_csv = rb_ary_join(v_order, rb_str_new_cstr(","));
938
+ } else if (!NIL_P(v_order)) {
939
+ VALUE order_string = SYMBOL_P(v_order) ? rb_sym2str(v_order) : rb_obj_as_string(v_order);
940
+ const char *order = StringValueCStr(order_string);
941
+
942
+ if (strcmp(order, "desc") == 0 || strcmp(order, "descending") == 0) {
943
+ descending = true;
944
+ } else if (strcmp(order, "asc") != 0 && strcmp(order, "ascending") != 0) {
945
+ order_csv = order_string;
946
+ }
839
947
  }
840
948
 
841
949
  if (RTEST(v_case_sensitive)) {
842
950
  case_sensitive = true;
843
951
  }
844
- }
845
-
846
- struct Document *document = get_document(self);
847
- const char *path_string = StringValueCStr(path);
848
-
849
- if (RB_TYPE_P(v_order, T_ARRAY)) {
850
- VALUE order_csv = rb_ary_join(v_order, rb_str_new_cstr(","));
851
- const char *order_string = StringValueCStr(order_csv);
852
- const char *reorder_path = StringValueCStr(path);
853
- const char *reorder_by;
854
952
 
855
- if (by) {
856
- VALUE reorder_by_value = rb_hash_aref(opts, ID2SYM(rb_intern("by")));
953
+ VALUE v_missing = rb_hash_aref(opts, ID2SYM(rb_intern("missing")));
857
954
 
858
- if (SYMBOL_P(reorder_by_value)) {
859
- reorder_by_value = rb_sym2str(reorder_by_value);
860
- }
861
-
862
- reorder_by = StringValueCStr(reorder_by_value);
863
- } else {
864
- reorder_by = ".";
955
+ if (SYMBOL_P(v_missing)) {
956
+ missing_value = rb_sym2str(v_missing);
957
+ } else if (!NIL_P(v_missing)) {
958
+ missing_value = rb_obj_as_string(v_missing);
865
959
  }
960
+ }
866
961
 
867
- YerbaResult result = yerba_document_reorder(document, reorder_path, reorder_by, order_string);
868
- check_result(result);
962
+ struct Document *document = get_document(self);
963
+ const char *path_string = StringValueCStr(selector);
964
+ const char *by = NIL_P(by_value) ? NULL : StringValueCStr(by_value);
965
+ const char *missing = NIL_P(missing_value) ? NULL : StringValueCStr(missing_value);
869
966
 
870
- return self;
871
- }
967
+ if (!NIL_P(order_csv)) {
968
+ YerbaResult result = yerba_document_reorder(document, path_string, by ? by : ".", StringValueCStr(order_csv));
969
+ check_result(result);
872
970
 
873
- const char *order = NULL;
971
+ RB_GC_GUARD(by_value);
972
+ RB_GC_GUARD(order_csv);
874
973
 
875
- if (SYMBOL_P(v_order)) {
876
- VALUE order_string = rb_sym2str(v_order);
877
- order = StringValueCStr(order_string);
878
- } else if (!NIL_P(v_order)) {
879
- order = StringValueCStr(v_order);
974
+ return self;
880
975
  }
881
976
 
882
977
  VALUE by_with_order = Qnil;
883
978
 
884
- if (order && strcmp(order, "desc") == 0) {
885
- if (by) {
886
- by_with_order = rb_sprintf("%s:desc", by);
887
- } else {
888
- by_with_order = rb_str_new_cstr(":desc");
889
- }
890
-
979
+ if (descending) {
980
+ by_with_order = by ? rb_sprintf("%s:desc", by) : rb_str_new_cstr(":desc");
891
981
  by = StringValueCStr(by_with_order);
892
982
  }
893
983
 
894
- YerbaResult result = yerba_document_sort(document, path_string, by, case_sensitive);
895
-
984
+ YerbaResult result = yerba_document_sort(document, path_string, by, case_sensitive, missing);
896
985
  check_result(result);
897
986
 
987
+ RB_GC_GUARD(by_value);
988
+ RB_GC_GUARD(by_with_order);
989
+ RB_GC_GUARD(missing_value);
990
+
898
991
  return self;
899
992
  }
900
993
 
901
- /* document.sort_keys(path, order) */
902
- static VALUE document_sort_keys(VALUE self, VALUE path, VALUE order) {
994
+ /* document.sort_keys(selector, order) */
995
+ static VALUE document_sort_keys(VALUE self, VALUE selector, VALUE order) {
903
996
  struct Document *document = get_document(self);
904
997
 
905
998
  VALUE order_string;
@@ -909,44 +1002,44 @@ static VALUE document_sort_keys(VALUE self, VALUE path, VALUE order) {
909
1002
  order_string = order;
910
1003
  }
911
1004
 
912
- YerbaResult result = yerba_document_sort_keys(document, StringValueCStr(path), StringValueCStr(order_string));
1005
+ YerbaResult result = yerba_document_sort_keys(document, StringValueCStr(selector), StringValueCStr(order_string));
913
1006
 
914
1007
  check_result(result);
915
1008
 
916
1009
  return self;
917
1010
  }
918
1011
 
919
- /* document.quote_style(path: nil, key_style: nil, value_style: nil) */
1012
+ /* document.quote_style(selector: nil, key_style: nil, value_style: nil) */
920
1013
  static VALUE document_quote_style(int argc, VALUE *argv, VALUE self) {
921
1014
  VALUE opts;
922
1015
  rb_scan_args(argc, argv, ":", &opts);
923
1016
 
924
- const char *path = NULL;
1017
+ const char *selector = NULL;
925
1018
  const char *key_style = NULL;
926
1019
  const char *value_style = NULL;
927
1020
 
928
1021
  if (!NIL_P(opts)) {
929
- VALUE v_path = rb_hash_aref(opts, ID2SYM(rb_intern("path")));
1022
+ VALUE v_selector = selector_option(opts);
930
1023
  VALUE v_key_style = rb_hash_aref(opts, ID2SYM(rb_intern("key_style")));
931
1024
  VALUE v_value_style = rb_hash_aref(opts, ID2SYM(rb_intern("value_style")));
932
1025
 
933
- if (!NIL_P(v_path)) path = StringValueCStr(v_path);
1026
+ if (!NIL_P(v_selector)) selector = StringValueCStr(v_selector);
934
1027
  if (!NIL_P(v_key_style)) key_style = StringValueCStr(v_key_style);
935
1028
  if (!NIL_P(v_value_style)) value_style = StringValueCStr(v_value_style);
936
1029
  }
937
1030
 
938
1031
  struct Document *document = get_document(self);
939
- YerbaResult result = yerba_document_quote_style(document, path, key_style, value_style);
1032
+ YerbaResult result = yerba_document_quote_style(document, selector, key_style, value_style);
940
1033
 
941
1034
  check_result(result);
942
1035
 
943
1036
  return self;
944
1037
  }
945
1038
 
946
- /* document.blank_lines(path, count) */
947
- static VALUE document_blank_lines(VALUE self, VALUE path, VALUE count) {
1039
+ /* document.blank_lines(selector, count) */
1040
+ static VALUE document_blank_lines(VALUE self, VALUE selector, VALUE count) {
948
1041
  struct Document *document = get_document(self);
949
- YerbaResult result = yerba_document_blank_lines(document, StringValueCStr(path), NUM2SIZET(count));
1042
+ YerbaResult result = yerba_document_blank_lines(document, StringValueCStr(selector), NUM2SIZET(count));
950
1043
 
951
1044
  check_result(result);
952
1045
 
@@ -1027,20 +1120,20 @@ static VALUE document_changed_p(VALUE self) {
1027
1120
 
1028
1121
  /* document.location(selector = nil) → Yerba::Location */
1029
1122
  static VALUE document_location(int argc, VALUE *argv, VALUE self) {
1030
- VALUE path;
1031
- rb_scan_args(argc, argv, "01", &path);
1123
+ VALUE selector;
1124
+ rb_scan_args(argc, argv, "01", &selector);
1032
1125
 
1033
1126
  struct Document *document = get_document(self);
1034
- const char *selector = NIL_P(path) ? "" : StringValueCStr(path);
1127
+ const char *selector_string = NIL_P(selector) ? "" : StringValueCStr(selector);
1035
1128
 
1036
- YerbaGetResult result = yerba_document_get(document, selector);
1129
+ YerbaGetResult result = yerba_document_get(document, selector_string);
1037
1130
 
1038
1131
  if (result.error) {
1039
1132
  yerba_get_result_free(result);
1040
1133
  return Qnil;
1041
1134
  }
1042
1135
 
1043
- if (result.location.start_line == 0 && result.location.end_line == 0 && strlen(selector) > 0) {
1136
+ if (result.location.start_line == 0 && result.location.end_line == 0 && strlen(selector_string) > 0) {
1044
1137
  yerba_get_result_free(result);
1045
1138
  return Qnil;
1046
1139
  }
@@ -1125,24 +1218,24 @@ static VALUE located_list_to_ruby(YerbaTypedList result, VALUE document) {
1125
1218
  }
1126
1219
 
1127
1220
  /* Collection.get(glob, selector) → [Yerba::Scalar|Map|Sequence, ...] */
1128
- static VALUE collection_s_get(VALUE self, VALUE pattern, VALUE path) {
1221
+ static VALUE collection_s_get(VALUE self, VALUE pattern, VALUE selector) {
1129
1222
  (void) self;
1130
1223
 
1131
- return located_list_to_ruby(yerba_glob_get(StringValueCStr(pattern), StringValueCStr(path)), Qnil);
1224
+ return located_list_to_ruby(yerba_glob_get(StringValueCStr(pattern), StringValueCStr(selector)), Qnil);
1132
1225
  }
1133
1226
 
1134
1227
  /* document.get_all(selector) → [Yerba::Scalar|Map|Sequence, ...] */
1135
- static VALUE document_get_all(VALUE self, VALUE path) {
1228
+ static VALUE document_get_all(VALUE self, VALUE selector) {
1136
1229
  struct Document *document = get_document(self);
1137
1230
 
1138
- return located_list_to_ruby(yerba_document_get_all(document, StringValueCStr(path)), self);
1231
+ return located_list_to_ruby(yerba_document_get_all(document, StringValueCStr(selector)), self);
1139
1232
  }
1140
1233
 
1141
- /* Collection.find(glob, path, condition: nil, select: nil) */
1234
+ /* Collection.find(glob, selector, condition: nil, select: nil) */
1142
1235
  static VALUE collection_s_find(int argc, VALUE *argv, VALUE self) {
1143
1236
  (void)self;
1144
- VALUE pattern, path, opts;
1145
- rb_scan_args(argc, argv, "2:", &pattern, &path, &opts);
1237
+ VALUE pattern, selector, opts;
1238
+ rb_scan_args(argc, argv, "2:", &pattern, &selector, &opts);
1146
1239
 
1147
1240
  const char *condition = NULL;
1148
1241
  const char *select = NULL;
@@ -1157,7 +1250,7 @@ static VALUE collection_s_find(int argc, VALUE *argv, VALUE self) {
1157
1250
 
1158
1251
  check_condition(condition, true);
1159
1252
 
1160
- YerbaTypedList result = yerba_glob_find(StringValueCStr(pattern), StringValueCStr(path), condition, select);
1253
+ YerbaTypedList result = yerba_glob_find(StringValueCStr(pattern), StringValueCStr(selector), condition, select);
1161
1254
 
1162
1255
  if (!result.json) return rb_ary_new();
1163
1256
 
@@ -1231,10 +1324,11 @@ void Init_yerba(void) {
1231
1324
  rb_define_method(rb_cDocument, "initialize", document_initialize, -1);
1232
1325
  rb_define_method(rb_cDocument, "replace_content!", document_replace_content, 1);
1233
1326
  rb_define_singleton_method(rb_cDocument, "parse", document_s_parse, 1);
1234
- rb_define_method(rb_cDocument, "[]", document_bracket, 1);
1235
- rb_define_method(rb_cDocument, "node_at", document_bracket, 1);
1236
- rb_define_method(rb_cDocument, "value_at", document_get_value, 1);
1327
+ rb_define_private_method(rb_cDocument, "native_node_at", document_bracket, 1);
1328
+ rb_define_private_method(rb_cDocument, "native_value_at", document_get_value, 1);
1237
1329
  rb_define_method(rb_cDocument, "values", document_values, 0);
1330
+ rb_define_private_method(rb_cDocument, "native_node_records", document_node_records, 0);
1331
+ rb_define_private_method(rb_cDocument, "native_generation", document_generation, 0);
1238
1332
  rb_define_method(rb_cDocument, "get_all", document_get_all, 1);
1239
1333
  rb_define_method(rb_cDocument, "location", document_location, -1);
1240
1334
  rb_define_method(rb_cDocument, "locations", document_locations, 1);