Ruby 2.7.7p221 (2022-11-24 revision 168ec2b1e5ad0e4688e963d9de019557c78feed9)
hash.c
Go to the documentation of this file.
1/**********************************************************************
2
3 hash.c -
4
5 $Author$
6 created at: Mon Nov 22 18:51:18 JST 1993
7
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
9 Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
10 Copyright (C) 2000 Information-technology Promotion Agency, Japan
11
12**********************************************************************/
13
14#include "ruby/encoding.h"
15#include "ruby/st.h"
16#include "ruby/util.h"
17#include "internal.h"
18#include <errno.h>
19#include "probes.h"
20#include "id.h"
21#include "symbol.h"
22#include "debug_counter.h"
23#include "transient_heap.h"
24#include "ruby_assert.h"
25#ifdef __APPLE__
26# ifdef HAVE_CRT_EXTERNS_H
27# include <crt_externs.h>
28# else
29# include "missing/crt_externs.h"
30# endif
31#endif
32
33#ifndef HASH_DEBUG
34#define HASH_DEBUG 0
35#endif
36
37#if HASH_DEBUG
38#include "gc.h"
39#endif
40
41#define HAS_EXTRA_STATES(hash, klass) ( \
42 ((klass = has_extra_methods(rb_obj_class(hash))) != 0) || \
43 FL_TEST((hash), FL_EXIVAR|RHASH_PROC_DEFAULT) || \
44 !NIL_P(RHASH_IFNONE(hash)))
45
46#define SET_DEFAULT(hash, ifnone) ( \
47 FL_UNSET_RAW(hash, RHASH_PROC_DEFAULT), \
48 RHASH_SET_IFNONE(hash, ifnone))
49
50#define SET_PROC_DEFAULT(hash, proc) set_proc_default(hash, proc)
51
52#define COPY_DEFAULT(hash, hash2) copy_default(RHASH(hash), RHASH(hash2))
53
54static inline void
55copy_default(struct RHash *hash, const struct RHash *hash2)
56{
57 hash->basic.flags &= ~RHASH_PROC_DEFAULT;
58 hash->basic.flags |= hash2->basic.flags & RHASH_PROC_DEFAULT;
59 RHASH_SET_IFNONE(hash, RHASH_IFNONE(hash2));
60}
61
62static VALUE
63has_extra_methods(VALUE klass)
64{
65 const VALUE base = rb_cHash;
66 VALUE c = klass;
67 while (c != base) {
68 if (rb_class_has_methods(c)) return klass;
69 c = RCLASS_SUPER(c);
70 }
71 return 0;
72}
73
74static VALUE rb_hash_s_try_convert(VALUE, VALUE);
75
76/*
77 * Hash WB strategy:
78 * 1. Check mutate st_* functions
79 * * st_insert()
80 * * st_insert2()
81 * * st_update()
82 * * st_add_direct()
83 * 2. Insert WBs
84 */
85
88{
89 return rb_obj_freeze(hash);
90}
91
93
94static VALUE envtbl;
95static ID id_hash, id_yield, id_default, id_flatten_bang;
96static ID id_hash_iter_lev;
97
100{
101 RB_OBJ_WRITE(hash, (&RHASH(hash)->ifnone), ifnone);
102 return hash;
103}
104
105static int
106rb_any_cmp(VALUE a, VALUE b)
107{
108 if (a == b) return 0;
109 if (RB_TYPE_P(a, T_STRING) && RBASIC(a)->klass == rb_cString &&
110 RB_TYPE_P(b, T_STRING) && RBASIC(b)->klass == rb_cString) {
111 return rb_str_hash_cmp(a, b);
112 }
113 if (a == Qundef || b == Qundef) return -1;
114 if (SYMBOL_P(a) && SYMBOL_P(b)) {
115 return a != b;
116 }
117
118 return !rb_eql(a, b);
119}
120
121static VALUE
122hash_recursive(VALUE obj, VALUE arg, int recurse)
123{
124 if (recurse) return INT2FIX(0);
125 return rb_funcallv(obj, id_hash, 0, 0);
126}
127
128VALUE
130{
131 VALUE hval = rb_exec_recursive_outer(hash_recursive, obj, 0);
132
133 while (!FIXNUM_P(hval)) {
134 if (RB_TYPE_P(hval, T_BIGNUM)) {
135 int sign;
136 unsigned long ul;
137 sign = rb_integer_pack(hval, &ul, 1, sizeof(ul), 0,
139 ul &= (1UL << (sizeof(long)*CHAR_BIT-1)) - 1;
140 if (sign < 0)
141 return LONG2FIX(-(long)ul);
142 return LONG2FIX((long)ul);
143 }
144 hval = rb_to_int(hval);
145 }
146 return hval;
147}
148
149static long rb_objid_hash(st_index_t index);
150
151static st_index_t
152dbl_to_index(double d)
153{
154 union {double d; st_index_t i;} u;
155 u.d = d;
156 return u.i;
157}
158
159long
161{
162 /* normalize -0.0 to 0.0 */
163 if (d == 0.0) d = 0.0;
164#if SIZEOF_INT == SIZEOF_VOIDP
165 return rb_memhash(&d, sizeof(d));
166#else
167 return rb_objid_hash(dbl_to_index(d));
168#endif
169}
170
171static inline long
172any_hash(VALUE a, st_index_t (*other_func)(VALUE))
173{
174 VALUE hval;
175 st_index_t hnum;
176
177 if (SPECIAL_CONST_P(a)) {
178 if (STATIC_SYM_P(a)) {
179 hnum = a >> (RUBY_SPECIAL_SHIFT + ID_SCOPE_SHIFT);
180 hnum = rb_hash_start(hnum);
181 goto out;
182 }
183 else if (FLONUM_P(a)) {
184 /* prevent pathological behavior: [Bug #10761] */
185 goto flt;
186 }
187 hnum = rb_objid_hash((st_index_t)a);
188 }
189 else if (BUILTIN_TYPE(a) == T_STRING) {
190 hnum = rb_str_hash(a);
191 }
192 else if (BUILTIN_TYPE(a) == T_SYMBOL) {
193 hnum = RSYMBOL(a)->hashval;
194 }
195 else if (BUILTIN_TYPE(a) == T_BIGNUM) {
196 hval = rb_big_hash(a);
197 hnum = FIX2LONG(hval);
198 }
199 else if (BUILTIN_TYPE(a) == T_FLOAT) {
200 flt:
202 }
203 else {
204 hnum = other_func(a);
205 }
206 out:
207#if SIZEOF_LONG < SIZEOF_ST_INDEX_T
208 if (hnum > 0)
209 hnum &= (unsigned long)-1 >> 2;
210 else
211 hnum |= ~((unsigned long)-1 >> 2);
212#else
213 hnum <<= 1;
214 hnum = RSHIFT(hnum, 1);
215#endif
216 return (long)hnum;
217}
218
219static st_index_t
220obj_any_hash(VALUE obj)
221{
222 obj = rb_hash(obj);
223 return FIX2LONG(obj);
224}
225
226static st_index_t
227rb_any_hash(VALUE a)
228{
229 return any_hash(a, obj_any_hash);
230}
231
232/* Here is a hash function for 64-bit key. It is about 5 times faster
233 (2 times faster when uint128 type is absent) on Haswell than
234 tailored Spooky or City hash function can be. */
235
236/* Here we two primes with random bit generation. */
237static const uint64_t prime1 = ((uint64_t)0x2e0bb864 << 32) | 0xe9ea7df5;
238static const uint32_t prime2 = 0x830fcab9;
239
240
241static inline uint64_t
242mult_and_mix(uint64_t m1, uint64_t m2)
243{
244#if defined HAVE_UINT128_T
245 uint128_t r = (uint128_t) m1 * (uint128_t) m2;
246 return (uint64_t) (r >> 64) ^ (uint64_t) r;
247#else
248 uint64_t hm1 = m1 >> 32, hm2 = m2 >> 32;
249 uint64_t lm1 = m1, lm2 = m2;
250 uint64_t v64_128 = hm1 * hm2;
251 uint64_t v32_96 = hm1 * lm2 + lm1 * hm2;
252 uint64_t v1_32 = lm1 * lm2;
253
254 return (v64_128 + (v32_96 >> 32)) ^ ((v32_96 << 32) + v1_32);
255#endif
256}
257
258static inline uint64_t
259key64_hash(uint64_t key, uint32_t seed)
260{
261 return mult_and_mix(key + seed, prime1);
262}
263
264/* Should cast down the result for each purpose */
265#define st_index_hash(index) key64_hash(rb_hash_start(index), prime2)
266
267static long
268rb_objid_hash(st_index_t index)
269{
270 return (long)st_index_hash(index);
271}
272
273static st_index_t
274objid_hash(VALUE obj)
275{
277 if (!FIXNUM_P(object_id))
279
280#if SIZEOF_LONG == SIZEOF_VOIDP
282#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
284#endif
285}
286
290VALUE
292{
293 long hnum = any_hash(obj, objid_hash);
294 return ST2FIX(hnum);
295}
296
297static const struct st_hash_type objhash = {
298 rb_any_cmp,
299 rb_any_hash,
300};
301
302#define rb_ident_cmp st_numcmp
303
304static st_index_t
305rb_ident_hash(st_data_t n)
306{
307#ifdef USE_FLONUM /* RUBY */
308 /*
309 * - flonum (on 64-bit) is pathologically bad, mix the actual
310 * float value in, but do not use the float value as-is since
311 * many integers get interpreted as 2.0 or -2.0 [Bug #10761]
312 */
313 if (FLONUM_P(n)) {
314 n ^= dbl_to_index(rb_float_value(n));
315 }
316#endif
317
319}
320
321#define identhash rb_hashtype_ident
324 rb_ident_hash,
325};
326
328
329/*
330 * RHASH_AR_TABLE_P(h):
331 * * as.ar == NULL or
332 * as.ar points ar_table.
333 * * as.ar is allocated by transient heap or xmalloc.
334 *
335 * !RHASH_AR_TABLE_P(h):
336 * * as.st points st_table.
337 */
338
339#define RHASH_AR_TABLE_MAX_BOUND RHASH_AR_TABLE_MAX_SIZE
340
341#define RHASH_AR_TABLE_REF(hash, n) (&RHASH_AR_TABLE(hash)->pairs[n])
342#define RHASH_AR_CLEARED_HINT 0xff
343
344typedef struct ar_table_pair_struct {
348
349typedef struct ar_table_struct {
350 /* 64bit CPU: 8B * 2 * 8 = 128B */
353
354size_t
356{
357 return sizeof(ar_table);
358}
359
360static inline st_hash_t
361ar_do_hash(st_data_t key)
362{
363 return (st_hash_t)rb_any_hash(key);
364}
365
366static inline ar_hint_t
367ar_do_hash_hint(st_hash_t hash_value)
368{
369 return (ar_hint_t)hash_value;
370}
371
372static inline ar_hint_t
373ar_hint(VALUE hash, unsigned int index)
374{
375 return RHASH(hash)->ar_hint.ary[index];
376}
377
378static inline void
379ar_hint_set_hint(VALUE hash, unsigned int index, ar_hint_t hint)
380{
381 RHASH(hash)->ar_hint.ary[index] = hint;
382}
383
384static inline void
385ar_hint_set(VALUE hash, unsigned int index, st_hash_t hash_value)
386{
387 ar_hint_set_hint(hash, index, ar_do_hash_hint(hash_value));
388}
389
390static inline void
391ar_clear_entry(VALUE hash, unsigned int index)
392{
394 pair->key = Qundef;
395 ar_hint_set_hint(hash, index, RHASH_AR_CLEARED_HINT);
396}
397
398static inline int
399ar_cleared_entry(VALUE hash, unsigned int index)
400{
401 if (ar_hint(hash, index) == RHASH_AR_CLEARED_HINT) {
402 /* RHASH_AR_CLEARED_HINT is only a hint, not mean cleared entry,
403 * so you need to check key == Qundef
404 */
406 return pair->key == Qundef;
407 }
408 else {
409 return FALSE;
410 }
411}
412
413static inline void
414ar_set_entry(VALUE hash, unsigned int index, st_data_t key, st_data_t val, st_hash_t hash_value)
415{
417 pair->key = key;
418 pair->val = val;
419 ar_hint_set(hash, index, hash_value);
420}
421
422#define RHASH_AR_TABLE_SIZE(h) (HASH_ASSERT(RHASH_AR_TABLE_P(h)), \
423 RHASH_AR_TABLE_SIZE_RAW(h))
424
425#define RHASH_AR_TABLE_BOUND_RAW(h) \
426 ((unsigned int)((RBASIC(h)->flags >> RHASH_AR_TABLE_BOUND_SHIFT) & \
427 (RHASH_AR_TABLE_BOUND_MASK >> RHASH_AR_TABLE_BOUND_SHIFT)))
428
429#define RHASH_AR_TABLE_BOUND(h) (HASH_ASSERT(RHASH_AR_TABLE_P(h)), \
430 RHASH_AR_TABLE_BOUND_RAW(h))
431
432#define RHASH_ST_TABLE_SET(h, s) rb_hash_st_table_set(h, s)
433#define RHASH_TYPE(hash) (RHASH_AR_TABLE_P(hash) ? &objhash : RHASH_ST_TABLE(hash)->type)
434
435#define HASH_ASSERT(expr) RUBY_ASSERT_MESG_WHEN(HASH_DEBUG, expr, #expr)
436
437#if HASH_DEBUG
438#define hash_verify(hash) hash_verify_(hash, __FILE__, __LINE__)
439
440void
441rb_hash_dump(VALUE hash)
442{
443 rb_obj_info_dump(hash);
444
445 if (RHASH_AR_TABLE_P(hash)) {
446 unsigned i, n = 0, bound = RHASH_AR_TABLE_BOUND(hash);
447
448 fprintf(stderr, " size:%u bound:%u\n",
450
451 for (i=0; i<bound; i++) {
452 st_data_t k, v;
453
454 if (!ar_cleared_entry(hash, i)) {
455 char b1[0x100], b2[0x100];
456 ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
457 k = pair->key;
458 v = pair->val;
459 fprintf(stderr, " %d key:%s val:%s hint:%02x\n", i,
460 rb_raw_obj_info(b1, 0x100, k),
461 rb_raw_obj_info(b2, 0x100, v),
462 ar_hint(hash, i));
463 n++;
464 }
465 else {
466 fprintf(stderr, " %d empty\n", i);
467 }
468 }
469 }
470}
471
472static VALUE
473hash_verify_(VALUE hash, const char *file, int line)
474{
476
477 if (RHASH_AR_TABLE_P(hash)) {
478 unsigned i, n = 0, bound = RHASH_AR_TABLE_BOUND(hash);
479
480 for (i=0; i<bound; i++) {
481 st_data_t k, v;
482 if (!ar_cleared_entry(hash, i)) {
483 ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
484 k = pair->key;
485 v = pair->val;
486 HASH_ASSERT(k != Qundef);
487 HASH_ASSERT(v != Qundef);
488 n++;
489 }
490 }
491 if (n != RHASH_AR_TABLE_SIZE(hash)) {
492 rb_bug("n:%u, RHASH_AR_TABLE_SIZE:%u", n, RHASH_AR_TABLE_SIZE(hash));
493 }
494 }
495 else {
499 }
500
501 if (RHASH_TRANSIENT_P(hash)) {
502 volatile st_data_t MAYBE_UNUSED(key) = RHASH_AR_TABLE_REF(hash, 0)->key; /* read */
505 }
506 return hash;
507}
508
509#else
510#define hash_verify(h) ((void)0)
511#endif
512
513static inline int
514RHASH_TABLE_NULL_P(VALUE hash)
515{
516 if (RHASH(hash)->as.ar == NULL) {
518 return TRUE;
519 }
520 else {
521 return FALSE;
522 }
523}
524
525static inline int
526RHASH_TABLE_EMPTY_P(VALUE hash)
527{
528 return RHASH_SIZE(hash) == 0;
529}
530
531int
533{
534 if (FL_TEST_RAW((hash), RHASH_ST_TABLE_FLAG)) {
535 HASH_ASSERT(RHASH(hash)->as.st != NULL);
536 return FALSE;
537 }
538 else {
539 return TRUE;
540 }
541}
542
543ar_table *
545{
547 return RHASH(hash)->as.ar;
548}
549
550st_table *
552{
554 return RHASH(hash)->as.st;
555}
556
557void
559{
560 HASH_ASSERT(st != NULL);
562 RHASH(hash)->as.st = st;
563}
564
565static void
566hash_ar_table_set(VALUE hash, ar_table *ar)
567{
569 HASH_ASSERT((RHASH_TRANSIENT_P(hash) && ar == NULL) ? FALSE : TRUE);
570 RHASH(hash)->as.ar = ar;
571 hash_verify(hash);
572}
573
574#define RHASH_SET_ST_FLAG(h) FL_SET_RAW(h, RHASH_ST_TABLE_FLAG)
575#define RHASH_UNSET_ST_FLAG(h) FL_UNSET_RAW(h, RHASH_ST_TABLE_FLAG)
576
577static inline void
578RHASH_AR_TABLE_BOUND_SET(VALUE h, st_index_t n)
579{
582
583 RBASIC(h)->flags &= ~RHASH_AR_TABLE_BOUND_MASK;
584 RBASIC(h)->flags |= n << RHASH_AR_TABLE_BOUND_SHIFT;
585}
586
587static inline void
588RHASH_AR_TABLE_SIZE_SET(VALUE h, st_index_t n)
589{
592
593 RBASIC(h)->flags &= ~RHASH_AR_TABLE_SIZE_MASK;
594 RBASIC(h)->flags |= n << RHASH_AR_TABLE_SIZE_SHIFT;
595}
596
597static inline void
598HASH_AR_TABLE_SIZE_ADD(VALUE h, st_index_t n)
599{
601
602 RHASH_AR_TABLE_SIZE_SET(h, RHASH_AR_TABLE_SIZE(h) + n);
603
604 hash_verify(h);
605}
606
607#define RHASH_AR_TABLE_SIZE_INC(h) HASH_AR_TABLE_SIZE_ADD(h, 1)
608
609static inline void
610RHASH_AR_TABLE_SIZE_DEC(VALUE h)
611{
613 int new_size = RHASH_AR_TABLE_SIZE(h) - 1;
614
615 if (new_size != 0) {
616 RHASH_AR_TABLE_SIZE_SET(h, new_size);
617 }
618 else {
619 RHASH_AR_TABLE_SIZE_SET(h, 0);
620 RHASH_AR_TABLE_BOUND_SET(h, 0);
621 }
622 hash_verify(h);
623}
624
625static inline void
626RHASH_AR_TABLE_CLEAR(VALUE h)
627{
628 RBASIC(h)->flags &= ~RHASH_AR_TABLE_SIZE_MASK;
629 RBASIC(h)->flags &= ~RHASH_AR_TABLE_BOUND_MASK;
630
631 hash_ar_table_set(h, NULL);
632}
633
634static ar_table*
635ar_alloc_table(VALUE hash)
636{
637 ar_table *tab = (ar_table*)rb_transient_heap_alloc(hash, sizeof(ar_table));
638
639 if (tab != NULL) {
641 }
642 else {
644 tab = (ar_table*)ruby_xmalloc(sizeof(ar_table));
645 }
646
647 RHASH_AR_TABLE_SIZE_SET(hash, 0);
648 RHASH_AR_TABLE_BOUND_SET(hash, 0);
649 hash_ar_table_set(hash, tab);
650
651 return tab;
652}
653
654NOINLINE(static int ar_equal(VALUE x, VALUE y));
655
656static int
657ar_equal(VALUE x, VALUE y)
658{
659 return rb_any_cmp(x, y) == 0;
660}
661
662static unsigned
663ar_find_entry_hint(VALUE hash, ar_hint_t hint, st_data_t key)
664{
665 unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
666 const ar_hint_t *hints = RHASH(hash)->ar_hint.ary;
667
668 /* if table is NULL, then bound also should be 0 */
669
670 for (i = 0; i < bound; i++) {
671 if (hints[i] == hint) {
672 ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
673 if (ar_equal(key, pair->key)) {
674 RB_DEBUG_COUNTER_INC(artable_hint_hit);
675 return i;
676 }
677 else {
678#if 0
679 static int pid;
680 static char fname[256];
681 static FILE *fp;
682
683 if (pid != getpid()) {
684 snprintf(fname, sizeof(fname), "/tmp/ruby-armiss.%d", pid = getpid());
685 if ((fp = fopen(fname, "w")) == NULL) rb_bug("fopen");
686 }
687
688 st_hash_t h1 = ar_do_hash(key);
689 st_hash_t h2 = ar_do_hash(pair->key);
690
691 fprintf(fp, "miss: hash_eq:%d hints[%d]:%02x hint:%02x\n"
692 " key :%016lx %s\n"
693 " pair->key:%016lx %s\n",
694 h1 == h2, i, hints[i], hint,
695 h1, rb_obj_info(key), h2, rb_obj_info(pair->key));
696#endif
697 RB_DEBUG_COUNTER_INC(artable_hint_miss);
698 }
699 }
700 }
701 RB_DEBUG_COUNTER_INC(artable_hint_notfound);
703}
704
705static unsigned
706ar_find_entry(VALUE hash, st_hash_t hash_value, st_data_t key)
707{
708 ar_hint_t hint = ar_do_hash_hint(hash_value);
709 return ar_find_entry_hint(hash, hint, key);
710}
711
712static inline void
713ar_free_and_clear_table(VALUE hash)
714{
715 ar_table *tab = RHASH_AR_TABLE(hash);
716
717 if (tab) {
718 if (RHASH_TRANSIENT_P(hash)) {
720 }
721 else {
723 }
724 RHASH_AR_TABLE_CLEAR(hash);
725 }
728 HASH_ASSERT(RHASH_TRANSIENT_P(hash) == 0);
729}
730
731static void
732ar_try_convert_table(VALUE hash)
733{
734 if (!RHASH_AR_TABLE_P(hash)) return;
735
736 const unsigned size = RHASH_AR_TABLE_SIZE(hash);
737
738 st_table *new_tab;
740
742 return;
743 }
744
745 new_tab = st_init_table_with_size(&objhash, size * 2);
746
747 for (i = 0; i < RHASH_AR_TABLE_MAX_BOUND; i++) {
748 ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
749 st_add_direct(new_tab, pair->key, pair->val);
750 }
751 ar_free_and_clear_table(hash);
752 RHASH_ST_TABLE_SET(hash, new_tab);
753 return;
754}
755
756static st_table *
757ar_force_convert_table(VALUE hash, const char *file, int line)
758{
759 st_table *new_tab;
760
761 if (RHASH_ST_TABLE_P(hash)) {
762 return RHASH_ST_TABLE(hash);
763 }
764
765 if (RHASH_AR_TABLE(hash)) {
766 unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
767
768#if RHASH_CONVERT_TABLE_DEBUG
769 rb_obj_info_dump(hash);
770 fprintf(stderr, "force_convert: %s:%d\n", file, line);
771 RB_DEBUG_COUNTER_INC(obj_hash_force_convert);
772#endif
773
774 new_tab = st_init_table_with_size(&objhash, RHASH_AR_TABLE_SIZE(hash));
775
776 for (i = 0; i < bound; i++) {
777 if (ar_cleared_entry(hash, i)) continue;
778
779 ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
780 st_add_direct(new_tab, pair->key, pair->val);
781 }
782 ar_free_and_clear_table(hash);
783 }
784 else {
785 new_tab = st_init_table(&objhash);
786 }
787 RHASH_ST_TABLE_SET(hash, new_tab);
788
789 return new_tab;
790}
791
792static ar_table *
793hash_ar_table(VALUE hash)
794{
795 if (RHASH_TABLE_NULL_P(hash)) {
796 ar_alloc_table(hash);
797 }
798 return RHASH_AR_TABLE(hash);
799}
800
801static int
802ar_compact_table(VALUE hash)
803{
804 const unsigned bound = RHASH_AR_TABLE_BOUND(hash);
805 const unsigned size = RHASH_AR_TABLE_SIZE(hash);
806
807 if (size == bound) {
808 return size;
809 }
810 else {
811 unsigned i, j=0;
812 ar_table_pair *pairs = RHASH_AR_TABLE(hash)->pairs;
813
814 for (i=0; i<bound; i++) {
815 if (ar_cleared_entry(hash, i)) {
816 if (j <= i) j = i+1;
817 for (; j<bound; j++) {
818 if (!ar_cleared_entry(hash, j)) {
819 pairs[i] = pairs[j];
820 ar_hint_set_hint(hash, i, (st_hash_t)ar_hint(hash, j));
821 ar_clear_entry(hash, j);
822 j++;
823 goto found;
824 }
825 }
826 /* non-empty is not found */
827 goto done;
828 found:;
829 }
830 }
831 done:
832 HASH_ASSERT(i<=bound);
833
834 RHASH_AR_TABLE_BOUND_SET(hash, size);
835 hash_verify(hash);
836 return size;
837 }
838}
839
840static int
841ar_add_direct_with_hash(VALUE hash, st_data_t key, st_data_t val, st_hash_t hash_value)
842{
843 unsigned bin = RHASH_AR_TABLE_BOUND(hash);
844
846 return 1;
847 }
848 else {
850 bin = ar_compact_table(hash);
851 hash_ar_table(hash);
852 }
854
855 ar_set_entry(hash, bin, key, val, hash_value);
856 RHASH_AR_TABLE_BOUND_SET(hash, bin+1);
858 return 0;
859 }
860}
861
862static int
863ar_general_foreach(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
864{
865 if (RHASH_AR_TABLE_SIZE(hash) > 0) {
866 unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
867
868 for (i = 0; i < bound; i++) {
869 if (ar_cleared_entry(hash, i)) continue;
870
871 ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
872 enum st_retval retval = (*func)(pair->key, pair->val, arg, 0);
873 /* pair may be not valid here because of theap */
874
875 switch (retval) {
876 case ST_CONTINUE:
877 break;
878 case ST_CHECK:
879 case ST_STOP:
880 return 0;
881 case ST_REPLACE:
882 if (replace) {
883 VALUE key = pair->key;
884 VALUE val = pair->val;
885 retval = (*replace)(&key, &val, arg, TRUE);
886
887 // TODO: pair should be same as pair before.
888 ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
889 pair->key = key;
890 pair->val = val;
891 }
892 break;
893 case ST_DELETE:
894 ar_clear_entry(hash, i);
895 RHASH_AR_TABLE_SIZE_DEC(hash);
896 break;
897 }
898 }
899 }
900 return 0;
901}
902
903static int
904ar_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
905{
906 return ar_general_foreach(hash, func, replace, arg);
907}
908
909struct functor {
912};
913
914static int
915apply_functor(st_data_t k, st_data_t v, st_data_t d, int _)
916{
917 const struct functor *f = (void *)d;
918 return f->func(k, v, f->arg);
919}
920
921static int
923{
924 const struct functor f = { func, arg };
925 return ar_general_foreach(hash, apply_functor, NULL, (st_data_t)&f);
926}
927
928static int
929ar_foreach_check(VALUE hash, st_foreach_check_callback_func *func, st_data_t arg,
930 st_data_t never)
931{
932 if (RHASH_AR_TABLE_SIZE(hash) > 0) {
933 unsigned i, ret = 0, bound = RHASH_AR_TABLE_BOUND(hash);
934 enum st_retval retval;
936 ar_table_pair *pair;
937 ar_hint_t hint;
938
939 for (i = 0; i < bound; i++) {
940 if (ar_cleared_entry(hash, i)) continue;
941
942 pair = RHASH_AR_TABLE_REF(hash, i);
943 key = pair->key;
944 hint = ar_hint(hash, i);
945
946 retval = (*func)(key, pair->val, arg, 0);
947 hash_verify(hash);
948
949 switch (retval) {
950 case ST_CHECK: {
951 pair = RHASH_AR_TABLE_REF(hash, i);
952 if (pair->key == never) break;
953 ret = ar_find_entry_hint(hash, hint, key);
954 if (ret == RHASH_AR_TABLE_MAX_BOUND) {
955 retval = (*func)(0, 0, arg, 1);
956 return 2;
957 }
958 }
959 case ST_CONTINUE:
960 break;
961 case ST_STOP:
962 case ST_REPLACE:
963 return 0;
964 case ST_DELETE: {
965 if (!ar_cleared_entry(hash, i)) {
966 ar_clear_entry(hash, i);
967 RHASH_AR_TABLE_SIZE_DEC(hash);
968 }
969 break;
970 }
971 }
972 }
973 }
974 return 0;
975}
976
977static int
978ar_update(VALUE hash, st_data_t key,
980{
981 int retval, existing;
982 unsigned bin = RHASH_AR_TABLE_MAX_BOUND;
983 st_data_t value = 0, old_key;
984 st_hash_t hash_value = ar_do_hash(key);
985
986 if (UNLIKELY(!RHASH_AR_TABLE_P(hash))) {
987 // `#hash` changes ar_table -> st_table
988 return -1;
989 }
990
991 if (RHASH_AR_TABLE_SIZE(hash) > 0) {
992 bin = ar_find_entry(hash, hash_value, key);
993 existing = (bin != RHASH_AR_TABLE_MAX_BOUND) ? TRUE : FALSE;
994 }
995 else {
996 hash_ar_table(hash); /* allocate ltbl if needed */
997 existing = FALSE;
998 }
999
1000 if (existing) {
1001 ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, bin);
1002 key = pair->key;
1003 value = pair->val;
1004 }
1005 old_key = key;
1006 retval = (*func)(&key, &value, arg, existing);
1007 /* pair can be invalid here because of theap */
1008
1009 switch (retval) {
1010 case ST_CONTINUE:
1011 if (!existing) {
1012 if (ar_add_direct_with_hash(hash, key, value, hash_value)) {
1013 return -1;
1014 }
1015 }
1016 else {
1017 ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, bin);
1018 if (old_key != key) {
1019 pair->key = key;
1020 }
1021 pair->val = value;
1022 }
1023 break;
1024 case ST_DELETE:
1025 if (existing) {
1026 ar_clear_entry(hash, bin);
1027 RHASH_AR_TABLE_SIZE_DEC(hash);
1028 }
1029 break;
1030 }
1031 return existing;
1032}
1033
1034static int
1035ar_insert(VALUE hash, st_data_t key, st_data_t value)
1036{
1037 unsigned bin = RHASH_AR_TABLE_BOUND(hash);
1038 st_hash_t hash_value = ar_do_hash(key);
1039
1040 if (UNLIKELY(!RHASH_AR_TABLE_P(hash))) {
1041 // `#hash` changes ar_table -> st_table
1042 return -1;
1043 }
1044
1045 hash_ar_table(hash); /* prepare ltbl */
1046
1047 bin = ar_find_entry(hash, hash_value, key);
1050 return -1;
1051 }
1052 else if (bin >= RHASH_AR_TABLE_MAX_BOUND) {
1053 bin = ar_compact_table(hash);
1054 hash_ar_table(hash);
1055 }
1057
1058 ar_set_entry(hash, bin, key, value, hash_value);
1059 RHASH_AR_TABLE_BOUND_SET(hash, bin+1);
1061 return 0;
1062 }
1063 else {
1064 RHASH_AR_TABLE_REF(hash, bin)->val = value;
1065 return 1;
1066 }
1067}
1068
1069static int
1070ar_lookup(VALUE hash, st_data_t key, st_data_t *value)
1071{
1072 if (RHASH_AR_TABLE_SIZE(hash) == 0) {
1073 return 0;
1074 }
1075 else {
1076 st_hash_t hash_value = ar_do_hash(key);
1077 if (UNLIKELY(!RHASH_AR_TABLE_P(hash))) {
1078 // `#hash` changes ar_table -> st_table
1079 return st_lookup(RHASH_ST_TABLE(hash), key, value);
1080 }
1081 unsigned bin = ar_find_entry(hash, hash_value, key);
1082
1084 return 0;
1085 }
1086 else {
1088 if (value != NULL) {
1089 *value = RHASH_AR_TABLE_REF(hash, bin)->val;
1090 }
1091 return 1;
1092 }
1093 }
1094}
1095
1096static int
1097ar_delete(VALUE hash, st_data_t *key, st_data_t *value)
1098{
1099 unsigned bin;
1100 st_hash_t hash_value = ar_do_hash(*key);
1101
1102 if (UNLIKELY(!RHASH_AR_TABLE_P(hash))) {
1103 // `#hash` changes ar_table -> st_table
1104 return st_delete(RHASH_ST_TABLE(hash), key, value);
1105 }
1106
1107 bin = ar_find_entry(hash, hash_value, *key);
1108
1110 if (value != 0) *value = 0;
1111 return 0;
1112 }
1113 else {
1114 if (value != 0) {
1115 ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, bin);
1116 *value = pair->val;
1117 }
1118 ar_clear_entry(hash, bin);
1119 RHASH_AR_TABLE_SIZE_DEC(hash);
1120 return 1;
1121 }
1122}
1123
1124static int
1125ar_shift(VALUE hash, st_data_t *key, st_data_t *value)
1126{
1127 if (RHASH_AR_TABLE_SIZE(hash) > 0) {
1128 unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
1129
1130 for (i = 0; i < bound; i++) {
1131 if (!ar_cleared_entry(hash, i)) {
1132 ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
1133 if (value != 0) *value = pair->val;
1134 *key = pair->key;
1135 ar_clear_entry(hash, i);
1136 RHASH_AR_TABLE_SIZE_DEC(hash);
1137 return 1;
1138 }
1139 }
1140 }
1141 if (value != NULL) *value = 0;
1142 return 0;
1143}
1144
1145static long
1146ar_keys(VALUE hash, st_data_t *keys, st_index_t size)
1147{
1148 unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
1149 st_data_t *keys_start = keys, *keys_end = keys + size;
1150
1151 for (i = 0; i < bound; i++) {
1152 if (keys == keys_end) {
1153 break;
1154 }
1155 else {
1156 if (!ar_cleared_entry(hash, i)) {
1157 *keys++ = RHASH_AR_TABLE_REF(hash, i)->key;
1158 }
1159 }
1160 }
1161
1162 return keys - keys_start;
1163}
1164
1165static long
1166ar_values(VALUE hash, st_data_t *values, st_index_t size)
1167{
1168 unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
1169 st_data_t *values_start = values, *values_end = values + size;
1170
1171 for (i = 0; i < bound; i++) {
1172 if (values == values_end) {
1173 break;
1174 }
1175 else {
1176 if (!ar_cleared_entry(hash, i)) {
1177 *values++ = RHASH_AR_TABLE_REF(hash, i)->val;
1178 }
1179 }
1180 }
1181
1182 return values - values_start;
1183}
1184
1185static ar_table*
1186ar_copy(VALUE hash1, VALUE hash2)
1187{
1188 ar_table *old_tab = RHASH_AR_TABLE(hash2);
1189
1190 if (old_tab != NULL) {
1191 ar_table *new_tab = RHASH_AR_TABLE(hash1);
1192 if (new_tab == NULL) {
1193 new_tab = (ar_table*) rb_transient_heap_alloc(hash1, sizeof(ar_table));
1194 if (new_tab != NULL) {
1196 }
1197 else {
1199 new_tab = (ar_table*)ruby_xmalloc(sizeof(ar_table));
1200 }
1201 }
1202 *new_tab = *old_tab;
1203 RHASH(hash1)->ar_hint.word = RHASH(hash2)->ar_hint.word;
1204 RHASH_AR_TABLE_BOUND_SET(hash1, RHASH_AR_TABLE_BOUND(hash2));
1205 RHASH_AR_TABLE_SIZE_SET(hash1, RHASH_AR_TABLE_SIZE(hash2));
1206 hash_ar_table_set(hash1, new_tab);
1207
1209 return new_tab;
1210 }
1211 else {
1212 RHASH_AR_TABLE_BOUND_SET(hash1, RHASH_AR_TABLE_BOUND(hash2));
1213 RHASH_AR_TABLE_SIZE_SET(hash1, RHASH_AR_TABLE_SIZE(hash2));
1214
1215 if (RHASH_TRANSIENT_P(hash1)) {
1217 }
1218 else if (RHASH_AR_TABLE(hash1)) {
1219 ruby_xfree(RHASH_AR_TABLE(hash1));
1220 }
1221
1222 hash_ar_table_set(hash1, NULL);
1223
1225 return old_tab;
1226 }
1227}
1228
1229static void
1230ar_clear(VALUE hash)
1231{
1232 if (RHASH_AR_TABLE(hash) != NULL) {
1233 RHASH_AR_TABLE_SIZE_SET(hash, 0);
1234 RHASH_AR_TABLE_BOUND_SET(hash, 0);
1235 }
1236 else {
1237 HASH_ASSERT(RHASH_AR_TABLE_SIZE(hash) == 0);
1239 }
1240}
1241
1242#if USE_TRANSIENT_HEAP
1243void
1245{
1246 if (RHASH_TRANSIENT_P(hash)) {
1247 ar_table *new_tab;
1248 ar_table *old_tab = RHASH_AR_TABLE(hash);
1249
1250 if (UNLIKELY(old_tab == NULL)) {
1251 rb_gc_force_recycle(hash);
1252 return;
1253 }
1254 HASH_ASSERT(old_tab != NULL);
1255 if (promote) {
1256 promote:
1257 new_tab = ruby_xmalloc(sizeof(ar_table));
1259 }
1260 else {
1261 new_tab = rb_transient_heap_alloc(hash, sizeof(ar_table));
1262 if (new_tab == NULL) goto promote;
1263 }
1264 *new_tab = *old_tab;
1265 hash_ar_table_set(hash, new_tab);
1266 }
1267 hash_verify(hash);
1268}
1269#endif
1270
1272
1277};
1278
1279static int
1280foreach_safe_i(st_data_t key, st_data_t value, st_data_t args, int error)
1281{
1282 int status;
1283 struct foreach_safe_arg *arg = (void *)args;
1284
1285 if (error) return ST_STOP;
1286 status = (*arg->func)(key, value, arg->arg);
1287 if (status == ST_CONTINUE) {
1288 return ST_CHECK;
1289 }
1290 return status;
1291}
1292
1293void
1295{
1296 struct foreach_safe_arg arg;
1297
1298 arg.tbl = table;
1299 arg.func = (st_foreach_func *)func;
1300 arg.arg = a;
1301 if (st_foreach_check(table, foreach_safe_i, (st_data_t)&arg, 0)) {
1302 rb_raise(rb_eRuntimeError, "hash modified during iteration");
1303 }
1304}
1305
1307
1308struct hash_foreach_arg {
1312};
1313
1314static int
1315hash_ar_foreach_iter(st_data_t key, st_data_t value, st_data_t argp, int error)
1316{
1317 struct hash_foreach_arg *arg = (struct hash_foreach_arg *)argp;
1318 int status;
1319
1320 if (error) return ST_STOP;
1321 status = (*arg->func)((VALUE)key, (VALUE)value, arg->arg);
1322 /* TODO: rehash check? rb_raise(rb_eRuntimeError, "rehash occurred during iteration"); */
1323
1324 switch (status) {
1325 case ST_DELETE:
1326 return ST_DELETE;
1327 case ST_CONTINUE:
1328 break;
1329 case ST_STOP:
1330 return ST_STOP;
1331 }
1332 return ST_CHECK;
1333}
1334
1335static int
1336hash_foreach_iter(st_data_t key, st_data_t value, st_data_t argp, int error)
1337{
1338 struct hash_foreach_arg *arg = (struct hash_foreach_arg *)argp;
1339 int status;
1340 st_table *tbl;
1341
1342 if (error) return ST_STOP;
1343 tbl = RHASH_ST_TABLE(arg->hash);
1344 status = (*arg->func)((VALUE)key, (VALUE)value, arg->arg);
1345 if (RHASH_ST_TABLE(arg->hash) != tbl) {
1346 rb_raise(rb_eRuntimeError, "rehash occurred during iteration");
1347 }
1348 switch (status) {
1349 case ST_DELETE:
1350 return ST_DELETE;
1351 case ST_CONTINUE:
1352 break;
1353 case ST_STOP:
1354 return ST_STOP;
1355 }
1356 return ST_CHECK;
1357}
1358
1359static int
1360iter_lev_in_ivar(VALUE hash)
1361{
1362 VALUE levval = rb_ivar_get(hash, id_hash_iter_lev);
1363 HASH_ASSERT(FIXNUM_P(levval));
1364 return FIX2INT(levval);
1365}
1366
1367void rb_ivar_set_internal(VALUE obj, ID id, VALUE val);
1368
1369static void
1370iter_lev_in_ivar_set(VALUE hash, int lev)
1371{
1372 rb_ivar_set_internal(hash, id_hash_iter_lev, INT2FIX(lev));
1373}
1374
1375static int
1376iter_lev_in_flags(VALUE hash)
1377{
1378 unsigned int u = (unsigned int)((RBASIC(hash)->flags >> RHASH_LEV_SHIFT) & RHASH_LEV_MAX);
1379 return (int)u;
1380}
1381
1382static int
1384{
1385 int lev = iter_lev_in_flags(hash);
1386
1387 if (lev == RHASH_LEV_MAX) {
1388 return iter_lev_in_ivar(hash);
1389 }
1390 else {
1391 return lev;
1392 }
1393}
1394
1395static void
1396hash_iter_lev_inc(VALUE hash)
1397{
1398 int lev = iter_lev_in_flags(hash);
1399 if (lev == RHASH_LEV_MAX) {
1400 lev = iter_lev_in_ivar(hash);
1401 iter_lev_in_ivar_set(hash, lev+1);
1402 }
1403 else {
1404 lev += 1;
1405 RBASIC(hash)->flags = ((RBASIC(hash)->flags & ~RHASH_LEV_MASK) | (lev << RHASH_LEV_SHIFT));
1406 if (lev == RHASH_LEV_MAX) {
1407 iter_lev_in_ivar_set(hash, lev);
1408 }
1409 }
1410}
1411
1412static void
1413hash_iter_lev_dec(VALUE hash)
1414{
1415 int lev = iter_lev_in_flags(hash);
1416 if (lev == RHASH_LEV_MAX) {
1417 lev = iter_lev_in_ivar(hash);
1418 HASH_ASSERT(lev > 0);
1419 iter_lev_in_ivar_set(hash, lev-1);
1420 }
1421 else {
1422 HASH_ASSERT(lev > 0);
1423 RBASIC(hash)->flags = ((RBASIC(hash)->flags & ~RHASH_LEV_MASK) | ((lev-1) << RHASH_LEV_SHIFT));
1424 }
1425}
1426
1427static VALUE
1428hash_foreach_ensure_rollback(VALUE hash)
1429{
1430 hash_iter_lev_inc(hash);
1431 return 0;
1432}
1433
1434static VALUE
1435hash_foreach_ensure(VALUE hash)
1436{
1437 hash_iter_lev_dec(hash);
1438 return 0;
1439}
1440
1441int
1443{
1444 if (RHASH_AR_TABLE_P(hash)) {
1445 return ar_foreach(hash, func, arg);
1446 }
1447 else {
1449 }
1450}
1451
1452int
1454{
1455 if (RHASH_AR_TABLE_P(hash)) {
1456 return ar_foreach_with_replace(hash, func, replace, arg);
1457 }
1458 else {
1460 }
1461}
1462
1463static VALUE
1464hash_foreach_call(VALUE arg)
1465{
1466 VALUE hash = ((struct hash_foreach_arg *)arg)->hash;
1467 int ret = 0;
1468 if (RHASH_AR_TABLE_P(hash)) {
1469 ret = ar_foreach_check(hash, hash_ar_foreach_iter,
1471 }
1472 else if (RHASH_ST_TABLE_P(hash)) {
1473 ret = st_foreach_check(RHASH_ST_TABLE(hash), hash_foreach_iter,
1475 }
1476 if (ret) {
1477 rb_raise(rb_eRuntimeError, "ret: %d, hash modified during iteration", ret);
1478 }
1479 return Qnil;
1480}
1481
1482void
1484{
1485 struct hash_foreach_arg arg;
1486
1487 if (RHASH_TABLE_EMPTY_P(hash))
1488 return;
1489 hash_iter_lev_inc(hash);
1490 arg.hash = hash;
1491 arg.func = (rb_foreach_func *)func;
1492 arg.arg = farg;
1493 rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash);
1495}
1496
1497static VALUE
1498hash_alloc_flags(VALUE klass, VALUE flags, VALUE ifnone)
1499{
1501 NEWOBJ_OF(hash, struct RHash, klass, T_HASH | wb | flags);
1502
1503 RHASH_SET_IFNONE((VALUE)hash, ifnone);
1504
1505 return (VALUE)hash;
1506}
1507
1508static VALUE
1509hash_alloc(VALUE klass)
1510{
1511 return hash_alloc_flags(klass, 0, Qnil);
1512}
1513
1514static VALUE
1515empty_hash_alloc(VALUE klass)
1516{
1517 RUBY_DTRACE_CREATE_HOOK(HASH, 0);
1518
1519 return hash_alloc(klass);
1520}
1521
1522VALUE
1524{
1525 return hash_alloc(rb_cHash);
1526}
1527
1530{
1531 VALUE ret = rb_hash_new();
1532 if (size == 0) {
1533 /* do nothing */
1534 }
1535 else if (size <= RHASH_AR_TABLE_MAX_SIZE) {
1536 ar_alloc_table(ret);
1537 }
1538 else {
1540 }
1541 return ret;
1542}
1543
1544static VALUE
1545hash_copy(VALUE ret, VALUE hash)
1546{
1547 if (!RHASH_EMPTY_P(hash)) {
1549 ar_copy(ret, hash);
1550 else if (RHASH_ST_TABLE_P(hash))
1552 }
1553 return ret;
1554}
1555
1556static VALUE
1557hash_dup(VALUE hash, VALUE klass, VALUE flags)
1558{
1559 return hash_copy(hash_alloc_flags(klass, flags, RHASH_IFNONE(hash)),
1560 hash);
1561}
1562
1563VALUE
1565{
1566 const VALUE flags = RBASIC(hash)->flags;
1567 VALUE ret = hash_dup(hash, rb_obj_class(hash),
1568 flags & (FL_EXIVAR|RHASH_PROC_DEFAULT));
1569 if (flags & FL_EXIVAR)
1571 return ret;
1572}
1573
1576{
1577 VALUE ret = hash_dup(hash, rb_cHash, 0);
1578 return ret;
1579}
1580
1581static void
1582rb_hash_modify_check(VALUE hash)
1583{
1585}
1586
1588#if RHASH_CONVERT_TABLE_DEBUG
1589rb_hash_tbl_raw(VALUE hash, const char *file, int line)
1590{
1591 return ar_force_convert_table(hash, file, line);
1592}
1593#else
1595{
1596 return ar_force_convert_table(hash, NULL, 0);
1597}
1598#endif
1599
1600struct st_table *
1601rb_hash_tbl(VALUE hash, const char *file, int line)
1602{
1603 OBJ_WB_UNPROTECT(hash);
1604 return RHASH_TBL_RAW(hash);
1605}
1606
1607static void
1608rb_hash_modify(VALUE hash)
1609{
1610 rb_hash_modify_check(hash);
1611}
1612
1613NORETURN(static void no_new_key(void));
1614static void
1615no_new_key(void)
1616{
1617 rb_raise(rb_eRuntimeError, "can't add a new key into hash during iteration");
1618}
1619
1623};
1624
1625#define NOINSERT_UPDATE_CALLBACK(func) \
1626static int \
1627func##_noinsert(st_data_t *key, st_data_t *val, st_data_t arg, int existing) \
1628{ \
1629 if (!existing) no_new_key(); \
1630 return func(key, val, (struct update_arg *)arg, existing); \
1631} \
1632 \
1633static int \
1634func##_insert(st_data_t *key, st_data_t *val, st_data_t arg, int existing) \
1635{ \
1636 return func(key, val, (struct update_arg *)arg, existing); \
1637}
1638
1646};
1647
1649
1650int
1652{
1653 if (RHASH_AR_TABLE_P(hash)) {
1654 int result = ar_update(hash, (st_data_t)key, func, arg);
1655 if (result == -1) {
1656 ar_try_convert_table(hash);
1657 }
1658 else {
1659 return result;
1660 }
1661 }
1662
1663 return st_update(RHASH_ST_TABLE(hash), (st_data_t)key, func, arg);
1664}
1665
1666static int
1667tbl_update(VALUE hash, VALUE key, tbl_update_func func, st_data_t optional_arg)
1668{
1669 struct update_arg arg;
1670 int result;
1671
1672 arg.arg = optional_arg;
1673 arg.hash = hash;
1674 arg.new_key = 0;
1675 arg.old_key = Qundef;
1676 arg.new_value = 0;
1677 arg.old_value = Qundef;
1678
1679 result = rb_hash_stlike_update(hash, key, func, (st_data_t)&arg);
1680
1681 /* write barrier */
1682 if (arg.new_key) RB_OBJ_WRITTEN(hash, arg.old_key, arg.new_key);
1683 if (arg.new_value) RB_OBJ_WRITTEN(hash, arg.old_value, arg.new_value);
1684
1685 return result;
1686}
1687
1688#define UPDATE_CALLBACK(iter_lev, func) ((iter_lev) > 0 ? func##_noinsert : func##_insert)
1689
1690#define RHASH_UPDATE_ITER(h, iter_lev, key, func, a) do { \
1691 tbl_update((h), (key), UPDATE_CALLBACK((iter_lev), func), (st_data_t)(a)); \
1692} while (0)
1693
1694#define RHASH_UPDATE(hash, key, func, arg) \
1695 RHASH_UPDATE_ITER(hash, RHASH_ITER_LEV(hash), key, func, arg)
1696
1697static void
1698set_proc_default(VALUE hash, VALUE proc)
1699{
1700 if (rb_proc_lambda_p(proc)) {
1701 int n = rb_proc_arity(proc);
1702
1703 if (n != 2 && (n >= 0 || n < -3)) {
1704 if (n < 0) n = -n-1;
1705 rb_raise(rb_eTypeError, "default_proc takes two arguments (2 for %d)", n);
1706 }
1707 }
1708
1710 RHASH_SET_IFNONE(hash, proc);
1711}
1712
1713/*
1714 * call-seq:
1715 * Hash.new -> new_hash
1716 * Hash.new(obj) -> new_hash
1717 * Hash.new {|hash, key| block } -> new_hash
1718 *
1719 * Returns a new, empty hash. If this hash is subsequently accessed by
1720 * a key that doesn't correspond to a hash entry, the value returned
1721 * depends on the style of <code>new</code> used to create the hash. In
1722 * the first form, the access returns <code>nil</code>. If
1723 * <i>obj</i> is specified, this single object will be used for
1724 * all <em>default values</em>. If a block is specified, it will be
1725 * called with the hash object and the key, and should return the
1726 * default value. It is the block's responsibility to store the value
1727 * in the hash if required.
1728 *
1729 * h = Hash.new("Go Fish")
1730 * h["a"] = 100
1731 * h["b"] = 200
1732 * h["a"] #=> 100
1733 * h["c"] #=> "Go Fish"
1734 * # The following alters the single default object
1735 * h["c"].upcase! #=> "GO FISH"
1736 * h["d"] #=> "GO FISH"
1737 * h.keys #=> ["a", "b"]
1738 *
1739 * # While this creates a new default object each time
1740 * h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }
1741 * h["c"] #=> "Go Fish: c"
1742 * h["c"].upcase! #=> "GO FISH: C"
1743 * h["d"] #=> "Go Fish: d"
1744 * h.keys #=> ["c", "d"]
1745 *
1746 */
1747
1748static VALUE
1749rb_hash_initialize(int argc, VALUE *argv, VALUE hash)
1750{
1751 VALUE ifnone;
1752
1753 rb_hash_modify(hash);
1754 if (rb_block_given_p()) {
1755 rb_check_arity(argc, 0, 0);
1756 ifnone = rb_block_proc();
1757 SET_PROC_DEFAULT(hash, ifnone);
1758 }
1759 else {
1760 rb_check_arity(argc, 0, 1);
1761 ifnone = argc == 0 ? Qnil : argv[0];
1762 RHASH_SET_IFNONE(hash, ifnone);
1763 }
1764
1765 return hash;
1766}
1767
1768/*
1769 * call-seq:
1770 * Hash[ key, value, ... ] -> new_hash
1771 * Hash[ [ [key, value], ... ] ] -> new_hash
1772 * Hash[ object ] -> new_hash
1773 *
1774 * Creates a new hash populated with the given objects.
1775 *
1776 * Similar to the literal <code>{ _key_ => _value_, ... }</code>. In the first
1777 * form, keys and values occur in pairs, so there must be an even number of
1778 * arguments.
1779 *
1780 * The second and third form take a single argument which is either an array
1781 * of key-value pairs or an object convertible to a hash.
1782 *
1783 * Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200}
1784 * Hash[ [ ["a", 100], ["b", 200] ] ] #=> {"a"=>100, "b"=>200}
1785 * Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200}
1786 */
1787
1788static VALUE
1789rb_hash_s_create(int argc, VALUE *argv, VALUE klass)
1790{
1791 VALUE hash, tmp;
1792
1793 if (argc == 1) {
1794 tmp = rb_hash_s_try_convert(Qnil, argv[0]);
1795 if (!NIL_P(tmp)) {
1796 hash = hash_alloc(klass);
1797 if (RHASH_AR_TABLE_P(tmp)) {
1798 ar_copy(hash, tmp);
1799 }
1800 else {
1802 }
1803 return hash;
1804 }
1805
1806 tmp = rb_check_array_type(argv[0]);
1807 if (!NIL_P(tmp)) {
1808 long i;
1809
1810 hash = hash_alloc(klass);
1811 for (i = 0; i < RARRAY_LEN(tmp); ++i) {
1812 VALUE e = RARRAY_AREF(tmp, i);
1814 VALUE key, val = Qnil;
1815
1816 if (NIL_P(v)) {
1817 rb_raise(rb_eArgError, "wrong element type %s at %ld (expected array)",
1819 }
1820 switch (RARRAY_LEN(v)) {
1821 default:
1822 rb_raise(rb_eArgError, "invalid number of elements (%ld for 1..2)",
1823 RARRAY_LEN(v));
1824 case 2:
1825 val = RARRAY_AREF(v, 1);
1826 case 1:
1827 key = RARRAY_AREF(v, 0);
1828 rb_hash_aset(hash, key, val);
1829 }
1830 }
1831 return hash;
1832 }
1833 }
1834 if (argc % 2 != 0) {
1835 rb_raise(rb_eArgError, "odd number of arguments for Hash");
1836 }
1837
1838 hash = hash_alloc(klass);
1841 return hash;
1842}
1843
1844VALUE
1846{
1847 return rb_convert_type_with_id(hash, T_HASH, "Hash", idTo_hash);
1848}
1849#define to_hash rb_to_hash_type
1850
1851VALUE
1853{
1855}
1856
1857/*
1858 * call-seq:
1859 * Hash.try_convert(obj) -> hash or nil
1860 *
1861 * Try to convert <i>obj</i> into a hash, using to_hash method.
1862 * Returns converted hash or nil if <i>obj</i> cannot be converted
1863 * for any reason.
1864 *
1865 * Hash.try_convert({1=>2}) # => {1=>2}
1866 * Hash.try_convert("1=>2") # => nil
1867 */
1868static VALUE
1869rb_hash_s_try_convert(VALUE dummy, VALUE hash)
1870{
1871 return rb_check_hash_type(hash);
1872}
1873
1874/*
1875 * call-seq:
1876 * Hash.ruby2_keywords_hash?(hash) -> true or false
1877 *
1878 * Checks if a given hash is flagged by Module#ruby2_keywords (or
1879 * Proc#ruby2_keywords).
1880 * This method is not for casual use; debugging, researching, and
1881 * some truly necessary cases like serialization of arguments.
1882 *
1883 * ruby2_keywords def foo(*args)
1884 * Hash.ruby2_keywords_hash?(args.last)
1885 * end
1886 * foo(k: 1) #=> true
1887 * foo({k: 1}) #=> false
1888 */
1889static VALUE
1890rb_hash_s_ruby2_keywords_hash_p(VALUE dummy, VALUE hash)
1891{
1893 return (RHASH(hash)->basic.flags & RHASH_PASS_AS_KEYWORDS) ? Qtrue : Qfalse;
1894}
1895
1896/*
1897 * call-seq:
1898 * Hash.ruby2_keywords_hash(hash) -> hash
1899 *
1900 * Duplicates a given hash and adds a ruby2_keywords flag.
1901 * This method is not for casual use; debugging, researching, and
1902 * some truly necessary cases like deserialization of arguments.
1903 *
1904 * h = {k: 1}
1905 * h = Hash.ruby2_keywords_hash(h)
1906 * def foo(k: 42)
1907 * k
1908 * end
1909 * foo(*[h]) #=> 1 with neither a warning or an error
1910 */
1911static VALUE
1912rb_hash_s_ruby2_keywords_hash(VALUE dummy, VALUE hash)
1913{
1916 RHASH(hash)->basic.flags |= RHASH_PASS_AS_KEYWORDS;
1917 return hash;
1918}
1919
1923};
1924
1925static int
1926rb_hash_rehash_i(VALUE key, VALUE value, VALUE arg)
1927{
1928 if (RHASH_AR_TABLE_P(arg)) {
1929 ar_insert(arg, (st_data_t)key, (st_data_t)value);
1930 }
1931 else {
1933 }
1934 return ST_CONTINUE;
1935}
1936
1937/*
1938 * call-seq:
1939 * hsh.rehash -> hsh
1940 *
1941 * Rebuilds the hash based on the current hash values for each key. If
1942 * values of key objects have changed since they were inserted, this
1943 * method will reindex <i>hsh</i>. If Hash#rehash is
1944 * called while an iterator is traversing the hash, a
1945 * RuntimeError will be raised in the iterator.
1946 *
1947 * a = [ "a", "b" ]
1948 * c = [ "c", "d" ]
1949 * h = { a => 100, c => 300 }
1950 * h[a] #=> 100
1951 * a[0] = "z"
1952 * h[a] #=> nil
1953 * h.rehash #=> {["z", "b"]=>100, ["c", "d"]=>300}
1954 * h[a] #=> 100
1955 */
1956
1957VALUE
1959{
1960 VALUE tmp;
1961 st_table *tbl;
1962
1963 if (RHASH_ITER_LEV(hash) > 0) {
1964 rb_raise(rb_eRuntimeError, "rehash during iteration");
1965 }
1966 rb_hash_modify_check(hash);
1967 if (RHASH_AR_TABLE_P(hash)) {
1968 tmp = hash_alloc(0);
1969 ar_alloc_table(tmp);
1970 rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
1971 ar_free_and_clear_table(hash);
1972 ar_copy(hash, tmp);
1973 ar_free_and_clear_table(tmp);
1974 }
1975 else if (RHASH_ST_TABLE_P(hash)) {
1976 st_table *old_tab = RHASH_ST_TABLE(hash);
1977 tmp = hash_alloc(0);
1978 tbl = st_init_table_with_size(old_tab->type, old_tab->num_entries);
1979 RHASH_ST_TABLE_SET(tmp, tbl);
1980 rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
1981 st_free_table(old_tab);
1982 RHASH_ST_TABLE_SET(hash, tbl);
1983 RHASH_ST_CLEAR(tmp);
1984 }
1985 hash_verify(hash);
1986 return hash;
1987}
1988
1989VALUE
1991{
1992 if (rb_method_basic_definition_p(CLASS_OF(hash), id_default)) {
1993 VALUE ifnone = RHASH_IFNONE(hash);
1994 if (!FL_TEST(hash, RHASH_PROC_DEFAULT)) return ifnone;
1995 if (key == Qundef) return Qnil;
1996 return rb_funcall(ifnone, id_yield, 2, hash, key);
1997 }
1998 else {
1999 return rb_funcall(hash, id_default, 1, key);
2000 }
2001}
2002
2003static inline int
2004hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval)
2005{
2006 hash_verify(hash);
2007
2008 if (RHASH_AR_TABLE_P(hash)) {
2009 return ar_lookup(hash, key, pval);
2010 }
2011 else {
2012 return st_lookup(RHASH_ST_TABLE(hash), key, pval);
2013 }
2014}
2015
2018{
2019 return hash_stlike_lookup(hash, key, pval);
2020}
2021
2022/*
2023 * call-seq:
2024 * hsh[key] -> value
2025 *
2026 * Element Reference---Retrieves the <i>value</i> object corresponding
2027 * to the <i>key</i> object. If not found, returns the default value (see
2028 * Hash::new for details).
2029 *
2030 * h = { "a" => 100, "b" => 200 }
2031 * h["a"] #=> 100
2032 * h["c"] #=> nil
2033 *
2034 */
2035
2036VALUE
2038{
2039 st_data_t val;
2040
2041 if (hash_stlike_lookup(hash, key, &val)) {
2042 return (VALUE)val;
2043 }
2044 else {
2045 return rb_hash_default_value(hash, key);
2046 }
2047}
2048
2049VALUE
2051{
2052 st_data_t val;
2053
2054 if (hash_stlike_lookup(hash, key, &val)) {
2055 return (VALUE)val;
2056 }
2057 else {
2058 return def; /* without Hash#default */
2059 }
2060}
2061
2062VALUE
2064{
2065 return rb_hash_lookup2(hash, key, Qnil);
2066}
2067
2068/*
2069 * call-seq:
2070 * hsh.fetch(key [, default] ) -> obj
2071 * hsh.fetch(key) {| key | block } -> obj
2072 *
2073 * Returns a value from the hash for the given key. If the key can't be
2074 * found, there are several options: With no other arguments, it will
2075 * raise a KeyError exception; if <i>default</i> is given,
2076 * then that will be returned; if the optional code block is specified,
2077 * then that will be run and its result returned.
2078 *
2079 * h = { "a" => 100, "b" => 200 }
2080 * h.fetch("a") #=> 100
2081 * h.fetch("z", "go fish") #=> "go fish"
2082 * h.fetch("z") { |el| "go fish, #{el}"} #=> "go fish, z"
2083 *
2084 * The following example shows that an exception is raised if the key
2085 * is not found and a default value is not supplied.
2086 *
2087 * h = { "a" => 100, "b" => 200 }
2088 * h.fetch("z")
2089 *
2090 * <em>produces:</em>
2091 *
2092 * prog.rb:2:in `fetch': key not found (KeyError)
2093 * from prog.rb:2
2094 *
2095 */
2096
2097static VALUE
2098rb_hash_fetch_m(int argc, VALUE *argv, VALUE hash)
2099{
2100 VALUE key;
2101 st_data_t val;
2102 long block_given;
2103
2104 rb_check_arity(argc, 1, 2);
2105 key = argv[0];
2106
2107 block_given = rb_block_given_p();
2108 if (block_given && argc == 2) {
2109 rb_warn("block supersedes default value argument");
2110 }
2111
2112 if (hash_stlike_lookup(hash, key, &val)) {
2113 return (VALUE)val;
2114 }
2115 else {
2116 if (block_given) {
2117 return rb_yield(key);
2118 }
2119 else if (argc == 1) {
2120 VALUE desc = rb_protect(rb_inspect, key, 0);
2121 if (NIL_P(desc)) {
2122 desc = rb_any_to_s(key);
2123 }
2124 desc = rb_str_ellipsize(desc, 65);
2125 rb_key_err_raise(rb_sprintf("key not found: %"PRIsVALUE, desc), hash, key);
2126 }
2127 else {
2128 return argv[1];
2129 }
2130 }
2131}
2132
2133VALUE
2135{
2136 return rb_hash_fetch_m(1, &key, hash);
2137}
2138
2139/*
2140 * call-seq:
2141 * hsh.default(key=nil) -> obj
2142 *
2143 * Returns the default value, the value that would be returned by
2144 * <i>hsh</i>[<i>key</i>] if <i>key</i> did not exist in <i>hsh</i>.
2145 * See also Hash::new and Hash#default=.
2146 *
2147 * h = Hash.new #=> {}
2148 * h.default #=> nil
2149 * h.default(2) #=> nil
2150 *
2151 * h = Hash.new("cat") #=> {}
2152 * h.default #=> "cat"
2153 * h.default(2) #=> "cat"
2154 *
2155 * h = Hash.new {|h,k| h[k] = k.to_i*10} #=> {}
2156 * h.default #=> nil
2157 * h.default(2) #=> 20
2158 */
2159
2160static VALUE
2161rb_hash_default(int argc, VALUE *argv, VALUE hash)
2162{
2163 VALUE args[2], ifnone;
2164
2165 rb_check_arity(argc, 0, 1);
2166 ifnone = RHASH_IFNONE(hash);
2167 if (FL_TEST(hash, RHASH_PROC_DEFAULT)) {
2168 if (argc == 0) return Qnil;
2169 args[0] = hash;
2170 args[1] = argv[0];
2171 return rb_funcallv(ifnone, id_yield, 2, args);
2172 }
2173 return ifnone;
2174}
2175
2176/*
2177 * call-seq:
2178 * hsh.default = obj -> obj
2179 *
2180 * Sets the default value, the value returned for a key that does not
2181 * exist in the hash. It is not possible to set the default to a
2182 * Proc that will be executed on each key lookup.
2183 *
2184 * h = { "a" => 100, "b" => 200 }
2185 * h.default = "Go fish"
2186 * h["a"] #=> 100
2187 * h["z"] #=> "Go fish"
2188 * # This doesn't do what you might hope...
2189 * h.default = proc do |hash, key|
2190 * hash[key] = key + key
2191 * end
2192 * h[2] #=> #<Proc:0x401b3948@-:6>
2193 * h["cat"] #=> #<Proc:0x401b3948@-:6>
2194 */
2195
2196static VALUE
2197rb_hash_set_default(VALUE hash, VALUE ifnone)
2198{
2199 rb_hash_modify_check(hash);
2200 SET_DEFAULT(hash, ifnone);
2201 return ifnone;
2202}
2203
2204/*
2205 * call-seq:
2206 * hsh.default_proc -> anObject
2207 *
2208 * If Hash::new was invoked with a block, return that
2209 * block, otherwise return <code>nil</code>.
2210 *
2211 * h = Hash.new {|h,k| h[k] = k*k } #=> {}
2212 * p = h.default_proc #=> #<Proc:0x401b3d08@-:1>
2213 * a = [] #=> []
2214 * p.call(a, 2)
2215 * a #=> [nil, nil, 4]
2216 */
2217
2218
2219static VALUE
2220rb_hash_default_proc(VALUE hash)
2221{
2222 if (FL_TEST(hash, RHASH_PROC_DEFAULT)) {
2223 return RHASH_IFNONE(hash);
2224 }
2225 return Qnil;
2226}
2227
2228/*
2229 * call-seq:
2230 * hsh.default_proc = proc_obj or nil
2231 *
2232 * Sets the default proc to be executed on each failed key lookup.
2233 *
2234 * h.default_proc = proc do |hash, key|
2235 * hash[key] = key + key
2236 * end
2237 * h[2] #=> 4
2238 * h["cat"] #=> "catcat"
2239 */
2240
2241VALUE
2243{
2244 VALUE b;
2245
2246 rb_hash_modify_check(hash);
2247 if (NIL_P(proc)) {
2248 SET_DEFAULT(hash, proc);
2249 return proc;
2250 }
2252 if (NIL_P(b) || !rb_obj_is_proc(b)) {
2254 "wrong default_proc type %s (expected Proc)",
2255 rb_obj_classname(proc));
2256 }
2257 proc = b;
2258 SET_PROC_DEFAULT(hash, proc);
2259 return proc;
2260}
2261
2262static int
2263key_i(VALUE key, VALUE value, VALUE arg)
2264{
2265 VALUE *args = (VALUE *)arg;
2266
2267 if (rb_equal(value, args[0])) {
2268 args[1] = key;
2269 return ST_STOP;
2270 }
2271 return ST_CONTINUE;
2272}
2273
2274/*
2275 * call-seq:
2276 * hsh.key(value) -> key
2277 *
2278 * Returns the key of an occurrence of a given value. If the value is
2279 * not found, returns <code>nil</code>.
2280 *
2281 * h = { "a" => 100, "b" => 200, "c" => 300, "d" => 300 }
2282 * h.key(200) #=> "b"
2283 * h.key(300) #=> "c"
2284 * h.key(999) #=> nil
2285 *
2286 */
2287
2288static VALUE
2289rb_hash_key(VALUE hash, VALUE value)
2290{
2291 VALUE args[2];
2292
2293 args[0] = value;
2294 args[1] = Qnil;
2295
2296 rb_hash_foreach(hash, key_i, (VALUE)args);
2297
2298 return args[1];
2299}
2300
2301/* :nodoc: */
2302static VALUE
2303rb_hash_index(VALUE hash, VALUE value)
2304{
2305 rb_warn_deprecated("Hash#index", "Hash#key");
2306 return rb_hash_key(hash, value);
2307}
2308
2309int
2311{
2312 if (RHASH_AR_TABLE_P(hash)) {
2313 return ar_delete(hash, pkey, pval);
2314 }
2315 else {
2316 return st_delete(RHASH_ST_TABLE(hash), pkey, pval);
2317 }
2318}
2319
2320/*
2321 * delete a specified entry a given key.
2322 * if there is the corresponding entry, return a value of the entry.
2323 * if there is no corresponding entry, return Qundef.
2324 */
2325VALUE
2327{
2328 st_data_t ktmp = (st_data_t)key, val;
2329
2330 if (rb_hash_stlike_delete(hash, &ktmp, &val)) {
2331 return (VALUE)val;
2332 }
2333 else {
2334 return Qundef;
2335 }
2336}
2337
2338/*
2339 * delete a specified entry by a given key.
2340 * if there is the corresponding entry, return a value of the entry.
2341 * if there is no corresponding entry, return Qnil.
2342 */
2343VALUE
2345{
2346 VALUE deleted_value = rb_hash_delete_entry(hash, key);
2347
2348 if (deleted_value != Qundef) { /* likely pass */
2349 return deleted_value;
2350 }
2351 else {
2352 return Qnil;
2353 }
2354}
2355
2356/*
2357 * call-seq:
2358 * hsh.delete(key) -> value
2359 * hsh.delete(key) {| key | block } -> value
2360 *
2361 * Deletes the key-value pair and returns the value from <i>hsh</i> whose
2362 * key is equal to <i>key</i>. If the key is not found, it returns
2363 * <em>nil</em>. If the optional code block is given and the
2364 * key is not found, pass in the key and return the result of
2365 * <i>block</i>.
2366 *
2367 * h = { "a" => 100, "b" => 200 }
2368 * h.delete("a") #=> 100
2369 * h.delete("z") #=> nil
2370 * h.delete("z") { |el| "#{el} not found" } #=> "z not found"
2371 *
2372 */
2373
2374static VALUE
2375rb_hash_delete_m(VALUE hash, VALUE key)
2376{
2377 VALUE val;
2378
2379 rb_hash_modify_check(hash);
2380 val = rb_hash_delete_entry(hash, key);
2381
2382 if (val != Qundef) {
2383 return val;
2384 }
2385 else {
2386 if (rb_block_given_p()) {
2387 return rb_yield(key);
2388 }
2389 else {
2390 return Qnil;
2391 }
2392 }
2393}
2394
2398};
2399
2400static int
2401shift_i_safe(VALUE key, VALUE value, VALUE arg)
2402{
2403 struct shift_var *var = (struct shift_var *)arg;
2404
2405 var->key = key;
2406 var->val = value;
2407 return ST_STOP;
2408}
2409
2410/*
2411 * call-seq:
2412 * hsh.shift -> anArray or obj
2413 *
2414 * Removes a key-value pair from <i>hsh</i> and returns it as the
2415 * two-item array <code>[</code> <i>key, value</i> <code>]</code>, or
2416 * the hash's default value if the hash is empty.
2417 *
2418 * h = { 1 => "a", 2 => "b", 3 => "c" }
2419 * h.shift #=> [1, "a"]
2420 * h #=> {2=>"b", 3=>"c"}
2421 */
2422
2423static VALUE
2424rb_hash_shift(VALUE hash)
2425{
2426 struct shift_var var;
2427
2428 rb_hash_modify_check(hash);
2429 if (RHASH_AR_TABLE_P(hash)) {
2430 var.key = Qundef;
2431 if (RHASH_ITER_LEV(hash) == 0) {
2432 if (ar_shift(hash, &var.key, &var.val)) {
2433 return rb_assoc_new(var.key, var.val);
2434 }
2435 }
2436 else {
2437 rb_hash_foreach(hash, shift_i_safe, (VALUE)&var);
2438 if (var.key != Qundef) {
2439 rb_hash_delete_entry(hash, var.key);
2440 return rb_assoc_new(var.key, var.val);
2441 }
2442 }
2443 }
2444 if (RHASH_ST_TABLE_P(hash)) {
2445 var.key = Qundef;
2446 if (RHASH_ITER_LEV(hash) == 0) {
2447 if (st_shift(RHASH_ST_TABLE(hash), &var.key, &var.val)) {
2448 return rb_assoc_new(var.key, var.val);
2449 }
2450 }
2451 else {
2452 rb_hash_foreach(hash, shift_i_safe, (VALUE)&var);
2453 if (var.key != Qundef) {
2454 rb_hash_delete_entry(hash, var.key);
2455 return rb_assoc_new(var.key, var.val);
2456 }
2457 }
2458 }
2459 return rb_hash_default_value(hash, Qnil);
2460}
2461
2462static int
2463delete_if_i(VALUE key, VALUE value, VALUE hash)
2464{
2465 if (RTEST(rb_yield_values(2, key, value))) {
2466 return ST_DELETE;
2467 }
2468 return ST_CONTINUE;
2469}
2470
2471static VALUE
2472hash_enum_size(VALUE hash, VALUE args, VALUE eobj)
2473{
2474 return rb_hash_size(hash);
2475}
2476
2477/*
2478 * call-seq:
2479 * hsh.delete_if {| key, value | block } -> hsh
2480 * hsh.delete_if -> an_enumerator
2481 *
2482 * Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
2483 * evaluates to <code>true</code>.
2484 *
2485 * If no block is given, an enumerator is returned instead.
2486 *
2487 * h = { "a" => 100, "b" => 200, "c" => 300 }
2488 * h.delete_if {|key, value| key >= "b" } #=> {"a"=>100}
2489 *
2490 */
2491
2492VALUE
2494{
2495 RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2496 rb_hash_modify_check(hash);
2497 if (!RHASH_TABLE_EMPTY_P(hash)) {
2498 rb_hash_foreach(hash, delete_if_i, hash);
2499 }
2500 return hash;
2501}
2502
2503/*
2504 * call-seq:
2505 * hsh.reject! {| key, value | block } -> hsh or nil
2506 * hsh.reject! -> an_enumerator
2507 *
2508 * Equivalent to Hash#delete_if, but returns
2509 * <code>nil</code> if no changes were made.
2510 */
2511
2512VALUE
2514{
2515 st_index_t n;
2516
2517 RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2518 rb_hash_modify(hash);
2519 n = RHASH_SIZE(hash);
2520 if (!n) return Qnil;
2521 rb_hash_foreach(hash, delete_if_i, hash);
2522 if (n == RHASH_SIZE(hash)) return Qnil;
2523 return hash;
2524}
2525
2526static int
2527reject_i(VALUE key, VALUE value, VALUE result)
2528{
2529 if (!RTEST(rb_yield_values(2, key, value))) {
2530 rb_hash_aset(result, key, value);
2531 }
2532 return ST_CONTINUE;
2533}
2534
2535/*
2536 * call-seq:
2537 * hsh.reject {|key, value| block} -> a_hash
2538 * hsh.reject -> an_enumerator
2539 *
2540 * Returns a new hash consisting of entries for which the block returns false.
2541 *
2542 * If no block is given, an enumerator is returned instead.
2543 *
2544 * h = { "a" => 100, "b" => 200, "c" => 300 }
2545 * h.reject {|k,v| k < "b"} #=> {"b" => 200, "c" => 300}
2546 * h.reject {|k,v| v > 100} #=> {"a" => 100}
2547 */
2548
2549VALUE
2551{
2552 VALUE result;
2553
2554 RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2555 if (RTEST(ruby_verbose)) {
2556 VALUE klass;
2557 if (HAS_EXTRA_STATES(hash, klass)) {
2558 rb_warn("extra states are no longer copied: %+"PRIsVALUE, hash);
2559 }
2560 }
2561 result = rb_hash_new();
2562 if (!RHASH_EMPTY_P(hash)) {
2563 rb_hash_foreach(hash, reject_i, result);
2564 }
2565 return result;
2566}
2567
2568/*
2569 * call-seq:
2570 * hsh.slice(*keys) -> a_hash
2571 *
2572 * Returns a hash containing only the given keys and their values.
2573 *
2574 * h = { a: 100, b: 200, c: 300 }
2575 * h.slice(:a) #=> {:a=>100}
2576 * h.slice(:b, :c, :d) #=> {:b=>200, :c=>300}
2577 */
2578
2579static VALUE
2580rb_hash_slice(int argc, VALUE *argv, VALUE hash)
2581{
2582 int i;
2583 VALUE key, value, result;
2584
2585 if (argc == 0 || RHASH_EMPTY_P(hash)) {
2586 return rb_hash_new();
2587 }
2588 result = rb_hash_new_with_size(argc);
2589
2590 for (i = 0; i < argc; i++) {
2591 key = argv[i];
2592 value = rb_hash_lookup2(hash, key, Qundef);
2593 if (value != Qundef)
2594 rb_hash_aset(result, key, value);
2595 }
2596
2597 return result;
2598}
2599
2600/*
2601 * call-seq:
2602 * hsh.values_at(key, ...) -> array
2603 *
2604 * Return an array containing the values associated with the given keys.
2605 * Also see Hash.select.
2606 *
2607 * h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
2608 * h.values_at("cow", "cat") #=> ["bovine", "feline"]
2609 */
2610
2611VALUE
2613{
2614 VALUE result = rb_ary_new2(argc);
2615 long i;
2616
2617 for (i=0; i<argc; i++) {
2618 rb_ary_push(result, rb_hash_aref(hash, argv[i]));
2619 }
2620 return result;
2621}
2622
2623/*
2624 * call-seq:
2625 * hsh.fetch_values(key, ...) -> array
2626 * hsh.fetch_values(key, ...) { |key| block } -> array
2627 *
2628 * Returns an array containing the values associated with the given keys
2629 * but also raises KeyError when one of keys can't be found.
2630 * Also see Hash#values_at and Hash#fetch.
2631 *
2632 * h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
2633 *
2634 * h.fetch_values("cow", "cat") #=> ["bovine", "feline"]
2635 * h.fetch_values("cow", "bird") # raises KeyError
2636 * h.fetch_values("cow", "bird") { |k| k.upcase } #=> ["bovine", "BIRD"]
2637 */
2638
2639VALUE
2641{
2642 VALUE result = rb_ary_new2(argc);
2643 long i;
2644
2645 for (i=0; i<argc; i++) {
2646 rb_ary_push(result, rb_hash_fetch(hash, argv[i]));
2647 }
2648 return result;
2649}
2650
2651static int
2652select_i(VALUE key, VALUE value, VALUE result)
2653{
2654 if (RTEST(rb_yield_values(2, key, value))) {
2655 rb_hash_aset(result, key, value);
2656 }
2657 return ST_CONTINUE;
2658}
2659
2660/*
2661 * call-seq:
2662 * hsh.select {|key, value| block} -> a_hash
2663 * hsh.select -> an_enumerator
2664 * hsh.filter {|key, value| block} -> a_hash
2665 * hsh.filter -> an_enumerator
2666 *
2667 * Returns a new hash consisting of entries for which the block returns true.
2668 *
2669 * If no block is given, an enumerator is returned instead.
2670 *
2671 * h = { "a" => 100, "b" => 200, "c" => 300 }
2672 * h.select {|k,v| k > "a"} #=> {"b" => 200, "c" => 300}
2673 * h.select {|k,v| v < 200} #=> {"a" => 100}
2674 *
2675 * Hash#filter is an alias for Hash#select.
2676 */
2677
2678VALUE
2680{
2681 VALUE result;
2682
2683 RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2684 result = rb_hash_new();
2685 if (!RHASH_EMPTY_P(hash)) {
2686 rb_hash_foreach(hash, select_i, result);
2687 }
2688 return result;
2689}
2690
2691static int
2692keep_if_i(VALUE key, VALUE value, VALUE hash)
2693{
2694 if (!RTEST(rb_yield_values(2, key, value))) {
2695 return ST_DELETE;
2696 }
2697 return ST_CONTINUE;
2698}
2699
2700/*
2701 * call-seq:
2702 * hsh.select! {| key, value | block } -> hsh or nil
2703 * hsh.select! -> an_enumerator
2704 * hsh.filter! {| key, value | block } -> hsh or nil
2705 * hsh.filter! -> an_enumerator
2706 *
2707 * Equivalent to Hash#keep_if, but returns
2708 * +nil+ if no changes were made.
2709 *
2710 * Hash#filter! is an alias for Hash#select!.
2711 */
2712
2713VALUE
2715{
2716 st_index_t n;
2717
2718 RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2719 rb_hash_modify_check(hash);
2720 n = RHASH_SIZE(hash);
2721 if (!n) return Qnil;
2722 rb_hash_foreach(hash, keep_if_i, hash);
2723 if (n == RHASH_SIZE(hash)) return Qnil;
2724 return hash;
2725}
2726
2727/*
2728 * call-seq:
2729 * hsh.keep_if {| key, value | block } -> hsh
2730 * hsh.keep_if -> an_enumerator
2731 *
2732 * Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
2733 * evaluates to +false+.
2734 *
2735 * If no block is given, an enumerator is returned instead.
2736 *
2737 * See also Hash#select!.
2738 */
2739
2740VALUE
2742{
2743 RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2744 rb_hash_modify_check(hash);
2745 if (!RHASH_TABLE_EMPTY_P(hash)) {
2746 rb_hash_foreach(hash, keep_if_i, hash);
2747 }
2748 return hash;
2749}
2750
2751static int
2752clear_i(VALUE key, VALUE value, VALUE dummy)
2753{
2754 return ST_DELETE;
2755}
2756
2757/*
2758 * call-seq:
2759 * hsh.clear -> hsh
2760 *
2761 * Removes all key-value pairs from <i>hsh</i>.
2762 *
2763 * h = { "a" => 100, "b" => 200 } #=> {"a"=>100, "b"=>200}
2764 * h.clear #=> {}
2765 *
2766 */
2767
2768VALUE
2770{
2771 rb_hash_modify_check(hash);
2772
2773 if (RHASH_ITER_LEV(hash) > 0) {
2774 rb_hash_foreach(hash, clear_i, 0);
2775 }
2776 else if (RHASH_AR_TABLE_P(hash)) {
2777 ar_clear(hash);
2778 }
2779 else {
2780 st_clear(RHASH_ST_TABLE(hash));
2781 }
2782
2783 return hash;
2784}
2785
2786static int
2787hash_aset(st_data_t *key, st_data_t *val, struct update_arg *arg, int existing)
2788{
2789 if (existing) {
2790 arg->new_value = arg->arg;
2791 arg->old_value = *val;
2792 }
2793 else {
2794 arg->new_key = *key;
2795 arg->new_value = arg->arg;
2796 }
2797 *val = arg->arg;
2798 return ST_CONTINUE;
2799}
2800
2801VALUE
2803{
2805 return rb_fstring(key);
2806 }
2807 else {
2808 return rb_str_new_frozen(key);
2809 }
2810}
2811
2812static int
2813hash_aset_str(st_data_t *key, st_data_t *val, struct update_arg *arg, int existing)
2814{
2815 if (!existing && !RB_OBJ_FROZEN(*key)) {
2816 *key = rb_hash_key_str(*key);
2817 }
2818 return hash_aset(key, val, arg, existing);
2819}
2820
2821NOINSERT_UPDATE_CALLBACK(hash_aset)
2822NOINSERT_UPDATE_CALLBACK(hash_aset_str)
2823
2824/*
2825 * call-seq:
2826 * hsh[key] = value -> value
2827 * hsh.store(key, value) -> value
2828 *
2829 * == Element Assignment
2830 *
2831 * Associates the value given by +value+ with the key given by +key+.
2832 *
2833 * h = { "a" => 100, "b" => 200 }
2834 * h["a"] = 9
2835 * h["c"] = 4
2836 * h #=> {"a"=>9, "b"=>200, "c"=>4}
2837 * h.store("d", 42) #=> 42
2838 * h #=> {"a"=>9, "b"=>200, "c"=>4, "d"=>42}
2839 *
2840 * +key+ should not have its value changed while it is in use as a key (an
2841 * <tt>unfrozen String</tt> passed as a key will be duplicated and frozen).
2842 *
2843 * a = "a"
2844 * b = "b".freeze
2845 * h = { a => 100, b => 200 }
2846 * h.key(100).equal? a #=> false
2847 * h.key(200).equal? b #=> true
2848 *
2849 */
2850
2851VALUE
2853{
2854 int iter_lev = RHASH_ITER_LEV(hash);
2855
2856 rb_hash_modify(hash);
2857
2858 if (RHASH_TABLE_NULL_P(hash)) {
2859 if (iter_lev > 0) no_new_key();
2860 ar_alloc_table(hash);
2861 }
2862
2863 if (RHASH_TYPE(hash) == &identhash || rb_obj_class(key) != rb_cString) {
2864 RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset, val);
2865 }
2866 else {
2867 RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset_str, val);
2868 }
2869 return val;
2870}
2871
2872/*
2873 * call-seq:
2874 * hsh.replace(other_hash) -> hsh
2875 *
2876 * Replaces the contents of <i>hsh</i> with the contents of
2877 * <i>other_hash</i>.
2878 *
2879 * h = { "a" => 100, "b" => 200 }
2880 * h.replace({ "c" => 300, "d" => 400 }) #=> {"c"=>300, "d"=>400}
2881 *
2882 */
2883
2884static VALUE
2885rb_hash_replace(VALUE hash, VALUE hash2)
2886{
2887 rb_hash_modify_check(hash);
2888 if (hash == hash2) return hash;
2889 if (RHASH_ITER_LEV(hash) > 0) {
2890 rb_raise(rb_eRuntimeError, "can't replace hash during iteration");
2891 }
2892 hash2 = to_hash(hash2);
2893
2894 COPY_DEFAULT(hash, hash2);
2895
2896 if (RHASH_AR_TABLE_P(hash)) {
2897 if (RHASH_AR_TABLE_P(hash2)) {
2898 ar_clear(hash);
2899 }
2900 else {
2901 ar_free_and_clear_table(hash);
2903 }
2904 }
2905 else {
2906 if (RHASH_AR_TABLE_P(hash2)) {
2908 RHASH_ST_CLEAR(hash);
2909 }
2910 else {
2911 st_clear(RHASH_ST_TABLE(hash));
2912 RHASH_TBL_RAW(hash)->type = RHASH_ST_TABLE(hash2)->type;
2913 }
2914 }
2915 rb_hash_foreach(hash2, rb_hash_rehash_i, (VALUE)hash);
2916
2918
2919 return hash;
2920}
2921
2922/*
2923 * call-seq:
2924 * hsh.length -> integer
2925 * hsh.size -> integer
2926 *
2927 * Returns the number of key-value pairs in the hash.
2928 *
2929 * h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
2930 * h.size #=> 4
2931 * h.delete("a") #=> 200
2932 * h.size #=> 3
2933 * h.length #=> 3
2934 *
2935 * Hash#length is an alias for Hash#size.
2936 */
2937
2938VALUE
2940{
2941 return INT2FIX(RHASH_SIZE(hash));
2942}
2943
2944size_t
2946{
2947 return (long)RHASH_SIZE(hash);
2948}
2949
2950/*
2951 * call-seq:
2952 * hsh.empty? -> true or false
2953 *
2954 * Returns <code>true</code> if <i>hsh</i> contains no key-value pairs.
2955 *
2956 * {}.empty? #=> true
2957 *
2958 */
2959
2960static VALUE
2961rb_hash_empty_p(VALUE hash)
2962{
2963 return RHASH_EMPTY_P(hash) ? Qtrue : Qfalse;
2964}
2965
2966static int
2967each_value_i(VALUE key, VALUE value, VALUE _)
2968{
2969 rb_yield(value);
2970 return ST_CONTINUE;
2971}
2972
2973/*
2974 * call-seq:
2975 * hsh.each_value {| value | block } -> hsh
2976 * hsh.each_value -> an_enumerator
2977 *
2978 * Calls <i>block</i> once for each key in <i>hsh</i>, passing the
2979 * value as a parameter.
2980 *
2981 * If no block is given, an enumerator is returned instead.
2982 *
2983 * h = { "a" => 100, "b" => 200 }
2984 * h.each_value {|value| puts value }
2985 *
2986 * <em>produces:</em>
2987 *
2988 * 100
2989 * 200
2990 */
2991
2992static VALUE
2993rb_hash_each_value(VALUE hash)
2994{
2995 RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2996 rb_hash_foreach(hash, each_value_i, 0);
2997 return hash;
2998}
2999
3000static int
3001each_key_i(VALUE key, VALUE value, VALUE _)
3002{
3003 rb_yield(key);
3004 return ST_CONTINUE;
3005}
3006
3007/*
3008 * call-seq:
3009 * hsh.each_key {| key | block } -> hsh
3010 * hsh.each_key -> an_enumerator
3011 *
3012 * Calls <i>block</i> once for each key in <i>hsh</i>, passing the key
3013 * as a parameter.
3014 *
3015 * If no block is given, an enumerator is returned instead.
3016 *
3017 * h = { "a" => 100, "b" => 200 }
3018 * h.each_key {|key| puts key }
3019 *
3020 * <em>produces:</em>
3021 *
3022 * a
3023 * b
3024 */
3025static VALUE
3026rb_hash_each_key(VALUE hash)
3027{
3028 RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3029 rb_hash_foreach(hash, each_key_i, 0);
3030 return hash;
3031}
3032
3033static int
3034each_pair_i(VALUE key, VALUE value, VALUE _)
3035{
3036 rb_yield(rb_assoc_new(key, value));
3037 return ST_CONTINUE;
3038}
3039
3040static int
3041each_pair_i_fast(VALUE key, VALUE value, VALUE _)
3042{
3043 VALUE argv[2];
3044 argv[0] = key;
3045 argv[1] = value;
3047 return ST_CONTINUE;
3048}
3049
3050/*
3051 * call-seq:
3052 * hsh.each {| key, value | block } -> hsh
3053 * hsh.each_pair {| key, value | block } -> hsh
3054 * hsh.each -> an_enumerator
3055 * hsh.each_pair -> an_enumerator
3056 *
3057 * Calls <i>block</i> once for each key in <i>hsh</i>, passing the key-value
3058 * pair as parameters.
3059 *
3060 * If no block is given, an enumerator is returned instead.
3061 *
3062 * h = { "a" => 100, "b" => 200 }
3063 * h.each {|key, value| puts "#{key} is #{value}" }
3064 *
3065 * <em>produces:</em>
3066 *
3067 * a is 100
3068 * b is 200
3069 *
3070 */
3071
3072static VALUE
3073rb_hash_each_pair(VALUE hash)
3074{
3075 RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3076 if (rb_block_arity() > 1)
3077 rb_hash_foreach(hash, each_pair_i_fast, 0);
3078 else
3079 rb_hash_foreach(hash, each_pair_i, 0);
3080 return hash;
3081}
3082
3083static int
3084transform_keys_i(VALUE key, VALUE value, VALUE result)
3085{
3086 VALUE new_key = rb_yield(key);
3087 rb_hash_aset(result, new_key, value);
3088 return ST_CONTINUE;
3089}
3090
3091/*
3092 * call-seq:
3093 * hsh.transform_keys {|key| block } -> new_hash
3094 * hsh.transform_keys -> an_enumerator
3095 *
3096 * Returns a new hash with the results of running the block once for
3097 * every key.
3098 * This method does not change the values.
3099 *
3100 * h = { a: 1, b: 2, c: 3 }
3101 * h.transform_keys {|k| k.to_s } #=> { "a" => 1, "b" => 2, "c" => 3 }
3102 * h.transform_keys(&:to_s) #=> { "a" => 1, "b" => 2, "c" => 3 }
3103 * h.transform_keys.with_index {|k, i| "#{k}.#{i}" }
3104 * #=> { "a.0" => 1, "b.1" => 2, "c.2" => 3 }
3105 *
3106 * If no block is given, an enumerator is returned instead.
3107 */
3108static VALUE
3109rb_hash_transform_keys(VALUE hash)
3110{
3111 VALUE result;
3112
3113 RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3114 result = rb_hash_new();
3115 if (!RHASH_EMPTY_P(hash)) {
3116 rb_hash_foreach(hash, transform_keys_i, result);
3117 }
3118
3119 return result;
3120}
3121
3122static VALUE rb_hash_flatten(int argc, VALUE *argv, VALUE hash);
3123
3124/*
3125 * call-seq:
3126 * hsh.transform_keys! {|key| block } -> hsh
3127 * hsh.transform_keys! -> an_enumerator
3128 *
3129 * Invokes the given block once for each key in <i>hsh</i>, replacing it
3130 * with the new key returned by the block, and then returns <i>hsh</i>.
3131 * This method does not change the values.
3132 *
3133 * h = { a: 1, b: 2, c: 3 }
3134 * h.transform_keys! {|k| k.to_s } #=> { "a" => 1, "b" => 2, "c" => 3 }
3135 * h.transform_keys!(&:to_sym) #=> { a: 1, b: 2, c: 3 }
3136 * h.transform_keys!.with_index {|k, i| "#{k}.#{i}" }
3137 * #=> { "a.0" => 1, "b.1" => 2, "c.2" => 3 }
3138 *
3139 * If no block is given, an enumerator is returned instead.
3140 */
3141static VALUE
3142rb_hash_transform_keys_bang(VALUE hash)
3143{
3144 RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3145 rb_hash_modify_check(hash);
3146 if (!RHASH_TABLE_EMPTY_P(hash)) {
3147 long i;
3148 VALUE pairs = rb_hash_flatten(0, NULL, hash);
3149 rb_hash_clear(hash);
3150 for (i = 0; i < RARRAY_LEN(pairs); i += 2) {
3151 VALUE key = RARRAY_AREF(pairs, i), new_key = rb_yield(key),
3152 val = RARRAY_AREF(pairs, i+1);
3153 rb_hash_aset(hash, new_key, val);
3154 }
3155 }
3156 return hash;
3157}
3158
3159static int
3160transform_values_foreach_func(st_data_t key, st_data_t value, st_data_t argp, int error)
3161{
3162 return ST_REPLACE;
3163}
3164
3165static int
3166transform_values_foreach_replace(st_data_t *key, st_data_t *value, st_data_t argp, int existing)
3167{
3168 VALUE new_value = rb_yield((VALUE)*value);
3169 VALUE hash = (VALUE)argp;
3170 RB_OBJ_WRITE(hash, value, new_value);
3171 return ST_CONTINUE;
3172}
3173
3174/*
3175 * call-seq:
3176 * hsh.transform_values {|value| block } -> new_hash
3177 * hsh.transform_values -> an_enumerator
3178 *
3179 * Returns a new hash with the results of running the block once for
3180 * every value.
3181 * This method does not change the keys.
3182 *
3183 * h = { a: 1, b: 2, c: 3 }
3184 * h.transform_values {|v| v * v + 1 } #=> { a: 2, b: 5, c: 10 }
3185 * h.transform_values(&:to_s) #=> { a: "1", b: "2", c: "3" }
3186 * h.transform_values.with_index {|v, i| "#{v}.#{i}" }
3187 * #=> { a: "1.0", b: "2.1", c: "3.2" }
3188 *
3189 * If no block is given, an enumerator is returned instead.
3190 */
3191static VALUE
3192rb_hash_transform_values(VALUE hash)
3193{
3194 VALUE result;
3195
3196 RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3197 result = hash_copy(hash_alloc(rb_cHash), hash);
3198 SET_DEFAULT(result, Qnil);
3199
3200 if (!RHASH_EMPTY_P(hash)) {
3201 rb_hash_stlike_foreach_with_replace(result, transform_values_foreach_func, transform_values_foreach_replace, result);
3202 }
3203
3204 return result;
3205}
3206
3207/*
3208 * call-seq:
3209 * hsh.transform_values! {|value| block } -> hsh
3210 * hsh.transform_values! -> an_enumerator
3211 *
3212 * Invokes the given block once for each value in <i>hsh</i>, replacing it
3213 * with the new value returned by the block, and then returns <i>hsh</i>.
3214 * This method does not change the keys.
3215 *
3216 * h = { a: 1, b: 2, c: 3 }
3217 * h.transform_values! {|v| v * v + 1 } #=> { a: 2, b: 5, c: 10 }
3218 * h.transform_values!(&:to_s) #=> { a: "2", b: "5", c: "10" }
3219 * h.transform_values!.with_index {|v, i| "#{v}.#{i}" }
3220 * #=> { a: "2.0", b: "5.1", c: "10.2" }
3221 *
3222 * If no block is given, an enumerator is returned instead.
3223 */
3224static VALUE
3225rb_hash_transform_values_bang(VALUE hash)
3226{
3227 RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3228 rb_hash_modify_check(hash);
3229
3230 if (!RHASH_TABLE_EMPTY_P(hash)) {
3231 rb_hash_stlike_foreach_with_replace(hash, transform_values_foreach_func, transform_values_foreach_replace, hash);
3232 }
3233
3234 return hash;
3235}
3236
3237static int
3238to_a_i(VALUE key, VALUE value, VALUE ary)
3239{
3240 rb_ary_push(ary, rb_assoc_new(key, value));
3241 return ST_CONTINUE;
3242}
3243
3244/*
3245 * call-seq:
3246 * hsh.to_a -> array
3247 *
3248 * Converts <i>hsh</i> to a nested array of <code>[</code> <i>key,
3249 * value</i> <code>]</code> arrays.
3250 *
3251 * h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 }
3252 * h.to_a #=> [["c", 300], ["a", 100], ["d", 400]]
3253 */
3254
3255static VALUE
3256rb_hash_to_a(VALUE hash)
3257{
3258 VALUE ary;
3259
3260 ary = rb_ary_new_capa(RHASH_SIZE(hash));
3261 rb_hash_foreach(hash, to_a_i, ary);
3262
3263 return ary;
3264}
3265
3266static int
3267inspect_i(VALUE key, VALUE value, VALUE str)
3268{
3269 VALUE str2;
3270
3271 str2 = rb_inspect(key);
3272 if (RSTRING_LEN(str) > 1) {
3274 }
3275 else {
3276 rb_enc_copy(str, str2);
3277 }
3278 rb_str_buf_append(str, str2);
3280 str2 = rb_inspect(value);
3281 rb_str_buf_append(str, str2);
3282
3283 return ST_CONTINUE;
3284}
3285
3286static VALUE
3287inspect_hash(VALUE hash, VALUE dummy, int recur)
3288{
3289 VALUE str;
3290
3291 if (recur) return rb_usascii_str_new2("{...}");
3292 str = rb_str_buf_new2("{");
3293 rb_hash_foreach(hash, inspect_i, str);
3294 rb_str_buf_cat2(str, "}");
3295
3296 return str;
3297}
3298
3299/*
3300 * call-seq:
3301 * hsh.to_s -> string
3302 * hsh.inspect -> string
3303 *
3304 * Return the contents of this hash as a string.
3305 *
3306 * h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 }
3307 * h.to_s #=> "{\"c\"=>300, \"a\"=>100, \"d\"=>400}"
3308 */
3309
3310static VALUE
3311rb_hash_inspect(VALUE hash)
3312{
3313 if (RHASH_EMPTY_P(hash))
3314 return rb_usascii_str_new2("{}");
3315 return rb_exec_recursive(inspect_hash, hash, 0);
3316}
3317
3318/*
3319 * call-seq:
3320 * hsh.to_hash => hsh
3321 *
3322 * Returns +self+.
3323 */
3324
3325static VALUE
3326rb_hash_to_hash(VALUE hash)
3327{
3328 return hash;
3329}
3330
3331VALUE
3333{
3334 VALUE pair;
3335
3336 pair = rb_check_array_type(arg);
3337 if (NIL_P(pair)) {
3338 rb_raise(rb_eTypeError, "wrong element type %s (expected array)",
3340 }
3341 if (RARRAY_LEN(pair) != 2) {
3342 rb_raise(rb_eArgError, "element has wrong array length (expected 2, was %ld)",
3343 RARRAY_LEN(pair));
3344 }
3345 rb_hash_aset(hash, RARRAY_AREF(pair, 0), RARRAY_AREF(pair, 1));
3346 return hash;
3347}
3348
3349static int
3350to_h_i(VALUE key, VALUE value, VALUE hash)
3351{
3352 rb_hash_set_pair(hash, rb_yield_values(2, key, value));
3353 return ST_CONTINUE;
3354}
3355
3356static VALUE
3357rb_hash_to_h_block(VALUE hash)
3358{
3360 rb_hash_foreach(hash, to_h_i, h);
3361 return h;
3362}
3363
3364/*
3365 * call-seq:
3366 * hsh.to_h -> hsh or new_hash
3367 * hsh.to_h {|key, value| block } -> new_hash
3368 *
3369 * Returns +self+. If called on a subclass of Hash, converts
3370 * the receiver to a Hash object.
3371 *
3372 * If a block is given, the results of the block on each pair of
3373 * the receiver will be used as pairs.
3374 */
3375
3376static VALUE
3377rb_hash_to_h(VALUE hash)
3378{
3379 if (rb_block_given_p()) {
3380 return rb_hash_to_h_block(hash);
3381 }
3382 if (rb_obj_class(hash) != rb_cHash) {
3383 const VALUE flags = RBASIC(hash)->flags;
3384 hash = hash_dup(hash, rb_cHash, flags & RHASH_PROC_DEFAULT);
3385 }
3386 return hash;
3387}
3388
3389static int
3390keys_i(VALUE key, VALUE value, VALUE ary)
3391{
3392 rb_ary_push(ary, key);
3393 return ST_CONTINUE;
3394}
3395
3396/*
3397 * call-seq:
3398 * hsh.keys -> array
3399 *
3400 * Returns a new array populated with the keys from this hash. See also
3401 * Hash#values.
3402 *
3403 * h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 }
3404 * h.keys #=> ["a", "b", "c", "d"]
3405 *
3406 */
3407
3410{
3411 st_index_t size = RHASH_SIZE(hash);
3413
3414 if (size == 0) return keys;
3415
3418 if (RHASH_AR_TABLE_P(hash)) {
3419 size = ar_keys(hash, ptr, size);
3420 }
3421 else {
3422 st_table *table = RHASH_ST_TABLE(hash);
3423 size = st_keys(table, ptr, size);
3424 }
3425 });
3428 }
3429 else {
3430 rb_hash_foreach(hash, keys_i, keys);
3431 }
3432
3433 return keys;
3434}
3435
3436static int
3437values_i(VALUE key, VALUE value, VALUE ary)
3438{
3439 rb_ary_push(ary, value);
3440 return ST_CONTINUE;
3441}
3442
3443/*
3444 * call-seq:
3445 * hsh.values -> array
3446 *
3447 * Returns a new array populated with the values from <i>hsh</i>. See
3448 * also Hash#keys.
3449 *
3450 * h = { "a" => 100, "b" => 200, "c" => 300 }
3451 * h.values #=> [100, 200, 300]
3452 *
3453 */
3454
3455VALUE
3457{
3458 VALUE values;
3459 st_index_t size = RHASH_SIZE(hash);
3460
3461 values = rb_ary_new_capa(size);
3462 if (size == 0) return values;
3463
3465 if (RHASH_AR_TABLE_P(hash)) {
3467 RARRAY_PTR_USE_TRANSIENT(values, ptr, {
3468 size = ar_values(hash, ptr, size);
3469 });
3470 }
3471 else if (RHASH_ST_TABLE_P(hash)) {
3472 st_table *table = RHASH_ST_TABLE(hash);
3474 RARRAY_PTR_USE_TRANSIENT(values, ptr, {
3475 size = st_values(table, ptr, size);
3476 });
3477 }
3478 rb_ary_set_len(values, size);
3479 }
3480 else {
3481 rb_hash_foreach(hash, values_i, values);
3482 }
3483
3484 return values;
3485}
3486
3487/*
3488 * call-seq:
3489 * hsh.has_key?(key) -> true or false
3490 * hsh.include?(key) -> true or false
3491 * hsh.key?(key) -> true or false
3492 * hsh.member?(key) -> true or false
3493 *
3494 * Returns <code>true</code> if the given key is present in <i>hsh</i>.
3495 *
3496 * h = { "a" => 100, "b" => 200 }
3497 * h.has_key?("a") #=> true
3498 * h.has_key?("z") #=> false
3499 *
3500 * Note that #include? and #member? do not test member
3501 * equality using <code>==</code> as do other Enumerables.
3502 *
3503 * See also Enumerable#include?
3504 */
3505
3508{
3509 if (hash_stlike_lookup(hash, key, NULL)) {
3510 return Qtrue;
3511 }
3512 else {
3513 return Qfalse;
3514 }
3515}
3516
3517static int
3518rb_hash_search_value(VALUE key, VALUE value, VALUE arg)
3519{
3520 VALUE *data = (VALUE *)arg;
3521
3522 if (rb_equal(value, data[1])) {
3523 data[0] = Qtrue;
3524 return ST_STOP;
3525 }
3526 return ST_CONTINUE;
3527}
3528
3529/*
3530 * call-seq:
3531 * hsh.has_value?(value) -> true or false
3532 * hsh.value?(value) -> true or false
3533 *
3534 * Returns <code>true</code> if the given value is present for some key
3535 * in <i>hsh</i>.
3536 *
3537 * h = { "a" => 100, "b" => 200 }
3538 * h.value?(100) #=> true
3539 * h.value?(999) #=> false
3540 */
3541
3542static VALUE
3543rb_hash_has_value(VALUE hash, VALUE val)
3544{
3545 VALUE data[2];
3546
3547 data[0] = Qfalse;
3548 data[1] = val;
3549 rb_hash_foreach(hash, rb_hash_search_value, (VALUE)data);
3550 return data[0];
3551}
3552
3556 int eql;
3557};
3558
3559static int
3560eql_i(VALUE key, VALUE val1, VALUE arg)
3561{
3562 struct equal_data *data = (struct equal_data *)arg;
3563 st_data_t val2;
3564
3565 if (!hash_stlike_lookup(data->hash, key, &val2)) {
3566 data->result = Qfalse;
3567 return ST_STOP;
3568 }
3569 else {
3570 if (!(data->eql ? rb_eql(val1, (VALUE)val2) : (int)rb_equal(val1, (VALUE)val2))) {
3571 data->result = Qfalse;
3572 return ST_STOP;
3573 }
3574 return ST_CONTINUE;
3575 }
3576}
3577
3578static VALUE
3579recursive_eql(VALUE hash, VALUE dt, int recur)
3580{
3581 struct equal_data *data;
3582
3583 if (recur) return Qtrue; /* Subtle! */
3584 data = (struct equal_data*)dt;
3585 data->result = Qtrue;
3586 rb_hash_foreach(hash, eql_i, dt);
3587
3588 return data->result;
3589}
3590
3591static VALUE
3592hash_equal(VALUE hash1, VALUE hash2, int eql)
3593{
3594 struct equal_data data;
3595
3596 if (hash1 == hash2) return Qtrue;
3597 if (!RB_TYPE_P(hash2, T_HASH)) {
3598 if (!rb_respond_to(hash2, idTo_hash)) {
3599 return Qfalse;
3600 }
3601 if (eql) {
3602 if (rb_eql(hash2, hash1)) {
3603 return Qtrue;
3604 }
3605 else {
3606 return Qfalse;
3607 }
3608 }
3609 else {
3610 return rb_equal(hash2, hash1);
3611 }
3612 }
3613 if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2))
3614 return Qfalse;
3615 if (!RHASH_TABLE_EMPTY_P(hash1) && !RHASH_TABLE_EMPTY_P(hash2)) {
3616 if (RHASH_TYPE(hash1) != RHASH_TYPE(hash2)) {
3617 return Qfalse;
3618 }
3619 else {
3620 data.hash = hash2;
3621 data.eql = eql;
3622 return rb_exec_recursive_paired(recursive_eql, hash1, hash2, (VALUE)&data);
3623 }
3624 }
3625
3626#if 0
3627 if (!(rb_equal(RHASH_IFNONE(hash1), RHASH_IFNONE(hash2)) &&
3629 return Qfalse;
3630#endif
3631 return Qtrue;
3632}
3633
3634/*
3635 * call-seq:
3636 * hsh == other_hash -> true or false
3637 *
3638 * Equality---Two hashes are equal if they each contain the same number
3639 * of keys and if each key-value pair is equal to (according to
3640 * Object#==) the corresponding elements in the other hash.
3641 *
3642 * h1 = { "a" => 1, "c" => 2 }
3643 * h2 = { 7 => 35, "c" => 2, "a" => 1 }
3644 * h3 = { "a" => 1, "c" => 2, 7 => 35 }
3645 * h4 = { "a" => 1, "d" => 2, "f" => 35 }
3646 * h1 == h2 #=> false
3647 * h2 == h3 #=> true
3648 * h3 == h4 #=> false
3649 *
3650 * The orders of each hashes are not compared.
3651 *
3652 * h1 = { "a" => 1, "c" => 2 }
3653 * h2 = { "c" => 2, "a" => 1 }
3654 * h1 == h2 #=> true
3655 *
3656 */
3657
3658static VALUE
3659rb_hash_equal(VALUE hash1, VALUE hash2)
3660{
3661 return hash_equal(hash1, hash2, FALSE);
3662}
3663
3664/*
3665 * call-seq:
3666 * hash.eql?(other) -> true or false
3667 *
3668 * Returns <code>true</code> if <i>hash</i> and <i>other</i> are
3669 * both hashes with the same content.
3670 * The orders of each hashes are not compared.
3671 */
3672
3673static VALUE
3674rb_hash_eql(VALUE hash1, VALUE hash2)
3675{
3676 return hash_equal(hash1, hash2, TRUE);
3677}
3678
3679static int
3680hash_i(VALUE key, VALUE val, VALUE arg)
3681{
3682 st_index_t *hval = (st_index_t *)arg;
3683 st_index_t hdata[2];
3684
3685 hdata[0] = rb_hash(key);
3686 hdata[1] = rb_hash(val);
3687 *hval ^= st_hash(hdata, sizeof(hdata), 0);
3688 return ST_CONTINUE;
3689}
3690
3691/*
3692 * call-seq:
3693 * hsh.hash -> integer
3694 *
3695 * Compute a hash-code for this hash. Two hashes with the same content
3696 * will have the same hash code (and will compare using <code>eql?</code>).
3697 *
3698 * See also Object#hash.
3699 */
3700
3701static VALUE
3702rb_hash_hash(VALUE hash)
3703{
3706 hval = rb_hash_uint(hval, (st_index_t)rb_hash_hash);
3707 if (size) {
3708 rb_hash_foreach(hash, hash_i, (VALUE)&hval);
3709 }
3710 hval = rb_hash_end(hval);
3711 return ST2FIX(hval);
3712}
3713
3714static int
3715rb_hash_invert_i(VALUE key, VALUE value, VALUE hash)
3716{
3717 rb_hash_aset(hash, value, key);
3718 return ST_CONTINUE;
3719}
3720
3721/*
3722 * call-seq:
3723 * hsh.invert -> new_hash
3724 *
3725 * Returns a new hash created by using <i>hsh</i>'s values as keys, and
3726 * the keys as values.
3727 * If a key with the same value already exists in the <i>hsh</i>, then
3728 * the last one defined will be used, the earlier value(s) will be discarded.
3729 *
3730 * h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 }
3731 * h.invert #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"}
3732 *
3733 * If there is no key with the same value, Hash#invert is involutive.
3734 *
3735 * h = { a: 1, b: 3, c: 4 }
3736 * h.invert.invert == h #=> true
3737 *
3738 * The condition, no key with the same value, can be tested by comparing
3739 * the size of inverted hash.
3740 *
3741 * # no key with the same value
3742 * h = { a: 1, b: 3, c: 4 }
3743 * h.size == h.invert.size #=> true
3744 *
3745 * # two (or more) keys has the same value
3746 * h = { a: 1, b: 3, c: 1 }
3747 * h.size == h.invert.size #=> false
3748 *
3749 */
3750
3751static VALUE
3752rb_hash_invert(VALUE hash)
3753{
3755
3756 rb_hash_foreach(hash, rb_hash_invert_i, h);
3757 return h;
3758}
3759
3760static int
3761rb_hash_update_callback(st_data_t *key, st_data_t *value, struct update_arg *arg, int existing)
3762{
3763 if (existing) {
3764 arg->old_value = *value;
3765 arg->new_value = arg->arg;
3766 }
3767 else {
3768 arg->new_key = *key;
3769 arg->new_value = arg->arg;
3770 }
3771 *value = arg->arg;
3772 return ST_CONTINUE;
3773}
3774
3775NOINSERT_UPDATE_CALLBACK(rb_hash_update_callback)
3776
3777static int
3778rb_hash_update_i(VALUE key, VALUE value, VALUE hash)
3779{
3780 RHASH_UPDATE(hash, key, rb_hash_update_callback, value);
3781 return ST_CONTINUE;
3782}
3783
3784static int
3785rb_hash_update_block_callback(st_data_t *key, st_data_t *value, struct update_arg *arg, int existing)
3786{
3787 VALUE newvalue = (VALUE)arg->arg;
3788
3789 if (existing) {
3790 newvalue = rb_yield_values(3, (VALUE)*key, (VALUE)*value, newvalue);
3791 arg->old_value = *value;
3792 }
3793 else {
3794 arg->new_key = *key;
3795 }
3796 arg->new_value = newvalue;
3797 *value = newvalue;
3798 return ST_CONTINUE;
3799}
3800
3801NOINSERT_UPDATE_CALLBACK(rb_hash_update_block_callback)
3802
3803static int
3804rb_hash_update_block_i(VALUE key, VALUE value, VALUE hash)
3805{
3806 RHASH_UPDATE(hash, key, rb_hash_update_block_callback, value);
3807 return ST_CONTINUE;
3808}
3809
3810/*
3811 * call-seq:
3812 * hsh.merge!(other_hash1, other_hash2, ...) -> hsh
3813 * hsh.update(other_hash1, other_hash2, ...) -> hsh
3814 * hsh.merge!(other_hash1, other_hash2, ...) {|key, oldval, newval| block}
3815 * -> hsh
3816 * hsh.update(other_hash1, other_hash2, ...) {|key, oldval, newval| block}
3817 * -> hsh
3818 *
3819 * Adds the contents of the given hashes to the receiver.
3820 *
3821 * If no block is given, entries with duplicate keys are overwritten
3822 * with the values from each +other_hash+ successively,
3823 * otherwise the value for each duplicate key is determined by
3824 * calling the block with the key, its value in the receiver and
3825 * its value in each +other_hash+.
3826 *
3827 * h1 = { "a" => 100, "b" => 200 }
3828 * h1.merge! #=> {"a"=>100, "b"=>200}
3829 * h1 #=> {"a"=>100, "b"=>200}
3830 *
3831 * h1 = { "a" => 100, "b" => 200 }
3832 * h2 = { "b" => 246, "c" => 300 }
3833 * h1.merge!(h2) #=> {"a"=>100, "b"=>246, "c"=>300}
3834 * h1 #=> {"a"=>100, "b"=>246, "c"=>300}
3835 *
3836 * h1 = { "a" => 100, "b" => 200 }
3837 * h2 = { "b" => 246, "c" => 300 }
3838 * h3 = { "b" => 357, "d" => 400 }
3839 * h1.merge!(h2, h3)
3840 * #=> {"a"=>100, "b"=>357, "c"=>300, "d"=>400}
3841 * h1 #=> {"a"=>100, "b"=>357, "c"=>300, "d"=>400}
3842 *
3843 * h1 = { "a" => 100, "b" => 200 }
3844 * h2 = { "b" => 246, "c" => 300 }
3845 * h3 = { "b" => 357, "d" => 400 }
3846 * h1.merge!(h2, h3) {|key, v1, v2| v1 }
3847 * #=> {"a"=>100, "b"=>200, "c"=>300, "d"=>400}
3848 * h1 #=> {"a"=>100, "b"=>200, "c"=>300, "d"=>400}
3849 *
3850 * Hash#update is an alias for Hash#merge!.
3851 */
3852
3853static VALUE
3854rb_hash_update(int argc, VALUE *argv, VALUE self)
3855{
3856 int i;
3857 bool block_given = rb_block_given_p();
3858
3859 rb_hash_modify(self);
3860 for (i = 0; i < argc; i++){
3861 VALUE hash = to_hash(argv[i]);
3862 if (block_given) {
3863 rb_hash_foreach(hash, rb_hash_update_block_i, self);
3864 }
3865 else {
3866 rb_hash_foreach(hash, rb_hash_update_i, self);
3867 }
3868 }
3869 return self;
3870}
3871
3876};
3877
3878static int
3879rb_hash_update_func_callback(st_data_t *key, st_data_t *value, struct update_arg *arg, int existing)
3880{
3881 struct update_func_arg *uf_arg = (struct update_func_arg *)arg->arg;
3882 VALUE newvalue = uf_arg->value;
3883
3884 if (existing) {
3885 newvalue = (*uf_arg->func)((VALUE)*key, (VALUE)*value, newvalue);
3886 arg->old_value = *value;
3887 }
3888 else {
3889 arg->new_key = *key;
3890 }
3891 arg->new_value = newvalue;
3892 *value = newvalue;
3893 return ST_CONTINUE;
3894}
3895
3896NOINSERT_UPDATE_CALLBACK(rb_hash_update_func_callback)
3897
3898static int
3899rb_hash_update_func_i(VALUE key, VALUE value, VALUE arg0)
3900{
3901 struct update_func_arg *arg = (struct update_func_arg *)arg0;
3902 VALUE hash = arg->hash;
3903
3904 arg->value = value;
3905 RHASH_UPDATE(hash, key, rb_hash_update_func_callback, (VALUE)arg);
3906 return ST_CONTINUE;
3907}
3908
3909VALUE
3911{
3912 rb_hash_modify(hash1);
3913 hash2 = to_hash(hash2);
3914 if (func) {
3915 struct update_func_arg arg;
3916 arg.hash = hash1;
3917 arg.func = func;
3918 rb_hash_foreach(hash2, rb_hash_update_func_i, (VALUE)&arg);
3919 }
3920 else {
3921 rb_hash_foreach(hash2, rb_hash_update_i, hash1);
3922 }
3923 return hash1;
3924}
3925
3926/*
3927 * call-seq:
3928 * hsh.merge(other_hash1, other_hash2, ...) -> new_hash
3929 * hsh.merge(other_hash1, other_hash2, ...) {|key, oldval, newval| block}
3930 * -> new_hash
3931 *
3932 * Returns a new hash that combines the contents of the receiver and
3933 * the contents of the given hashes.
3934 *
3935 * If no block is given, entries with duplicate keys are overwritten
3936 * with the values from each +other_hash+ successively,
3937 * otherwise the value for each duplicate key is determined by
3938 * calling the block with the key, its value in the receiver and
3939 * its value in each +other_hash+.
3940 *
3941 * When called without any argument, returns a copy of the receiver.
3942 *
3943 * h1 = { "a" => 100, "b" => 200 }
3944 * h2 = { "b" => 246, "c" => 300 }
3945 * h3 = { "b" => 357, "d" => 400 }
3946 * h1.merge #=> {"a"=>100, "b"=>200}
3947 * h1.merge(h2) #=> {"a"=>100, "b"=>246, "c"=>300}
3948 * h1.merge(h2, h3) #=> {"a"=>100, "b"=>357, "c"=>300, "d"=>400}
3949 * h1.merge(h2) {|key, oldval, newval| newval - oldval}
3950 * #=> {"a"=>100, "b"=>46, "c"=>300}
3951 * h1.merge(h2, h3) {|key, oldval, newval| newval - oldval}
3952 * #=> {"a"=>100, "b"=>311, "c"=>300, "d"=>400}
3953 * h1 #=> {"a"=>100, "b"=>200}
3954 *
3955 */
3956
3957static VALUE
3958rb_hash_merge(int argc, VALUE *argv, VALUE self)
3959{
3960 return rb_hash_update(argc, argv, rb_hash_dup(self));
3961}
3962
3963static int
3964assoc_cmp(VALUE a, VALUE b)
3965{
3966 return !RTEST(rb_equal(a, b));
3967}
3968
3969static VALUE
3970lookup2_call(VALUE arg)
3971{
3972 VALUE *args = (VALUE *)arg;
3973 return rb_hash_lookup2(args[0], args[1], Qundef);
3974}
3975
3978 const struct st_hash_type *orighash;
3979};
3980
3981static VALUE
3982reset_hash_type(VALUE arg)
3983{
3984 struct reset_hash_type_arg *p = (struct reset_hash_type_arg *)arg;
3986 RHASH_ST_TABLE(p->hash)->type = p->orighash;
3987 return Qundef;
3988}
3989
3990static int
3991assoc_i(VALUE key, VALUE val, VALUE arg)
3992{
3993 VALUE *args = (VALUE *)arg;
3994
3995 if (RTEST(rb_equal(args[0], key))) {
3996 args[1] = rb_assoc_new(key, val);
3997 return ST_STOP;
3998 }
3999 return ST_CONTINUE;
4000}
4001
4002/*
4003 * call-seq:
4004 * hash.assoc(obj) -> an_array or nil
4005 *
4006 * Searches through the hash comparing _obj_ with the key using <code>==</code>.
4007 * Returns the key-value pair (two elements array) or +nil+
4008 * if no match is found. See Array#assoc.
4009 *
4010 * h = {"colors" => ["red", "blue", "green"],
4011 * "letters" => ["a", "b", "c" ]}
4012 * h.assoc("letters") #=> ["letters", ["a", "b", "c"]]
4013 * h.assoc("foo") #=> nil
4014 */
4015
4016VALUE
4018{
4019 st_table *table;
4020 const struct st_hash_type *orighash;
4021 VALUE args[2];
4022
4023 if (RHASH_EMPTY_P(hash)) return Qnil;
4024
4025 ar_force_convert_table(hash, __FILE__, __LINE__);
4027 table = RHASH_ST_TABLE(hash);
4028 orighash = table->type;
4029
4030 if (orighash != &identhash) {
4031 VALUE value;
4032 struct reset_hash_type_arg ensure_arg;
4033 struct st_hash_type assochash;
4034
4035 assochash.compare = assoc_cmp;
4036 assochash.hash = orighash->hash;
4037 table->type = &assochash;
4038 args[0] = hash;
4039 args[1] = key;
4040 ensure_arg.hash = hash;
4041 ensure_arg.orighash = orighash;
4042 value = rb_ensure(lookup2_call, (VALUE)&args, reset_hash_type, (VALUE)&ensure_arg);
4043 if (value != Qundef) return rb_assoc_new(key, value);
4044 }
4045
4046 args[0] = key;
4047 args[1] = Qnil;
4048 rb_hash_foreach(hash, assoc_i, (VALUE)args);
4049 return args[1];
4050}
4051
4052static int
4053rassoc_i(VALUE key, VALUE val, VALUE arg)
4054{
4055 VALUE *args = (VALUE *)arg;
4056
4057 if (RTEST(rb_equal(args[0], val))) {
4058 args[1] = rb_assoc_new(key, val);
4059 return ST_STOP;
4060 }
4061 return ST_CONTINUE;
4062}
4063
4064/*
4065 * call-seq:
4066 * hash.rassoc(obj) -> an_array or nil
4067 *
4068 * Searches through the hash comparing _obj_ with the value using <code>==</code>.
4069 * Returns the first key-value pair (two-element array) that matches. See
4070 * also Array#rassoc.
4071 *
4072 * a = {1=> "one", 2 => "two", 3 => "three", "ii" => "two"}
4073 * a.rassoc("two") #=> [2, "two"]
4074 * a.rassoc("four") #=> nil
4075 */
4076
4077VALUE
4079{
4080 VALUE args[2];
4081
4082 args[0] = obj;
4083 args[1] = Qnil;
4084 rb_hash_foreach(hash, rassoc_i, (VALUE)args);
4085 return args[1];
4086}
4087
4088static int
4089flatten_i(VALUE key, VALUE val, VALUE ary)
4090{
4091 VALUE pair[2];
4092
4093 pair[0] = key;
4094 pair[1] = val;
4095 rb_ary_cat(ary, pair, 2);
4096
4097 return ST_CONTINUE;
4098}
4099
4100/*
4101 * call-seq:
4102 * hash.flatten -> an_array
4103 * hash.flatten(level) -> an_array
4104 *
4105 * Returns a new array that is a one-dimensional flattening of this
4106 * hash. That is, for every key or value that is an array, extract
4107 * its elements into the new array. Unlike Array#flatten, this
4108 * method does not flatten recursively by default. The optional
4109 * <i>level</i> argument determines the level of recursion to flatten.
4110 *
4111 * a = {1=> "one", 2 => [2,"two"], 3 => "three"}
4112 * a.flatten # => [1, "one", 2, [2, "two"], 3, "three"]
4113 * a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"]
4114 */
4115
4116static VALUE
4117rb_hash_flatten(int argc, VALUE *argv, VALUE hash)
4118{
4119 VALUE ary;
4120
4121 rb_check_arity(argc, 0, 1);
4122
4123 if (argc) {
4124 int level = NUM2INT(argv[0]);
4125
4126 if (level == 0) return rb_hash_to_a(hash);
4127
4128 ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2);
4129 rb_hash_foreach(hash, flatten_i, ary);
4130 level--;
4131
4132 if (level > 0) {
4133 VALUE ary_flatten_level = INT2FIX(level);
4134 rb_funcallv(ary, id_flatten_bang, 1, &ary_flatten_level);
4135 }
4136 else if (level < 0) {
4137 /* flatten recursively */
4138 rb_funcallv(ary, id_flatten_bang, 0, 0);
4139 }
4140 }
4141 else {
4142 ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2);
4143 rb_hash_foreach(hash, flatten_i, ary);
4144 }
4145
4146 return ary;
4147}
4148
4149static int
4150delete_if_nil(VALUE key, VALUE value, VALUE hash)
4151{
4152 if (NIL_P(value)) {
4153 return ST_DELETE;
4154 }
4155 return ST_CONTINUE;
4156}
4157
4158static int
4159set_if_not_nil(VALUE key, VALUE value, VALUE hash)
4160{
4161 if (!NIL_P(value)) {
4162 rb_hash_aset(hash, key, value);
4163 }
4164 return ST_CONTINUE;
4165}
4166
4167/*
4168 * call-seq:
4169 * hsh.compact -> new_hash
4170 *
4171 * Returns a new hash with the nil values/key pairs removed
4172 *
4173 * h = { a: 1, b: false, c: nil }
4174 * h.compact #=> { a: 1, b: false }
4175 * h #=> { a: 1, b: false, c: nil }
4176 *
4177 */
4178
4179static VALUE
4180rb_hash_compact(VALUE hash)
4181{
4182 VALUE result = rb_hash_new();
4183 if (!RHASH_EMPTY_P(hash)) {
4184 rb_hash_foreach(hash, set_if_not_nil, result);
4185 }
4186 return result;
4187}
4188
4189/*
4190 * call-seq:
4191 * hsh.compact! -> hsh or nil
4192 *
4193 * Removes all nil values from the hash.
4194 * Returns nil if no changes were made, otherwise returns the hash.
4195 *
4196 * h = { a: 1, b: false, c: nil }
4197 * h.compact! #=> { a: 1, b: false }
4198 *
4199 */
4200
4201static VALUE
4202rb_hash_compact_bang(VALUE hash)
4203{
4204 st_index_t n;
4205 rb_hash_modify_check(hash);
4206 n = RHASH_SIZE(hash);
4207 if (n) {
4208 rb_hash_foreach(hash, delete_if_nil, hash);
4209 if (n != RHASH_SIZE(hash))
4210 return hash;
4211 }
4212 return Qnil;
4213}
4214
4215static st_table *rb_init_identtable_with_size(st_index_t size);
4216
4217/*
4218 * call-seq:
4219 * hsh.compare_by_identity -> hsh
4220 *
4221 * Makes <i>hsh</i> compare its keys by their identity, i.e. it
4222 * will consider exact same objects as same keys.
4223 *
4224 * h1 = { "a" => 100, "b" => 200, :c => "c" }
4225 * h1["a"] #=> 100
4226 * h1.compare_by_identity
4227 * h1.compare_by_identity? #=> true
4228 * h1["a".dup] #=> nil # different objects.
4229 * h1[:c] #=> "c" # same symbols are all same.
4230 *
4231 */
4232
4233static VALUE
4234rb_hash_compare_by_id(VALUE hash)
4235{
4236 VALUE tmp;
4237 st_table *identtable;
4238
4239 if (rb_hash_compare_by_id_p(hash)) return hash;
4240
4241 rb_hash_modify_check(hash);
4242 ar_force_convert_table(hash, __FILE__, __LINE__);
4244
4245 tmp = hash_alloc(0);
4246 identtable = rb_init_identtable_with_size(RHASH_SIZE(hash));
4247 RHASH_ST_TABLE_SET(tmp, identtable);
4248 rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
4250 RHASH_ST_TABLE_SET(hash, identtable);
4251 RHASH_ST_CLEAR(tmp);
4253
4254 return hash;
4255}
4256
4257/*
4258 * call-seq:
4259 * hsh.compare_by_identity? -> true or false
4260 *
4261 * Returns <code>true</code> if <i>hsh</i> will compare its keys by
4262 * their identity. Also see Hash#compare_by_identity.
4263 *
4264 */
4265
4268{
4270 return Qtrue;
4271 }
4272 else {
4273 return Qfalse;
4274 }
4275}
4276
4277VALUE
4279{
4282 return hash;
4283}
4284
4285st_table *
4287{
4288 return st_init_table(&identhash);
4289}
4290
4291static st_table *
4292rb_init_identtable_with_size(st_index_t size)
4293{
4295}
4296
4297static int
4298any_p_i(VALUE key, VALUE value, VALUE arg)
4299{
4300 VALUE ret = rb_yield(rb_assoc_new(key, value));
4301 if (RTEST(ret)) {
4302 *(VALUE *)arg = Qtrue;
4303 return ST_STOP;
4304 }
4305 return ST_CONTINUE;
4306}
4307
4308static int
4309any_p_i_fast(VALUE key, VALUE value, VALUE arg)
4310{
4311 VALUE ret = rb_yield_values(2, key, value);
4312 if (RTEST(ret)) {
4313 *(VALUE *)arg = Qtrue;
4314 return ST_STOP;
4315 }
4316 return ST_CONTINUE;
4317}
4318
4319static int
4320any_p_i_pattern(VALUE key, VALUE value, VALUE arg)
4321{
4322 VALUE ret = rb_funcall(((VALUE *)arg)[1], idEqq, 1, rb_assoc_new(key, value));
4323 if (RTEST(ret)) {
4324 *(VALUE *)arg = Qtrue;
4325 return ST_STOP;
4326 }
4327 return ST_CONTINUE;
4328}
4329
4330/*
4331 * call-seq:
4332 * hsh.any? [{ |(key, value)| block }] -> true or false
4333 * hsh.any?(pattern) -> true or false
4334 *
4335 * See also Enumerable#any?
4336 */
4337
4338static VALUE
4339rb_hash_any_p(int argc, VALUE *argv, VALUE hash)
4340{
4341 VALUE args[2];
4342 args[0] = Qfalse;
4343
4344 rb_check_arity(argc, 0, 1);
4345 if (RHASH_EMPTY_P(hash)) return Qfalse;
4346 if (argc) {
4347 if (rb_block_given_p()) {
4348 rb_warn("given block not used");
4349 }
4350 args[1] = argv[0];
4351
4352 rb_hash_foreach(hash, any_p_i_pattern, (VALUE)args);
4353 }
4354 else {
4355 if (!rb_block_given_p()) {
4356 /* yields pairs, never false */
4357 return Qtrue;
4358 }
4359 if (rb_block_arity() > 1)
4360 rb_hash_foreach(hash, any_p_i_fast, (VALUE)args);
4361 else
4362 rb_hash_foreach(hash, any_p_i, (VALUE)args);
4363 }
4364 return args[0];
4365}
4366
4367/*
4368 * call-seq:
4369 * hsh.dig(key, ...) -> object
4370 *
4371 * Extracts the nested value specified by the sequence of <i>key</i>
4372 * objects by calling +dig+ at each step, returning +nil+ if any
4373 * intermediate step is +nil+.
4374 *
4375 * h = { foo: {bar: {baz: 1}}}
4376 *
4377 * h.dig(:foo, :bar, :baz) #=> 1
4378 * h.dig(:foo, :zot, :xyz) #=> nil
4379 *
4380 * g = { foo: [10, 11, 12] }
4381 * g.dig(:foo, 1) #=> 11
4382 * g.dig(:foo, 1, 0) #=> TypeError: Integer does not have #dig method
4383 * g.dig(:foo, :bar) #=> TypeError: no implicit conversion of Symbol into Integer
4384 */
4385
4386static VALUE
4387rb_hash_dig(int argc, VALUE *argv, VALUE self)
4388{
4390 self = rb_hash_aref(self, *argv);
4391 if (!--argc) return self;
4392 ++argv;
4393 return rb_obj_dig(argc, argv, self, Qnil);
4394}
4395
4396static int
4397hash_le_i(VALUE key, VALUE value, VALUE arg)
4398{
4399 VALUE *args = (VALUE *)arg;
4400 VALUE v = rb_hash_lookup2(args[0], key, Qundef);
4401 if (v != Qundef && rb_equal(value, v)) return ST_CONTINUE;
4402 args[1] = Qfalse;
4403 return ST_STOP;
4404}
4405
4406static VALUE
4407hash_le(VALUE hash1, VALUE hash2)
4408{
4409 VALUE args[2];
4410 args[0] = hash2;
4411 args[1] = Qtrue;
4412 rb_hash_foreach(hash1, hash_le_i, (VALUE)args);
4413 return args[1];
4414}
4415
4416/*
4417 * call-seq:
4418 * hash <= other -> true or false
4419 *
4420 * Returns <code>true</code> if <i>hash</i> is subset of
4421 * <i>other</i> or equals to <i>other</i>.
4422 *
4423 * h1 = {a:1, b:2}
4424 * h2 = {a:1, b:2, c:3}
4425 * h1 <= h2 #=> true
4426 * h2 <= h1 #=> false
4427 * h1 <= h1 #=> true
4428 */
4429static VALUE
4430rb_hash_le(VALUE hash, VALUE other)
4431{
4432 other = to_hash(other);
4433 if (RHASH_SIZE(hash) > RHASH_SIZE(other)) return Qfalse;
4434 return hash_le(hash, other);
4435}
4436
4437/*
4438 * call-seq:
4439 * hash < other -> true or false
4440 *
4441 * Returns <code>true</code> if <i>hash</i> is subset of
4442 * <i>other</i>.
4443 *
4444 * h1 = {a:1, b:2}
4445 * h2 = {a:1, b:2, c:3}
4446 * h1 < h2 #=> true
4447 * h2 < h1 #=> false
4448 * h1 < h1 #=> false
4449 */
4450static VALUE
4451rb_hash_lt(VALUE hash, VALUE other)
4452{
4453 other = to_hash(other);
4454 if (RHASH_SIZE(hash) >= RHASH_SIZE(other)) return Qfalse;
4455 return hash_le(hash, other);
4456}
4457
4458/*
4459 * call-seq:
4460 * hash >= other -> true or false
4461 *
4462 * Returns <code>true</code> if <i>other</i> is subset of
4463 * <i>hash</i> or equals to <i>hash</i>.
4464 *
4465 * h1 = {a:1, b:2}
4466 * h2 = {a:1, b:2, c:3}
4467 * h1 >= h2 #=> false
4468 * h2 >= h1 #=> true
4469 * h1 >= h1 #=> true
4470 */
4471static VALUE
4472rb_hash_ge(VALUE hash, VALUE other)
4473{
4474 other = to_hash(other);
4475 if (RHASH_SIZE(hash) < RHASH_SIZE(other)) return Qfalse;
4476 return hash_le(other, hash);
4477}
4478
4479/*
4480 * call-seq:
4481 * hash > other -> true or false
4482 *
4483 * Returns <code>true</code> if <i>other</i> is subset of
4484 * <i>hash</i>.
4485 *
4486 * h1 = {a:1, b:2}
4487 * h2 = {a:1, b:2, c:3}
4488 * h1 > h2 #=> false
4489 * h2 > h1 #=> true
4490 * h1 > h1 #=> false
4491 */
4492static VALUE
4493rb_hash_gt(VALUE hash, VALUE other)
4494{
4495 other = to_hash(other);
4496 if (RHASH_SIZE(hash) <= RHASH_SIZE(other)) return Qfalse;
4497 return hash_le(other, hash);
4498}
4499
4500static VALUE
4501hash_proc_call(RB_BLOCK_CALL_FUNC_ARGLIST(key, hash))
4502{
4503 rb_check_arity(argc, 1, 1);
4504 return rb_hash_aref(hash, *argv);
4505}
4506
4507/*
4508 * call-seq:
4509 * hash.to_proc -> proc
4510 *
4511 * Returns a Proc which maps keys to values.
4512 *
4513 * h = {a:1, b:2}
4514 * hp = h.to_proc
4515 * hp.call(:a) #=> 1
4516 * hp.call(:b) #=> 2
4517 * hp.call(:c) #=> nil
4518 * [:a, :b, :c].map(&h) #=> [1, 2, nil]
4519 */
4520static VALUE
4521rb_hash_to_proc(VALUE hash)
4522{
4523 return rb_func_proc_new(hash_proc_call, hash);
4524}
4525
4526static VALUE
4527rb_hash_deconstruct_keys(VALUE hash, VALUE keys)
4528{
4529 return hash;
4530}
4531
4532static int
4533add_new_i(st_data_t *key, st_data_t *val, st_data_t arg, int existing)
4534{
4535 VALUE *args = (VALUE *)arg;
4536 if (existing) return ST_STOP;
4537 RB_OBJ_WRITTEN(args[0], Qundef, (VALUE)*key);
4538 RB_OBJ_WRITE(args[0], (VALUE *)val, args[1]);
4539 return ST_CONTINUE;
4540}
4541
4542/*
4543 * add +key+ to +val+ pair if +hash+ does not contain +key+.
4544 * returns non-zero if +key+ was contained.
4545 */
4546int
4548{
4549 st_table *tbl;
4550 int ret = 0;
4551 VALUE args[2];
4552 args[0] = hash;
4553 args[1] = val;
4554
4555 if (RHASH_AR_TABLE_P(hash)) {
4556 hash_ar_table(hash);
4557
4558 ret = ar_update(hash, (st_data_t)key, add_new_i, (st_data_t)args);
4559 if (ret != -1) {
4560 return ret;
4561 }
4562 ar_try_convert_table(hash);
4563 }
4564 tbl = RHASH_TBL_RAW(hash);
4565 return st_update(tbl, (st_data_t)key, add_new_i, (st_data_t)args);
4566
4567}
4568
4569static st_data_t
4570key_stringify(VALUE key)
4571{
4572 return (rb_obj_class(key) == rb_cString && !RB_OBJ_FROZEN(key)) ?
4574}
4575
4576static void
4577ar_bulk_insert(VALUE hash, long argc, const VALUE *argv)
4578{
4579 long i;
4580 for (i = 0; i < argc; ) {
4581 st_data_t k = key_stringify(argv[i++]);
4582 st_data_t v = argv[i++];
4583 ar_insert(hash, k, v);
4586 }
4587}
4588
4589void
4591{
4592 HASH_ASSERT(argc % 2 == 0);
4593 if (argc > 0) {
4594 st_index_t size = argc / 2;
4595
4596 if (RHASH_TABLE_NULL_P(hash)) {
4598 hash_ar_table(hash);
4599 }
4600 else {
4602 }
4603 }
4604
4605 if (RHASH_AR_TABLE_P(hash) &&
4607 ar_bulk_insert(hash, argc, argv);
4608 }
4609 else {
4611 }
4612 }
4613}
4614
4615static char **origenviron;
4616#ifdef _WIN32
4617#define GET_ENVIRON(e) ((e) = rb_w32_get_environ())
4618#define FREE_ENVIRON(e) rb_w32_free_environ(e)
4619static char **my_environ;
4620#undef environ
4621#define environ my_environ
4622#undef getenv
4623static char *(*w32_getenv)(const char*);
4624static char *
4625w32_getenv_unknown(const char *name)
4626{
4627 char *(*func)(const char*);
4629 func = rb_w32_getenv;
4630 }
4631 else {
4632 func = rb_w32_ugetenv;
4633 }
4634 /* atomic assignment in flat memory model */
4635 return (w32_getenv = func)(name);
4636}
4637static char *(*w32_getenv)(const char*) = w32_getenv_unknown;
4638#define getenv(n) w32_getenv(n)
4639#elif defined(__APPLE__)
4640#undef environ
4641#define environ (*_NSGetEnviron())
4642#define GET_ENVIRON(e) (e)
4643#define FREE_ENVIRON(e)
4644#else
4645extern char **environ;
4646#define GET_ENVIRON(e) (e)
4647#define FREE_ENVIRON(e)
4648#endif
4649#ifdef ENV_IGNORECASE
4650#define ENVMATCH(s1, s2) (STRCASECMP((s1), (s2)) == 0)
4651#define ENVNMATCH(s1, s2, n) (STRNCASECMP((s1), (s2), (n)) == 0)
4652#else
4653#define ENVMATCH(n1, n2) (strcmp((n1), (n2)) == 0)
4654#define ENVNMATCH(s1, s2, n) (memcmp((s1), (s2), (n)) == 0)
4655#endif
4656
4657static VALUE
4658env_enc_str_new(const char *ptr, long len, rb_encoding *enc)
4659{
4660#ifdef _WIN32
4662 const int ecflags = ECONV_INVALID_REPLACE | ECONV_UNDEF_REPLACE;
4663 rb_encoding *utf8 = rb_utf8_encoding();
4664 VALUE str = rb_enc_str_new(NULL, 0, (internal ? internal : enc));
4665 if (NIL_P(rb_str_cat_conv_enc_opts(str, 0, ptr, len, utf8, ecflags, Qnil))) {
4667 }
4668#else
4670#endif
4671
4673 return str;
4674}
4675
4676static VALUE
4677env_enc_str_new_cstr(const char *ptr, rb_encoding *enc)
4678{
4679 return env_enc_str_new(ptr, strlen(ptr), enc);
4680}
4681
4682static VALUE
4683env_str_new(const char *ptr, long len)
4684{
4685 return env_enc_str_new(ptr, len, rb_locale_encoding());
4686}
4687
4688static VALUE
4689env_str_new2(const char *ptr)
4690{
4691 if (!ptr) return Qnil;
4692 return env_str_new(ptr, strlen(ptr));
4693}
4694
4695static const char TZ_ENV[] = "TZ";
4696extern bool ruby_tz_uptodate_p;
4697
4698static rb_encoding *
4699env_encoding_for(const char *name, const char *ptr)
4700{
4701 if (ENVMATCH(name, PATH_ENV)) {
4702 return rb_filesystem_encoding();
4703 }
4704 else {
4705 return rb_locale_encoding();
4706 }
4707}
4708
4709static VALUE
4710env_name_new(const char *name, const char *ptr)
4711{
4712 return env_enc_str_new_cstr(ptr, env_encoding_for(name, ptr));
4713}
4714
4715static void *
4716get_env_cstr(
4717#ifdef _WIN32
4718 volatile VALUE *pstr,
4719#else
4720 VALUE str,
4721#endif
4722 const char *name)
4723{
4724#ifdef _WIN32
4725 VALUE str = *pstr;
4726#endif
4727 char *var;
4728 rb_encoding *enc = rb_enc_get(str);
4729 if (!rb_enc_asciicompat(enc)) {
4730 rb_raise(rb_eArgError, "bad environment variable %s: ASCII incompatible encoding: %s",
4731 name, rb_enc_name(enc));
4732 }
4733#ifdef _WIN32
4736 }
4737#endif
4738 var = RSTRING_PTR(str);
4739 if (memchr(var, '\0', RSTRING_LEN(str))) {
4740 rb_raise(rb_eArgError, "bad environment variable %s: contains null byte", name);
4741 }
4742 return rb_str_fill_terminator(str, 1); /* ASCII compatible */
4743}
4744
4745#ifdef _WIN32
4746#define get_env_ptr(var, val) \
4747 (var = get_env_cstr(&(val), #var))
4748#else
4749#define get_env_ptr(var, val) \
4750 (var = get_env_cstr(val, #var))
4751#endif
4752
4753static inline const char *
4754env_name(volatile VALUE *s)
4755{
4756 const char *name;
4757 SafeStringValue(*s);
4758 get_env_ptr(name, *s);
4759 return name;
4760}
4761
4762#define env_name(s) env_name(&(s))
4763
4764static VALUE env_aset(VALUE nm, VALUE val);
4765
4766static VALUE
4767env_delete(VALUE name)
4768{
4769 const char *nam, *val;
4770
4771 nam = env_name(name);
4772 val = getenv(nam);
4773
4774 /*
4775 * ENV['TZ'] = nil has a special meaning.
4776 * TZ is no longer considered up-to-date and ruby call tzset() as needed.
4777 * It could be useful if sysadmin change /etc/localtime.
4778 * This hack might works only on Linux glibc.
4779 */
4780 if (ENVMATCH(nam, TZ_ENV)) {
4782 }
4783
4784 if (val) {
4785 VALUE value = env_str_new2(val);
4786
4787 ruby_setenv(nam, 0);
4788 if (ENVMATCH(nam, PATH_ENV)) {
4790 }
4791 return value;
4792 }
4793 return Qnil;
4794}
4795
4796/*
4797 * call-seq:
4798 * ENV.delete(name) -> value
4799 * ENV.delete(name) { |name| block } -> value
4800 *
4801 * Deletes the environment variable with +name+ if it exists and returns its value:
4802 * ENV['foo'] = '0'
4803 * ENV.delete('foo') # => '0'
4804 * Returns +nil+ if the named environment variable does not exist:
4805 * ENV.delete('foo') # => nil
4806 * If a block given and the environment variable does not exist,
4807 * yields +name+ to the block and returns +nil+:
4808 * ENV.delete('foo') { |name| puts name } # => nil
4809 * foo
4810 * If a block given and the environment variable exists,
4811 * deletes the environment variable and returns its value (ignoring the block):
4812 * ENV['foo'] = '0'
4813 * ENV.delete('foo') { |name| fail 'ignored' } # => "0"
4814 * Raises an exception if +name+ is invalid.
4815 * See {Invalid Names and Values}[#class-ENV-label-Invalid-Names+and+Values].
4816 */
4817static VALUE
4818env_delete_m(VALUE obj, VALUE name)
4819{
4820 VALUE val;
4821
4822 val = env_delete(name);
4823 if (NIL_P(val) && rb_block_given_p()) rb_yield(name);
4824 return val;
4825}
4826
4827/*
4828 * call-seq:
4829 * ENV[name] -> value
4830 *
4831 * Returns the value for the environment variable +name+ if it exists:
4832 * ENV['foo'] = '0'
4833 * ENV['foo'] # => "0"
4834 * Returns nil if the named variable does not exist:
4835 * ENV.clear
4836 * ENV['foo'] # => nil
4837 * Raises an exception if +name+ is invalid.
4838 * See {Invalid Names and Values}[#class-ENV-label-Invalid-Names+and+Values].
4839 */
4840static VALUE
4841rb_f_getenv(VALUE obj, VALUE name)
4842{
4843 const char *nam, *env;
4844
4845 nam = env_name(name);
4846 env = getenv(nam);
4847 if (env) {
4848 return env_name_new(nam, env);
4849 }
4850 return Qnil;
4851}
4852
4853/*
4854 * call-seq:
4855 * ENV.fetch(name) -> value
4856 * ENV.fetch(name, default) -> value
4857 * ENV.fetch(name) { |name| block } -> value
4858 *
4859 * If +name+ is the name of an environment variable, returns its value:
4860 * ENV['foo'] = '0'
4861 * ENV.fetch('foo') # => '0'
4862 * Otherwise if a block is given (but not a default value),
4863 * yields +name+ to the block and returns the block's return value:
4864 * ENV.fetch('foo') { |name| :need_not_return_a_string } # => :need_not_return_a_string
4865 * Otherwise if a default value is given (but not a block), returns the default value:
4866 * ENV.delete('foo')
4867 * ENV.fetch('foo', :default_need_not_be_a_string) # => :default_need_not_be_a_string
4868 * If the environment variable does not exist and both default and block are given,
4869 * issues a warning ("warning: block supersedes default value argument"),
4870 * yields +name+ to the block, and returns the block's return value:
4871 * ENV.fetch('foo', :default) { |name| :block_return } # => :block_return
4872 * Raises KeyError if +name+ is valid, but not found,
4873 * and neither default value nor block is given:
4874 * ENV.fetch('foo') # Raises KeyError (key not found: "foo")
4875 * Raises an exception if +name+ is invalid.
4876 * See {Invalid Names and Values}[#class-ENV-label-Invalid-Names+and+Values].
4877 */
4878static VALUE
4879env_fetch(int argc, VALUE *argv, VALUE _)
4880{
4881 VALUE key;
4882 long block_given;
4883 const char *nam, *env;
4884
4885 rb_check_arity(argc, 1, 2);
4886 key = argv[0];
4887 block_given = rb_block_given_p();
4888 if (block_given && argc == 2) {
4889 rb_warn("block supersedes default value argument");
4890 }
4891 nam = env_name(key);
4892 env = getenv(nam);
4893 if (!env) {
4894 if (block_given) return rb_yield(key);
4895 if (argc == 1) {
4896 rb_key_err_raise(rb_sprintf("key not found: \"%"PRIsVALUE"\"", key), envtbl, key);
4897 }
4898 return argv[1];
4899 }
4900 return env_name_new(nam, env);
4901}
4902
4903int
4905{
4906 rb_warning("rb_env_path_tainted is deprecated and will be removed in Ruby 3.2.");
4907 return 0;
4908}
4909
4910#if defined(_WIN32) || (defined(HAVE_SETENV) && defined(HAVE_UNSETENV))
4911#elif defined __sun
4912static int
4913in_origenv(const char *str)
4914{
4915 char **env;
4916 for (env = origenviron; *env; ++env) {
4917 if (*env == str) return 1;
4918 }
4919 return 0;
4920}
4921#else
4922static int
4923envix(const char *nam)
4924{
4925 register int i, len = strlen(nam);
4926 char **env;
4927
4929 for (i = 0; env[i]; i++) {
4930 if (ENVNMATCH(env[i],nam,len) && env[i][len] == '=')
4931 break; /* memcmp must come first to avoid */
4932 } /* potential SEGV's */
4934 return i;
4935}
4936#endif
4937
4938#if defined(_WIN32)
4939static size_t
4940getenvsize(const WCHAR* p)
4941{
4942 const WCHAR* porg = p;
4943 while (*p++) p += lstrlenW(p) + 1;
4944 return p - porg + 1;
4945}
4946
4947static size_t
4948getenvblocksize(void)
4949{
4950#ifdef _MAX_ENV
4951 return _MAX_ENV;
4952#else
4953 return 32767;
4954#endif
4955}
4956
4957static int
4958check_envsize(size_t n)
4959{
4960 if (_WIN32_WINNT < 0x0600 && rb_w32_osver() < 6) {
4961 /* https://msdn.microsoft.com/en-us/library/windows/desktop/ms682653(v=vs.85).aspx */
4962 /* Windows Server 2003 and Windows XP: The maximum size of the
4963 * environment block for the process is 32,767 characters. */
4964 WCHAR* p = GetEnvironmentStringsW();
4965 if (!p) return -1; /* never happen */
4966 n += getenvsize(p);
4967 FreeEnvironmentStringsW(p);
4968 if (n >= getenvblocksize()) {
4969 return -1;
4970 }
4971 }
4972 return 0;
4973}
4974#endif
4975
4976#if defined(_WIN32) || \
4977 (defined(__sun) && !(defined(HAVE_SETENV) && defined(HAVE_UNSETENV)))
4978
4979NORETURN(static void invalid_envname(const char *name));
4980
4981static void
4982invalid_envname(const char *name)
4983{
4984 rb_syserr_fail_str(EINVAL, rb_sprintf("ruby_setenv(%s)", name));
4985}
4986
4987static const char *
4988check_envname(const char *name)
4989{
4990 if (strchr(name, '=')) {
4991 invalid_envname(name);
4992 }
4993 return name;
4994}
4995#endif
4996
4997void
4998ruby_setenv(const char *name, const char *value)
4999{
5000#if defined(_WIN32)
5001# if defined(MINGW_HAS_SECURE_API) || RUBY_MSVCRT_VERSION >= 80
5002# define HAVE__WPUTENV_S 1
5003# endif
5004 VALUE buf;
5005 WCHAR *wname;
5006 WCHAR *wvalue = 0;
5007 int failed = 0;
5008 int len;
5009 check_envname(name);
5010 len = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0);
5011 if (value) {
5012 int len2;
5013 len2 = MultiByteToWideChar(CP_UTF8, 0, value, -1, NULL, 0);
5014 if (check_envsize((size_t)len + len2)) { /* len and len2 include '\0' */
5015 goto fail; /* 2 for '=' & '\0' */
5016 }
5017 wname = ALLOCV_N(WCHAR, buf, len + len2);
5018 wvalue = wname + len;
5019 MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, len);
5020 MultiByteToWideChar(CP_UTF8, 0, value, -1, wvalue, len2);
5021#ifndef HAVE__WPUTENV_S
5022 wname[len-1] = L'=';
5023#endif
5024 }
5025 else {
5026 wname = ALLOCV_N(WCHAR, buf, len + 1);
5027 MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, len);
5028 wvalue = wname + len;
5029 *wvalue = L'\0';
5030#ifndef HAVE__WPUTENV_S
5031 wname[len-1] = L'=';
5032#endif
5033 }
5034#ifndef HAVE__WPUTENV_S
5035 failed = _wputenv(wname);
5036#else
5037 failed = _wputenv_s(wname, wvalue);
5038#endif
5039 ALLOCV_END(buf);
5040 /* even if putenv() failed, clean up and try to delete the
5041 * variable from the system area. */
5042 if (!value || !*value) {
5043 /* putenv() doesn't handle empty value */
5044 if (!SetEnvironmentVariable(name, value) &&
5045 GetLastError() != ERROR_ENVVAR_NOT_FOUND) goto fail;
5046 }
5047 if (failed) {
5048 fail:
5049 invalid_envname(name);
5050 }
5051#elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)
5052 if (value) {
5053 if (setenv(name, value, 1))
5054 rb_sys_fail_str(rb_sprintf("setenv(%s)", name));
5055 }
5056 else {
5057#ifdef VOID_UNSETENV
5058 unsetenv(name);
5059#else
5060 if (unsetenv(name))
5061 rb_sys_fail_str(rb_sprintf("unsetenv(%s)", name));
5062#endif
5063 }
5064#elif defined __sun
5065 /* Solaris 9 (or earlier) does not have setenv(3C) and unsetenv(3C). */
5066 /* The below code was tested on Solaris 10 by:
5067 % ./configure ac_cv_func_setenv=no ac_cv_func_unsetenv=no
5068 */
5069 size_t len, mem_size;
5070 char **env_ptr, *str, *mem_ptr;
5071
5072 check_envname(name);
5073 len = strlen(name);
5074 if (value) {
5075 mem_size = len + strlen(value) + 2;
5076 mem_ptr = malloc(mem_size);
5077 if (mem_ptr == NULL)
5078 rb_sys_fail_str(rb_sprintf("malloc("PRIuSIZE")", mem_size));
5079 snprintf(mem_ptr, mem_size, "%s=%s", name, value);
5080 }
5081 for (env_ptr = GET_ENVIRON(environ); (str = *env_ptr) != 0; ++env_ptr) {
5082 if (!strncmp(str, name, len) && str[len] == '=') {
5083 if (!in_origenv(str)) free(str);
5084 while ((env_ptr[0] = env_ptr[1]) != 0) env_ptr++;
5085 break;
5086 }
5087 }
5088 if (value) {
5089 if (putenv(mem_ptr)) {
5090 free(mem_ptr);
5091 rb_sys_fail_str(rb_sprintf("putenv(%s)", name));
5092 }
5093 }
5094#else /* WIN32 */
5095 size_t len;
5096 int i;
5097
5098 i=envix(name); /* where does it go? */
5099
5100 if (environ == origenviron) { /* need we copy environment? */
5101 int j;
5102 int max;
5103 char **tmpenv;
5104
5105 for (max = i; environ[max]; max++) ;
5106 tmpenv = ALLOC_N(char*, max+2);
5107 for (j=0; j<max; j++) /* copy environment */
5108 tmpenv[j] = ruby_strdup(environ[j]);
5109 tmpenv[max] = 0;
5110 environ = tmpenv; /* tell exec where it is now */
5111 }
5112 if (environ[i]) {
5113 char **envp = origenviron;
5114 while (*envp && *envp != environ[i]) envp++;
5115 if (!*envp)
5116 xfree(environ[i]);
5117 if (!value) {
5118 while (environ[i]) {
5119 environ[i] = environ[i+1];
5120 i++;
5121 }
5122 return;
5123 }
5124 }
5125 else { /* does not exist yet */
5126 if (!value) return;
5127 REALLOC_N(environ, char*, i+2); /* just expand it a bit */
5128 environ[i+1] = 0; /* make sure it's null terminated */
5129 }
5130 len = strlen(name) + strlen(value) + 2;
5131 environ[i] = ALLOC_N(char, len);
5132 snprintf(environ[i],len,"%s=%s",name,value); /* all that work just for this */
5133#endif /* WIN32 */
5134}
5135
5136void
5138{
5139 ruby_setenv(name, 0);
5140}
5141
5142/*
5143 * call-seq:
5144 * ENV[name] = value -> value
5145 * ENV.store(name, value) -> value
5146 *
5147 * ENV.store is an alias for ENV.[]=.
5148 *
5149 * Creates, updates, or deletes the named environment variable, returning the value.
5150 * Both +name+ and +value+ may be instances of String.
5151 * See {Valid Names and Values}[#class-ENV-label-Valid+Names+and+Values].
5152 *
5153 * - If the named environment variable does not exist:
5154 * - If +value+ is +nil+, does nothing.
5155 * ENV.clear
5156 * ENV['foo'] = nil # => nil
5157 * ENV.include?('foo') # => false
5158 * ENV.store('bar', nil) # => nil
5159 * ENV.include?('bar') # => false
5160 * - If +value+ is not +nil+, creates the environment variable with +name+ and +value+:
5161 * # Create 'foo' using ENV.[]=.
5162 * ENV['foo'] = '0' # => '0'
5163 * ENV['foo'] # => '0'
5164 * # Create 'bar' using ENV.store.
5165 * ENV.store('bar', '1') # => '1'
5166 * ENV['bar'] # => '1'
5167 * - If the named environment variable exists:
5168 * - If +value+ is not +nil+, updates the environment variable with value +value+:
5169 * # Update 'foo' using ENV.[]=.
5170 * ENV['foo'] = '2' # => '2'
5171 * ENV['foo'] # => '2'
5172 * # Update 'bar' using ENV.store.
5173 * ENV.store('bar', '3') # => '3'
5174 * ENV['bar'] # => '3'
5175 * - If +value+ is +nil+, deletes the environment variable:
5176 * # Delete 'foo' using ENV.[]=.
5177 * ENV['foo'] = nil # => nil
5178 * ENV.include?('foo') # => false
5179 * # Delete 'bar' using ENV.store.
5180 * ENV.store('bar', nil) # => nil
5181 * ENV.include?('bar') # => false
5182 *
5183 * Raises an exception if +name+ or +value+ is invalid.
5184 * See {Invalid Names and Values}[#class-ENV-label-Invalid+Names+and+Values].
5185 */
5186static VALUE
5187env_aset_m(VALUE obj, VALUE nm, VALUE val)
5188{
5189 return env_aset(nm, val);
5190}
5191
5192static VALUE
5193env_aset(VALUE nm, VALUE val)
5194{
5195 char *name, *value;
5196
5197 if (NIL_P(val)) {
5198 env_delete(nm);
5199 return Qnil;
5200 }
5201 SafeStringValue(nm);
5202 SafeStringValue(val);
5203 /* nm can be modified in `val.to_str`, don't get `name` before
5204 * check for `val` */
5205 get_env_ptr(name, nm);
5206 get_env_ptr(value, val);
5207
5208 ruby_setenv(name, value);
5209 if (ENVMATCH(name, PATH_ENV)) {
5210 RB_GC_GUARD(nm);
5211 }
5212 else if (ENVMATCH(name, TZ_ENV)) {
5214 }
5215 return val;
5216}
5217
5218static VALUE
5219env_keys(void)
5220{
5221 char **env;
5222 VALUE ary;
5223
5224 ary = rb_ary_new();
5226 while (*env) {
5227 char *s = strchr(*env, '=');
5228 if (s) {
5229 rb_ary_push(ary, env_str_new(*env, s-*env));
5230 }
5231 env++;
5232 }
5234 return ary;
5235}
5236
5237/*
5238 * call-seq:
5239 * ENV.keys -> Array
5240 *
5241 * Returns all variable names in an Array:
5242 * ENV.replace('foo' => '0', 'bar' => '1')
5243 * ENV.keys # => ['bar', 'foo']
5244 * The order of the names is OS-dependent.
5245 * See {About Ordering}[#class-ENV-label-About+Ordering].
5246 *
5247 * Returns the empty Array if ENV is empty:
5248 * ENV.clear
5249 * ENV.keys # => []
5250 */
5251
5252static VALUE
5253env_f_keys(VALUE _)
5254{
5255 return env_keys();
5256}
5257
5258static VALUE
5259rb_env_size(VALUE ehash, VALUE args, VALUE eobj)
5260{
5261 char **env;
5262 long cnt = 0;
5263
5265 for (; *env ; ++env) {
5266 if (strchr(*env, '=')) {
5267 cnt++;
5268 }
5269 }
5271 return LONG2FIX(cnt);
5272}
5273
5274/*
5275 * call-seq:
5276 * ENV.each_key { |name| block } -> ENV
5277 * ENV.each_key -> Enumerator
5278 *
5279 * Yields each environment variable name:
5280 * ENV.replace('foo' => '0', 'bar' => '1') # => ENV
5281 * names = []
5282 * ENV.each_key { |name| names.push(name) } # => ENV
5283 * names # => ["bar", "foo"]
5284 *
5285 * Returns an Enumerator if no block given:
5286 * e = ENV.each_key # => #<Enumerator: {"bar"=>"1", "foo"=>"0"}:each_key>
5287 * names = []
5288 * e.each { |name| names.push(name) } # => ENV
5289 * names # => ["bar", "foo"]
5290 */
5291static VALUE
5292env_each_key(VALUE ehash)
5293{
5294 VALUE keys;
5295 long i;
5296
5297 RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5298 keys = env_keys();
5299 for (i=0; i<RARRAY_LEN(keys); i++) {
5301 }
5302 return ehash;
5303}
5304
5305static VALUE
5306env_values(void)
5307{
5308 VALUE ary;
5309 char **env;
5310
5311 ary = rb_ary_new();
5313 while (*env) {
5314 char *s = strchr(*env, '=');
5315 if (s) {
5316 rb_ary_push(ary, env_str_new2(s+1));
5317 }
5318 env++;
5319 }
5321 return ary;
5322}
5323
5324/*
5325 * call-seq:
5326 * ENV.values -> Array
5327 *
5328 * Returns all environment variable values in an Array:
5329 * ENV.replace('foo' => '0', 'bar' => '1')
5330 * ENV.values # => ['1', '0']
5331 * The order of the values is OS-dependent.
5332 * See {About Ordering}[#class-ENV-label-About+Ordering].
5333 *
5334 * Returns the empty Array if ENV is empty:
5335 * ENV.clear
5336 * ENV.values # => []
5337 */
5338static VALUE
5339env_f_values(VALUE _)
5340{
5341 return env_values();
5342}
5343
5344/*
5345 * call-seq:
5346 * ENV.each_value { |value| block } -> ENV
5347 * ENV.each_value -> Enumerator
5348 *
5349 * Yields each environment variable value:
5350 * ENV.replace('foo' => '0', 'bar' => '1') # => ENV
5351 * values = []
5352 * ENV.each_value { |value| values.push(value) } # => ENV
5353 * values # => ["1", "0"]
5354 *
5355 * Returns an Enumerator if no block given:
5356 * e = ENV.each_value # => #<Enumerator: {"bar"=>"1", "foo"=>"0"}:each_value>
5357 * values = []
5358 * e.each { |value| values.push(value) } # => ENV
5359 * values # => ["1", "0"]
5360 */
5361static VALUE
5362env_each_value(VALUE ehash)
5363{
5364 VALUE values;
5365 long i;
5366
5367 RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5368 values = env_values();
5369 for (i=0; i<RARRAY_LEN(values); i++) {
5370 rb_yield(RARRAY_AREF(values, i));
5371 }
5372 return ehash;
5373}
5374
5375/*
5376 * call-seq:
5377 * ENV.each { |name, value| block } -> ENV
5378 * ENV.each -> Enumerator
5379 * ENV.each_pair { |name, value| block } -> ENV
5380 * ENV.each_pair -> Enumerator
5381 *
5382 * Yields each environment variable name and its value as a 2-element Array:
5383 * h = {}
5384 * ENV.each_pair { |name, value| h[name] = value } # => ENV
5385 * h # => {"bar"=>"1", "foo"=>"0"}
5386 *
5387 * Returns an Enumerator if no block given:
5388 * h = {}
5389 * e = ENV.each_pair # => #<Enumerator: {"bar"=>"1", "foo"=>"0"}:each_pair>
5390 * e.each { |name, value| h[name] = value } # => ENV
5391 * h # => {"bar"=>"1", "foo"=>"0"}
5392 */
5393static VALUE
5394env_each_pair(VALUE ehash)
5395{
5396 char **env;
5397 VALUE ary;
5398 long i;
5399
5400 RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5401
5402 ary = rb_ary_new();
5404 while (*env) {
5405 char *s = strchr(*env, '=');
5406 if (s) {
5407 rb_ary_push(ary, env_str_new(*env, s-*env));
5408 rb_ary_push(ary, env_str_new2(s+1));
5409 }
5410 env++;
5411 }
5413
5414 if (rb_block_arity() > 1) {
5415 for (i=0; i<RARRAY_LEN(ary); i+=2) {
5416 rb_yield_values(2, RARRAY_AREF(ary, i), RARRAY_AREF(ary, i+1));
5417 }
5418 }
5419 else {
5420 for (i=0; i<RARRAY_LEN(ary); i+=2) {
5422 }
5423 }
5424 return ehash;
5425}
5426
5427/*
5428 * call-seq:
5429 * ENV.reject! { |name, value| block } -> ENV or nil
5430 * ENV.reject! -> Enumerator
5431 *
5432 * Similar to ENV.delete_if, but returns +nil+ if no changes were made.
5433 *
5434 * Deletes each environment variable for which the block returns a truthy value,
5435 * returning ENV (if any deletions) or +nil+ (if not):
5436 * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
5437 * ENV.reject! { |name, value| name.start_with?('b') } # => ENV
5438 * ENV # => {"foo"=>"0"}
5439 * ENV.reject! { |name, value| name.start_with?('b') } # => nil
5440 *
5441 * Returns an Enumerator if no block given:
5442 * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
5443 * e = ENV.reject! # => #<Enumerator: {"bar"=>"1", "baz"=>"2", "foo"=>"0"}:reject!>
5444 * e.each { |name, value| name.start_with?('b') } # => ENV
5445 * ENV # => {"foo"=>"0"}
5446 * e.each { |name, value| name.start_with?('b') } # => nil
5447 */
5448static VALUE
5449env_reject_bang(VALUE ehash)
5450{
5451 VALUE keys;
5452 long i;
5453 int del = 0;
5454
5455 RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5456 keys = env_keys();
5458 for (i=0; i<RARRAY_LEN(keys); i++) {
5459 VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
5460 if (!NIL_P(val)) {
5461 if (RTEST(rb_yield_values(2, RARRAY_AREF(keys, i), val))) {
5462 env_delete(RARRAY_AREF(keys, i));
5463 del++;
5464 }
5465 }
5466 }
5468 if (del == 0) return Qnil;
5469 return envtbl;
5470}
5471
5472/*
5473 * call-seq:
5474 * ENV.delete_if { |name, value| block } -> ENV
5475 * ENV.delete_if -> Enumerator
5476 *
5477 * Deletes every environment variable for which the block evaluates to +true+.
5478 *
5479 * If no block is given an enumerator is returned instead.
5480 */
5481static VALUE
5482env_delete_if(VALUE ehash)
5483{
5484 RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5485 env_reject_bang(ehash);
5486 return envtbl;
5487}
5488
5489/*
5490 * call-seq:
5491 * ENV.values_at(name, ...) -> Array
5492 *
5493 * Returns an array containing the environment variable values associated with
5494 * the given names. See also ENV.select.
5495 */
5496static VALUE
5497env_values_at(int argc, VALUE *argv, VALUE _)
5498{
5499 VALUE result;
5500 long i;
5501
5502 result = rb_ary_new();
5503 for (i=0; i<argc; i++) {
5504 rb_ary_push(result, rb_f_getenv(Qnil, argv[i]));
5505 }
5506 return result;
5507}
5508
5509/*
5510 * call-seq:
5511 * ENV.select { |name, value| block } -> Hash
5512 * ENV.select -> Enumerator
5513 * ENV.filter { |name, value| block } -> Hash
5514 * ENV.filter -> Enumerator
5515 *
5516 * Returns a copy of the environment for entries where the block returns true.
5517 *
5518 * Returns an Enumerator if no block was given.
5519 *
5520 * ENV.filter is an alias for ENV.select.
5521 */
5522static VALUE
5523env_select(VALUE ehash)
5524{
5525 VALUE result;
5526 VALUE keys;
5527 long i;
5528
5529 RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5530 result = rb_hash_new();
5531 keys = env_keys();
5532 for (i = 0; i < RARRAY_LEN(keys); ++i) {
5534 VALUE val = rb_f_getenv(Qnil, key);
5535 if (!NIL_P(val)) {
5536 if (RTEST(rb_yield_values(2, key, val))) {
5537 rb_hash_aset(result, key, val);
5538 }
5539 }
5540 }
5542
5543 return result;
5544}
5545
5546/*
5547 * call-seq:
5548 * ENV.select! { |name, value| block } -> ENV or nil
5549 * ENV.select! -> Enumerator
5550 * ENV.filter! { |name, value| block } -> ENV or nil
5551 * ENV.filter! -> Enumerator
5552 *
5553 * Equivalent to ENV.keep_if but returns +nil+ if no changes were made.
5554 *
5555 * ENV.filter! is an alias for ENV.select!.
5556 */
5557static VALUE
5558env_select_bang(VALUE ehash)
5559{
5560 VALUE keys;
5561 long i;
5562 int del = 0;
5563
5564 RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5565 keys = env_keys();
5567 for (i=0; i<RARRAY_LEN(keys); i++) {
5568 VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
5569 if (!NIL_P(val)) {
5570 if (!RTEST(rb_yield_values(2, RARRAY_AREF(keys, i), val))) {
5571 env_delete(RARRAY_AREF(keys, i));
5572 del++;
5573 }
5574 }
5575 }
5577 if (del == 0) return Qnil;
5578 return envtbl;
5579}
5580
5581/*
5582 * call-seq:
5583 * ENV.keep_if { |name, value| block } -> ENV
5584 * ENV.keep_if -> Enumerator
5585 *
5586 * Deletes every environment variable where the block evaluates to +false+.
5587 *
5588 * Returns an enumerator if no block was given.
5589 */
5590static VALUE
5591env_keep_if(VALUE ehash)
5592{
5593 RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5594 env_select_bang(ehash);
5595 return envtbl;
5596}
5597
5598/*
5599 * call-seq:
5600 * ENV.slice(*keys) -> a_hash
5601 *
5602 * Returns a hash containing only the given keys from ENV and their values.
5603 *
5604 * ENV.slice("TERM","HOME") #=> {"TERM"=>"xterm-256color", "HOME"=>"/Users/rhc"}
5605 */
5606static VALUE
5607env_slice(int argc, VALUE *argv, VALUE _)
5608{
5609 int i;
5610 VALUE key, value, result;
5611
5612 if (argc == 0) {
5613 return rb_hash_new();
5614 }
5615 result = rb_hash_new_with_size(argc);
5616
5617 for (i = 0; i < argc; i++) {
5618 key = argv[i];
5619 value = rb_f_getenv(Qnil, key);
5620 if (value != Qnil)
5621 rb_hash_aset(result, key, value);
5622 }
5623
5624 return result;
5625}
5626
5627VALUE
5629{
5630 VALUE keys;
5631 long i;
5632
5633 keys = env_keys();
5634 for (i=0; i<RARRAY_LEN(keys); i++) {
5635 VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
5636 if (!NIL_P(val)) {
5637 env_delete(RARRAY_AREF(keys, i));
5638 }
5639 }
5641 return envtbl;
5642}
5643
5644/*
5645 * call-seq:
5646 * ENV.clear -> ENV
5647 *
5648 * Removes every environment variable; returns ENV:
5649 * ENV.replace('foo' => '0', 'bar' => '1')
5650 * ENV.size # => 2
5651 * ENV.clear # => ENV
5652 * ENV.size # => 0
5653 */
5654static VALUE
5655env_clear(VALUE _)
5656{
5657 return rb_env_clear();
5658}
5659
5660/*
5661 * call-seq:
5662 * ENV.to_s -> "ENV"
5663 *
5664 * Returns "ENV"
5665 */
5666static VALUE
5667env_to_s(VALUE _)
5668{
5669 return rb_usascii_str_new2("ENV");
5670}
5671
5672/*
5673 * call-seq:
5674 * ENV.inspect -> string
5675 *
5676 * Returns the contents of the environment as a String.
5677 */
5678static VALUE
5679env_inspect(VALUE _)
5680{
5681 char **env;
5682 VALUE str, i;
5683
5684 str = rb_str_buf_new2("{");
5686 while (*env) {
5687 char *s = strchr(*env, '=');
5688
5689 if (env != environ) {
5690 rb_str_buf_cat2(str, ", ");
5691 }
5692 if (s) {
5693 rb_str_buf_cat2(str, "\"");
5694 rb_str_buf_cat(str, *env, s-*env);
5695 rb_str_buf_cat2(str, "\"=>");
5696 i = rb_inspect(rb_str_new2(s+1));
5698 }
5699 env++;
5700 }
5702 rb_str_buf_cat2(str, "}");
5703
5704 return str;
5705}
5706
5707/*
5708 * call-seq:
5709 * ENV.to_a -> Array
5710 *
5711 * Converts the environment variables into an array of names and value arrays.
5712 *
5713 * ENV.to_a # => [["TERM", "xterm-color"], ["SHELL", "/bin/bash"], ...]
5714 *
5715 */
5716static VALUE
5717env_to_a(VALUE _)
5718{
5719 char **env;
5720 VALUE ary;
5721
5722 ary = rb_ary_new();
5724 while (*env) {
5725 char *s = strchr(*env, '=');
5726 if (s) {
5727 rb_ary_push(ary, rb_assoc_new(env_str_new(*env, s-*env),
5728 env_str_new2(s+1)));
5729 }
5730 env++;
5731 }
5733 return ary;
5734}
5735
5736/*
5737 * call-seq:
5738 * ENV.rehash
5739 *
5740 * Re-hashing the environment variables does nothing. It is provided for
5741 * compatibility with Hash.
5742 */
5743static VALUE
5744env_none(VALUE _)
5745{
5746 return Qnil;
5747}
5748
5749/*
5750 * call-seq:
5751 * ENV.length
5752 * ENV.size
5753 *
5754 * Returns the number of environment variables.
5755 */
5756static VALUE
5757env_size(VALUE _)
5758{
5759 int i;
5760 char **env;
5761
5763 for (i=0; env[i]; i++)
5764 ;
5766 return INT2FIX(i);
5767}
5768
5769/*
5770 * call-seq:
5771 * ENV.empty? -> true or false
5772 *
5773 * Returns true when there are no environment variables
5774 */
5775static VALUE
5776env_empty_p(VALUE _)
5777{
5778 char **env;
5779
5781 if (env[0] == 0) {
5783 return Qtrue;
5784 }
5786 return Qfalse;
5787}
5788
5789/*
5790 * call-seq:
5791 * ENV.include?(name) -> true or false
5792 * ENV.has_key?(name) -> true or false
5793 * ENV.member?(name) -> true or false
5794 * ENV.key?(name) -> true or false
5795 *
5796 * ENV.has_key?, ENV.member?, and ENV.key? are aliases for ENV.include?.
5797 *
5798 * Returns +true+ if there is an environment variable with the given +name+:
5799 * ENV.replace('foo' => '0', 'bar' => '1')
5800 * ENV.include?('foo') # => true
5801 * Returns +false+ if +name+ is a valid String and there is no such environment variable:
5802 * ENV.include?('baz') # => false
5803 * Returns +false+ if +name+ is the empty String or is a String containing character <code>'='</code>:
5804 * ENV.include?('') # => false
5805 * ENV.include?('=') # => false
5806 * Raises an exception if +name+ is a String containing the NUL character <code>"\0"</code>:
5807 * ENV.include?("\0") # Raises ArgumentError (bad environment variable name: contains null byte)
5808 * Raises an exception if +name+ has an encoding that is not ASCII-compatible:
5809 * ENV.include?("\xa1\xa1".force_encoding(Encoding::UTF_16LE))
5810 * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: UTF-16LE)
5811 * Raises an exception if +name+ is not a String:
5812 * ENV.include?(Object.new) # TypeError (no implicit conversion of Object into String)
5813 */
5814static VALUE
5815env_has_key(VALUE env, VALUE key)
5816{
5817 const char *s;
5818
5819 s = env_name(key);
5820 if (getenv(s)) return Qtrue;
5821 return Qfalse;
5822}
5823
5824/*
5825 * call-seq:
5826 * ENV.assoc(name) -> Array or nil
5827 *
5828 * Returns a 2-element Array containing the name and value of the environment variable
5829 * for +name+ if it exists:
5830 * ENV.replace('foo' => '0', 'bar' => '1')
5831 * ENV.assoc('foo') # => ['foo' '0']
5832 * Returns +nil+ if +name+ is a valid String and there is no such environment variable:
5833 * ENV.assoc('baz') # => false
5834 * Returns +nil+ if +name+ is the empty String or is a String containing character <code>'='</code>:
5835 * ENV.assoc('') # => false
5836 * ENV.assoc('=') # => false
5837 * Raises an exception if +name+ is a String containing the NUL character <code>"\0"</code>:
5838 * ENV.assoc("\0") # Raises ArgumentError (bad environment variable name: contains null byte)
5839 * Raises an exception if +name+ has an encoding that is not ASCII-compatible:
5840 * ENV.assoc("\xa1\xa1".force_encoding(Encoding::UTF_16LE))
5841 * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: UTF-16LE)
5842 * Raises an exception if +name+ is not a String:
5843 * ENV.assoc(Object.new) # TypeError (no implicit conversion of Object into String)
5844 */
5845static VALUE
5846env_assoc(VALUE env, VALUE key)
5847{
5848 const char *s, *e;
5849
5850 s = env_name(key);
5851 e = getenv(s);
5852 if (e) return rb_assoc_new(key, env_str_new2(e));
5853 return Qnil;
5854}
5855
5856/*
5857 * call-seq:
5858 * ENV.value?(value) -> true or false
5859 * ENV.has_value?(value) -> true or false
5860 *
5861 * Returns +true+ if there is an environment variable with the given +value+.
5862 */
5863static VALUE
5864env_has_value(VALUE dmy, VALUE obj)
5865{
5866 char **env;
5867
5869 if (NIL_P(obj)) return Qnil;
5871 while (*env) {
5872 char *s = strchr(*env, '=');
5873 if (s++) {
5874 long len = strlen(s);
5875 if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
5877 return Qtrue;
5878 }
5879 }
5880 env++;
5881 }
5883 return Qfalse;
5884}
5885
5886/*
5887 * call-seq:
5888 * ENV.rassoc(value)
5889 *
5890 * Returns an Array of the name and value of the environment variable with
5891 * +value+ or +nil+ if the value cannot be found.
5892 */
5893static VALUE
5894env_rassoc(VALUE dmy, VALUE obj)
5895{
5896 char **env;
5897
5899 if (NIL_P(obj)) return Qnil;
5901 while (*env) {
5902 char *s = strchr(*env, '=');
5903 if (s++) {
5904 long len = strlen(s);
5905 if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
5906 VALUE result = rb_assoc_new(rb_str_new(*env, s-*env-1), obj);
5908 return result;
5909 }
5910 }
5911 env++;
5912 }
5914 return Qnil;
5915}
5916
5917/*
5918 * call-seq:
5919 * ENV.key(value) -> name or nil
5920 *
5921 * Returns the name of the first environment variable with +value+ if it exists:
5922 * ENV.replace('foo' => '0', 'bar' => '1')
5923 * ENV.key('0') # =>'foo'
5924 * The order in which environment variables are examined is OS-dependent.
5925 * See {About Ordering}[#class-ENV-label-About+Ordering].
5926 *
5927 * Returns +nil+ if there is no such value:
5928 * ENV.key('2') # => nil
5929 * Raises an exception if +value+ is not a String:
5930 * ENV.key(Object.new) # raises TypeError (no implicit conversion of Object into String)
5931 */
5932static VALUE
5933env_key(VALUE dmy, VALUE value)
5934{
5935 char **env;
5936 VALUE str;
5937
5938 SafeStringValue(value);
5940 while (*env) {
5941 char *s = strchr(*env, '=');
5942 if (s++) {
5943 long len = strlen(s);
5944 if (RSTRING_LEN(value) == len && strncmp(s, RSTRING_PTR(value), len) == 0) {
5945 str = env_str_new(*env, s-*env-1);
5947 return str;
5948 }
5949 }
5950 env++;
5951 }
5953 return Qnil;
5954}
5955
5956/*
5957 * call-seq:
5958 * ENV.index(value) -> key
5959 *
5960 * Deprecated method that is equivalent to ENV.key
5961 */
5962static VALUE
5963env_index(VALUE dmy, VALUE value)
5964{
5965 rb_warn_deprecated("ENV.index", "ENV.key");
5966 return env_key(dmy, value);
5967}
5968
5969static VALUE
5970env_to_hash(void)
5971{
5972 char **env;
5973 VALUE hash;
5974
5975 hash = rb_hash_new();
5977 while (*env) {
5978 char *s = strchr(*env, '=');
5979 if (s) {
5980 rb_hash_aset(hash, env_str_new(*env, s-*env),
5981 env_str_new2(s+1));
5982 }
5983 env++;
5984 }
5986 return hash;
5987}
5988
5989/*
5990 * call-seq:
5991 * ENV.to_hash -> hash
5992 *
5993 * Creates a hash with a copy of the environment variables.
5994 *
5995 */
5996
5997static VALUE
5998env_f_to_hash(VALUE _)
5999{
6000 return env_to_hash();
6001}
6002
6003/*
6004 * call-seq:
6005 * ENV.to_h -> hash
6006 * ENV.to_h {|name, value| block } -> hash
6007 *
6008 * Creates a hash with a copy of the environment variables.
6009 *
6010 */
6011static VALUE
6012env_to_h(VALUE _)
6013{
6014 VALUE hash = env_to_hash();
6015 if (rb_block_given_p()) {
6016 hash = rb_hash_to_h_block(hash);
6017 }
6018 return hash;
6019}
6020
6021/*
6022 * call-seq:
6023 * ENV.reject { |name, value| block } -> Hash
6024 * ENV.reject -> Enumerator
6025 *
6026 * Same as ENV.delete_if, but works on (and returns) a copy of the
6027 * environment.
6028 */
6029static VALUE
6030env_reject(VALUE _)
6031{
6032 return rb_hash_delete_if(env_to_hash());
6033}
6034
6035/*
6036 * call-seq:
6037 * ENV.freeze -> raises TypeError
6038 *
6039 * Ruby does not allow ENV to be frozen, so calling ENV.freeze
6040 * raises TypeError.
6041 */
6042static VALUE
6043env_freeze(VALUE self)
6044{
6045 rb_raise(rb_eTypeError, "cannot freeze ENV");
6046 return self; /* Not reached */
6047}
6048
6049/*
6050 * call-seq:
6051 * ENV.shift -> [name, value] or nil
6052 *
6053 * Removes the first environment variable from ENV and returns
6054 * a 2-element Array containing its name and value:
6055 * ENV.replace('foo' => '0', 'bar' => '1')
6056 * ENV.to_hash # => {'bar' => '1', 'foo' => '0'}
6057 * ENV.shift # => ['bar', '1']
6058 * ENV.to_hash # => {'foo' => '0'}
6059 * Exactly which environment variable is "first" is OS-dependent.
6060 * See {About Ordering}[#class-ENV-label-About+Ordering].
6061 *
6062 * Returns +nil+ if the environment is empty:
6063 * ENV.clear
6064 * ENV.shift # => nil
6065 */
6066static VALUE
6067env_shift(VALUE _)
6068{
6069 char **env;
6070 VALUE result = Qnil;
6071
6073 if (*env) {
6074 char *s = strchr(*env, '=');
6075 if (s) {
6076 VALUE key = env_str_new(*env, s-*env);
6077 VALUE val = env_str_new2(getenv(RSTRING_PTR(key)));
6078 env_delete(key);
6079 result = rb_assoc_new(key, val);
6080 }
6081 }
6083 return result;
6084}
6085
6086/*
6087 * call-seq:
6088 * ENV.invert -> Hash
6089 *
6090 * Returns a new hash created by using environment variable names as values
6091 * and values as names.
6092 */
6093static VALUE
6094env_invert(VALUE _)
6095{
6096 return rb_hash_invert(env_to_hash());
6097}
6098
6099static void
6100keylist_delete(VALUE keys, VALUE key)
6101{
6102 long keylen, elen;
6103 const char *keyptr, *eptr;
6104 RSTRING_GETMEM(key, keyptr, keylen);
6105 for (long i=0; i<RARRAY_LEN(keys); i++) {
6106 VALUE e = RARRAY_AREF(keys, i);
6107 RSTRING_GETMEM(e, eptr, elen);
6108 if (elen != keylen) continue;
6109 if (!ENVNMATCH(keyptr, eptr, elen)) continue;
6111 return;
6112 }
6113}
6114
6115static int
6116env_replace_i(VALUE key, VALUE val, VALUE keys)
6117{
6118 env_name(key);
6119 env_aset(key, val);
6120
6121 keylist_delete(keys, key);
6122 return ST_CONTINUE;
6123}
6124
6125/*
6126 * call-seq:
6127 * ENV.replace(hash) -> ENV
6128 *
6129 * Replaces the entire content of the environment variables
6130 * with the name/value pairs in the given +hash+;
6131 * returns ENV.
6132 *
6133 * Replaces the content of ENV with the given pairs:
6134 * ENV.replace('foo' => '0', 'bar' => '1') # => ENV
6135 * ENV.to_hash # => {"bar"=>"1", "foo"=>"0"}
6136 *
6137 * Raises an exception if a name or value is invalid.
6138 * See {Invalid Names and Values}[#class-ENV-label-Invalid-Names+and+Values].
6139 */
6140static VALUE
6141env_replace(VALUE env, VALUE hash)
6142{
6143 VALUE keys;
6144 long i;
6145
6146 keys = env_keys();
6147 if (env == hash) return env;
6148 hash = to_hash(hash);
6149 rb_hash_foreach(hash, env_replace_i, keys);
6150
6151 for (i=0; i<RARRAY_LEN(keys); i++) {
6152 env_delete(RARRAY_AREF(keys, i));
6153 }
6155 return env;
6156}
6157
6158static int
6159env_update_i(VALUE key, VALUE val, VALUE _)
6160{
6161 env_aset(key, val);
6162 return ST_CONTINUE;
6163}
6164
6165static int
6166env_update_block_i(VALUE key, VALUE val, VALUE _)
6167{
6168 VALUE oldval = rb_f_getenv(Qnil, key);
6169 if (!NIL_P(oldval)) {
6170 val = rb_yield_values(3, key, oldval, val);
6171 }
6172 env_aset(key, val);
6173 return ST_CONTINUE;
6174}
6175
6176/*
6177 * call-seq:
6178 * ENV.update(hash) -> ENV
6179 * ENV.update(hash) { |name, old_value, new_value| block } -> ENV
6180 * ENV.merge!(hash) -> ENV
6181 * ENV.merge!(hash) { |name, old_value, new_value| block } -> ENV
6182 *
6183 * Adds the contents of +hash+ to the environment variables. If no block is
6184 * specified entries with duplicate keys are overwritten, otherwise the value
6185 * of each duplicate name is determined by calling the block with the key, its
6186 * value from the environment and its value from the hash.
6187 */
6188static VALUE
6189env_update(VALUE env, VALUE hash)
6190{
6191 if (env == hash) return env;
6192 hash = to_hash(hash);
6194 env_update_block_i : env_update_i;
6195 rb_hash_foreach(hash, func, 0);
6196 return env;
6197}
6198
6199/*
6200 * A Hash is a dictionary-like collection of unique keys and their values.
6201 * Also called associative arrays, they are similar to Arrays, but where an
6202 * Array uses integers as its index, a Hash allows you to use any object
6203 * type.
6204 *
6205 * Hashes enumerate their values in the order that the corresponding keys
6206 * were inserted.
6207 *
6208 * A Hash can be easily created by using its implicit form:
6209 *
6210 * grades = { "Jane Doe" => 10, "Jim Doe" => 6 }
6211 *
6212 * Hashes allow an alternate syntax for keys that are symbols.
6213 * Instead of
6214 *
6215 * options = { :font_size => 10, :font_family => "Arial" }
6216 *
6217 * You could write it as:
6218 *
6219 * options = { font_size: 10, font_family: "Arial" }
6220 *
6221 * Each named key is a symbol you can access in hash:
6222 *
6223 * options[:font_size] # => 10
6224 *
6225 * A Hash can also be created through its ::new method:
6226 *
6227 * grades = Hash.new
6228 * grades["Dorothy Doe"] = 9
6229 *
6230 * Hashes have a <em>default value</em> that is returned when accessing
6231 * keys that do not exist in the hash. If no default is set +nil+ is used.
6232 * You can set the default value by sending it as an argument to Hash.new:
6233 *
6234 * grades = Hash.new(0)
6235 *
6236 * Or by using the #default= method:
6237 *
6238 * grades = {"Timmy Doe" => 8}
6239 * grades.default = 0
6240 *
6241 * Accessing a value in a Hash requires using its key:
6242 *
6243 * puts grades["Jane Doe"] # => 0
6244 *
6245 * === Common Uses
6246 *
6247 * Hashes are an easy way to represent data structures, such as
6248 *
6249 * books = {}
6250 * books[:matz] = "The Ruby Programming Language"
6251 * books[:black] = "The Well-Grounded Rubyist"
6252 *
6253 * Hashes are also commonly used as a way to have named parameters in
6254 * functions. Note that no brackets are used below. If a hash is the last
6255 * argument on a method call, no braces are needed, thus creating a really
6256 * clean interface:
6257 *
6258 * Person.create(name: "John Doe", age: 27)
6259 *
6260 * def self.create(params)
6261 * @name = params[:name]
6262 * @age = params[:age]
6263 * end
6264 *
6265 * === Hash Keys
6266 *
6267 * Two objects refer to the same hash key when their <code>hash</code> value
6268 * is identical and the two objects are <code>eql?</code> to each other.
6269 *
6270 * A user-defined class may be used as a hash key if the <code>hash</code>
6271 * and <code>eql?</code> methods are overridden to provide meaningful
6272 * behavior. By default, separate instances refer to separate hash keys.
6273 *
6274 * A typical implementation of <code>hash</code> is based on the
6275 * object's data while <code>eql?</code> is usually aliased to the overridden
6276 * <code>==</code> method:
6277 *
6278 * class Book
6279 * attr_reader :author, :title
6280 *
6281 * def initialize(author, title)
6282 * @author = author
6283 * @title = title
6284 * end
6285 *
6286 * def ==(other)
6287 * self.class === other and
6288 * other.author == @author and
6289 * other.title == @title
6290 * end
6291 *
6292 * alias eql? ==
6293 *
6294 * def hash
6295 * @author.hash ^ @title.hash # XOR
6296 * end
6297 * end
6298 *
6299 * book1 = Book.new 'matz', 'Ruby in a Nutshell'
6300 * book2 = Book.new 'matz', 'Ruby in a Nutshell'
6301 *
6302 * reviews = {}
6303 *
6304 * reviews[book1] = 'Great reference!'
6305 * reviews[book2] = 'Nice and compact!'
6306 *
6307 * reviews.length #=> 1
6308 *
6309 * See also Object#hash and Object#eql?
6310 */
6311
6312void
6314{
6315#undef rb_intern
6316#define rb_intern(str) rb_intern_const(str)
6317 id_hash = rb_intern("hash");
6318 id_yield = rb_intern("yield");
6319 id_default = rb_intern("default");
6320 id_flatten_bang = rb_intern("flatten!");
6321 id_hash_iter_lev = rb_make_internal_id();
6322
6324
6326
6327 rb_define_alloc_func(rb_cHash, empty_hash_alloc);
6328 rb_define_singleton_method(rb_cHash, "[]", rb_hash_s_create, -1);
6329 rb_define_singleton_method(rb_cHash, "try_convert", rb_hash_s_try_convert, 1);
6330 rb_define_method(rb_cHash, "initialize", rb_hash_initialize, -1);
6331 rb_define_method(rb_cHash, "initialize_copy", rb_hash_replace, 1);
6333
6334 rb_define_method(rb_cHash, "to_hash", rb_hash_to_hash, 0);
6335 rb_define_method(rb_cHash, "to_h", rb_hash_to_h, 0);
6336 rb_define_method(rb_cHash, "to_a", rb_hash_to_a, 0);
6337 rb_define_method(rb_cHash, "inspect", rb_hash_inspect, 0);
6338 rb_define_alias(rb_cHash, "to_s", "inspect");
6339 rb_define_method(rb_cHash, "to_proc", rb_hash_to_proc, 0);
6340
6341 rb_define_method(rb_cHash, "==", rb_hash_equal, 1);
6343 rb_define_method(rb_cHash, "hash", rb_hash_hash, 0);
6344 rb_define_method(rb_cHash, "eql?", rb_hash_eql, 1);
6345 rb_define_method(rb_cHash, "fetch", rb_hash_fetch_m, -1);
6348 rb_define_method(rb_cHash, "default", rb_hash_default, -1);
6349 rb_define_method(rb_cHash, "default=", rb_hash_set_default, 1);
6350 rb_define_method(rb_cHash, "default_proc", rb_hash_default_proc, 0);
6352 rb_define_method(rb_cHash, "key", rb_hash_key, 1);
6353 rb_define_method(rb_cHash, "index", rb_hash_index, 1);
6355 rb_define_method(rb_cHash, "length", rb_hash_size, 0);
6356 rb_define_method(rb_cHash, "empty?", rb_hash_empty_p, 0);
6357
6358 rb_define_method(rb_cHash, "each_value", rb_hash_each_value, 0);
6359 rb_define_method(rb_cHash, "each_key", rb_hash_each_key, 0);
6360 rb_define_method(rb_cHash, "each_pair", rb_hash_each_pair, 0);
6361 rb_define_method(rb_cHash, "each", rb_hash_each_pair, 0);
6362
6363 rb_define_method(rb_cHash, "transform_keys", rb_hash_transform_keys, 0);
6364 rb_define_method(rb_cHash, "transform_keys!", rb_hash_transform_keys_bang, 0);
6365 rb_define_method(rb_cHash, "transform_values", rb_hash_transform_values, 0);
6366 rb_define_method(rb_cHash, "transform_values!", rb_hash_transform_values_bang, 0);
6367
6370 rb_define_method(rb_cHash, "values_at", rb_hash_values_at, -1);
6371 rb_define_method(rb_cHash, "fetch_values", rb_hash_fetch_values, -1);
6372
6373 rb_define_method(rb_cHash, "shift", rb_hash_shift, 0);
6374 rb_define_method(rb_cHash, "delete", rb_hash_delete_m, 1);
6383 rb_define_method(rb_cHash, "slice", rb_hash_slice, -1);
6385 rb_define_method(rb_cHash, "invert", rb_hash_invert, 0);
6386 rb_define_method(rb_cHash, "update", rb_hash_update, -1);
6387 rb_define_method(rb_cHash, "replace", rb_hash_replace, 1);
6388 rb_define_method(rb_cHash, "merge!", rb_hash_update, -1);
6389 rb_define_method(rb_cHash, "merge", rb_hash_merge, -1);
6392 rb_define_method(rb_cHash, "flatten", rb_hash_flatten, -1);
6393 rb_define_method(rb_cHash, "compact", rb_hash_compact, 0);
6394 rb_define_method(rb_cHash, "compact!", rb_hash_compact_bang, 0);
6395
6396 rb_define_method(rb_cHash, "include?", rb_hash_has_key, 1);
6398 rb_define_method(rb_cHash, "has_key?", rb_hash_has_key, 1);
6399 rb_define_method(rb_cHash, "has_value?", rb_hash_has_value, 1);
6401 rb_define_method(rb_cHash, "value?", rb_hash_has_value, 1);
6402
6403 rb_define_method(rb_cHash, "compare_by_identity", rb_hash_compare_by_id, 0);
6404 rb_define_method(rb_cHash, "compare_by_identity?", rb_hash_compare_by_id_p, 0);
6405
6406 rb_define_method(rb_cHash, "any?", rb_hash_any_p, -1);
6407 rb_define_method(rb_cHash, "dig", rb_hash_dig, -1);
6408
6409 rb_define_method(rb_cHash, "<=", rb_hash_le, 1);
6410 rb_define_method(rb_cHash, "<", rb_hash_lt, 1);
6411 rb_define_method(rb_cHash, ">=", rb_hash_ge, 1);
6412 rb_define_method(rb_cHash, ">", rb_hash_gt, 1);
6413
6414 rb_define_method(rb_cHash, "deconstruct_keys", rb_hash_deconstruct_keys, 1);
6415
6416 rb_define_singleton_method(rb_cHash, "ruby2_keywords_hash?", rb_hash_s_ruby2_keywords_hash_p, 1);
6417 rb_define_singleton_method(rb_cHash, "ruby2_keywords_hash", rb_hash_s_ruby2_keywords_hash, 1);
6418
6419 /* Document-class: ENV
6420 *
6421 * ENV is a hash-like accessor for environment variables.
6422 *
6423 * === Interaction with the Operating System
6424 *
6425 * The ENV object interacts with the operating system's environment variables:
6426 *
6427 * - When you get the value for a name in ENV, the value is retrieved from among the current environment variables.
6428 * - When you create or set a name-value pair in ENV, the name and value are immediately set in the environment variables.
6429 * - When you delete a name-value pair in ENV, it is immediately deleted from the environment variables.
6430 *
6431 * === Names and Values
6432 *
6433 * Generally, a name or value is a String.
6434 *
6435 * ==== Valid Names and Values
6436 *
6437 * Each name or value must be one of the following:
6438 *
6439 * - A String.
6440 * - An object that responds to \#to_str by returning a String, in which case that String will be used as the name or value.
6441 *
6442 * ==== Invalid Names and Values
6443 *
6444 * A new name:
6445 *
6446 * - May not be the empty string:
6447 * ENV[''] = '0'
6448 * # Raises Errno::EINVAL (Invalid argument - ruby_setenv())
6449 *
6450 * - May not contain character <code>"="</code>:
6451 * ENV['='] = '0'
6452 * # Raises Errno::EINVAL (Invalid argument - ruby_setenv(=))
6453 *
6454 * A new name or value:
6455 *
6456 * - May not be a non-String that does not respond to \#to_str:
6457 *
6458 * ENV['foo'] = Object.new
6459 * # Raises TypeError (no implicit conversion of Object into String)
6460 * ENV[Object.new] = '0'
6461 * # Raises TypeError (no implicit conversion of Object into String)
6462 *
6463 * - May not contain the NUL character <code>"\0"</code>:
6464 *
6465 * ENV['foo'] = "\0"
6466 * # Raises ArgumentError (bad environment variable value: contains null byte)
6467 * ENV["\0"] == '0'
6468 * # Raises ArgumentError (bad environment variable name: contains null byte)
6469 *
6470 * - May not have an ASCII-incompatible encoding such as UTF-16LE or ISO-2022-JP:
6471 *
6472 * ENV['foo'] = '0'.force_encoding(Encoding::ISO_2022_JP)
6473 * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: ISO-2022-JP)
6474 * ENV["foo".force_encoding(Encoding::ISO_2022_JP)] = '0'
6475 * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: ISO-2022-JP)
6476 *
6477 * === About Ordering
6478 *
6479 * ENV enumerates its name/value pairs in the order found
6480 * in the operating system's environment variables.
6481 * Therefore the ordering of ENV content is OS-dependent, and may be indeterminate.
6482 *
6483 * This will be seen in:
6484 * - A Hash returned by an ENV method.
6485 * - An Enumerator returned by an ENV method.
6486 * - An Array returned by ENV.keys, ENV.values, or ENV.to_a.
6487 * - The String returned by ENV.inspect.
6488 * - The Array returned by ENV.shift.
6489 * - The name returned by ENV.key.
6490 *
6491 * === About the Examples
6492 * Some methods in ENV return ENV itself. Typically, there are many environment variables.
6493 * It's not useful to display a large ENV in the examples here,
6494 * so most example snippets begin by resetting the contents of ENV:
6495 * - ENV.replace replaces ENV with a new collection of entries.
6496 * - ENV.clear empties ENV.
6497 */
6498
6499 /*
6500 * Hack to get RDoc to regard ENV as a class:
6501 * envtbl = rb_define_class("ENV", rb_cObject);
6502 */
6503 origenviron = environ;
6504 envtbl = rb_obj_alloc(rb_cObject);
6506
6507 rb_define_singleton_method(envtbl, "[]", rb_f_getenv, 1);
6508 rb_define_singleton_method(envtbl, "fetch", env_fetch, -1);
6509 rb_define_singleton_method(envtbl, "[]=", env_aset_m, 2);
6510 rb_define_singleton_method(envtbl, "store", env_aset_m, 2);
6511 rb_define_singleton_method(envtbl, "each", env_each_pair, 0);
6512 rb_define_singleton_method(envtbl, "each_pair", env_each_pair, 0);
6513 rb_define_singleton_method(envtbl, "each_key", env_each_key, 0);
6514 rb_define_singleton_method(envtbl, "each_value", env_each_value, 0);
6515 rb_define_singleton_method(envtbl, "delete", env_delete_m, 1);
6516 rb_define_singleton_method(envtbl, "delete_if", env_delete_if, 0);
6517 rb_define_singleton_method(envtbl, "keep_if", env_keep_if, 0);
6518 rb_define_singleton_method(envtbl, "slice", env_slice, -1);
6519 rb_define_singleton_method(envtbl, "clear", env_clear, 0);
6520 rb_define_singleton_method(envtbl, "reject", env_reject, 0);
6521 rb_define_singleton_method(envtbl, "reject!", env_reject_bang, 0);
6522 rb_define_singleton_method(envtbl, "select", env_select, 0);
6523 rb_define_singleton_method(envtbl, "select!", env_select_bang, 0);
6524 rb_define_singleton_method(envtbl, "filter", env_select, 0);
6525 rb_define_singleton_method(envtbl, "filter!", env_select_bang, 0);
6526 rb_define_singleton_method(envtbl, "shift", env_shift, 0);
6527 rb_define_singleton_method(envtbl, "freeze", env_freeze, 0);
6528 rb_define_singleton_method(envtbl, "invert", env_invert, 0);
6529 rb_define_singleton_method(envtbl, "replace", env_replace, 1);
6530 rb_define_singleton_method(envtbl, "update", env_update, 1);
6531 rb_define_singleton_method(envtbl, "merge!", env_update, 1);
6532 rb_define_singleton_method(envtbl, "inspect", env_inspect, 0);
6533 rb_define_singleton_method(envtbl, "rehash", env_none, 0);
6534 rb_define_singleton_method(envtbl, "to_a", env_to_a, 0);
6535 rb_define_singleton_method(envtbl, "to_s", env_to_s, 0);
6536 rb_define_singleton_method(envtbl, "key", env_key, 1);
6537 rb_define_singleton_method(envtbl, "index", env_index, 1);
6538 rb_define_singleton_method(envtbl, "size", env_size, 0);
6539 rb_define_singleton_method(envtbl, "length", env_size, 0);
6540 rb_define_singleton_method(envtbl, "empty?", env_empty_p, 0);
6541 rb_define_singleton_method(envtbl, "keys", env_f_keys, 0);
6542 rb_define_singleton_method(envtbl, "values", env_f_values, 0);
6543 rb_define_singleton_method(envtbl, "values_at", env_values_at, -1);
6544 rb_define_singleton_method(envtbl, "include?", env_has_key, 1);
6545 rb_define_singleton_method(envtbl, "member?", env_has_key, 1);
6546 rb_define_singleton_method(envtbl, "has_key?", env_has_key, 1);
6547 rb_define_singleton_method(envtbl, "has_value?", env_has_value, 1);
6548 rb_define_singleton_method(envtbl, "key?", env_has_key, 1);
6549 rb_define_singleton_method(envtbl, "value?", env_has_value, 1);
6550 rb_define_singleton_method(envtbl, "to_hash", env_f_to_hash, 0);
6551 rb_define_singleton_method(envtbl, "to_h", env_to_h, 0);
6552 rb_define_singleton_method(envtbl, "assoc", env_assoc, 1);
6553 rb_define_singleton_method(envtbl, "rassoc", env_rassoc, 1);
6554
6555 /*
6556 * ENV is a Hash-like accessor for environment variables.
6557 *
6558 * See ENV (the class) for more details.
6559 */
6560 rb_define_global_const("ENV", envtbl);
6561
6562 /* for callcc */
6563 ruby_register_rollback_func_for_ensure(hash_foreach_ensure, hash_foreach_ensure_rollback);
6564
6565 HASH_ASSERT(sizeof(ar_hint_t) * RHASH_AR_TABLE_MAX_SIZE == sizeof(VALUE));
6566}
#define L(x)
Definition: asm.h:125
#define recur(fmt)
#define fail()
struct RIMemo * ptr
Definition: debug.c:65
#define free(x)
Definition: dln.c:52
rb_encoding * rb_utf8_encoding(void)
Definition: encoding.c:1328
rb_encoding * rb_filesystem_encoding(void)
Definition: encoding.c:1387
rb_encoding * rb_default_internal_encoding(void)
Definition: encoding.c:1512
rb_encoding * rb_enc_get(VALUE obj)
Definition: encoding.c:872
int rb_ascii8bit_encindex(void)
Definition: encoding.c:1322
void rb_enc_copy(VALUE obj1, VALUE obj2)
Definition: encoding.c:990
int rb_locale_encindex(void)
Definition: encoding.c:1354
rb_encoding * rb_locale_encoding(void)
Definition: encoding.c:1372
VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to)
Definition: string.c:1030
#define ECONV_UNDEF_REPLACE
Definition: encoding.h:396
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
Definition: string.c:796
#define rb_enc_name(enc)
Definition: encoding.h:177
#define ECONV_INVALID_REPLACE
Definition: encoding.h:394
#define rb_enc_asciicompat(enc)
Definition: encoding.h:245
int rb_enc_str_asciionly_p(VALUE)
Definition: string.c:678
VALUE rb_external_str_new_with_enc(const char *ptr, long len, rb_encoding *)
Definition: string.c:1036
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
ID id_yield
Definition: eventids1.c:136
ID id_hash
Definition: eventids1.c:53
void rb_include_module(VALUE, VALUE)
Definition: class.c:882
void rb_extend_object(VALUE, VALUE)
Extend the object with the module.
Definition: eval.c:1701
VALUE rb_define_class(const char *, VALUE)
Defines a top-level class.
Definition: class.c:662
int rb_class_has_methods(VALUE c)
Definition: class.c:2219
void rb_define_alias(VALUE, const char *, const char *)
Defines an alias of a method.
Definition: class.c:1818
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:898
VALUE rb_cObject
Object class.
Definition: ruby.h:2012
VALUE rb_cString
Definition: ruby.h:2046
VALUE rb_mEnumerable
Definition: enum.c:20
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2671
void rb_bug(const char *fmt,...)
Definition: error.c:636
void rb_syserr_fail_str(int e, VALUE mesg)
Definition: error.c:2789
void rb_sys_fail_str(VALUE mesg)
Definition: error.c:2801
VALUE rb_eTypeError
Definition: error.c:924
VALUE rb_protect(VALUE(*)(VALUE), VALUE, int *)
Protects a function call from potential global escapes from the function.
Definition: eval.c:1072
const char * rb_builtin_class_name(VALUE x)
Definition: error.c:799
VALUE rb_eRuntimeError
Definition: error.c:922
void rb_warn(const char *fmt,...)
Definition: error.c:315
VALUE rb_eArgError
Definition: error.c:925
VALUE rb_ensure(VALUE(*)(VALUE), VALUE, VALUE(*)(VALUE), VALUE)
An equivalent to ensure clause.
Definition: eval.c:1115
VALUE rb_obj_dig(int argc, VALUE *argv, VALUE self, VALUE notfound)
Definition: object.c:3791
VALUE rb_any_to_s(VALUE)
Default implementation of #to_s.
Definition: object.c:527
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
Definition: object.c:1895
int rb_eql(VALUE, VALUE)
Determines if obj1 and obj2 are equal in terms of Object::eql?.
Definition: object.c:147
VALUE rb_obj_class(VALUE)
Equivalent to Object#class in Ruby.
Definition: object.c:217
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
Definition: object.c:551
VALUE rb_convert_type_with_id(VALUE, int, const char *, ID)
Definition: object.c:2914
VALUE rb_equal(VALUE, VALUE)
Same as Object#===, case equality.
Definition: object.c:124
VALUE rb_obj_freeze(VALUE)
Make the object unmodifiable.
Definition: object.c:1080
VALUE rb_obj_hash(VALUE obj)
Definition: hash.c:291
VALUE rb_check_convert_type_with_id(VALUE, int, const char *, ID)
Definition: object.c:2957
VALUE rb_to_int(VALUE)
Converts val into Integer.
Definition: object.c:3021
VALUE rb_hash_size(VALUE hash)
Definition: hash.c:2939
VALUE rb_hash_values_at(int argc, VALUE *argv, VALUE hash)
Definition: hash.c:2612
#define identhash
Definition: hash.c:321
VALUE rb_hash_default_value(VALUE hash, VALUE key)
Definition: hash.c:1990
VALUE rb_to_hash_type(VALUE hash)
Definition: hash.c:1845
void rb_hash_bulk_insert(long argc, const VALUE *argv, VALUE hash)
Definition: hash.c:4590
int rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
Definition: hash.c:1453
VALUE rb_hash_values(VALUE hash)
Definition: hash.c:3456
#define RHASH_TYPE(hash)
Definition: hash.c:433
MJIT_FUNC_EXPORTED VALUE rb_hash_new_with_size(st_index_t size)
Definition: hash.c:1529
VALUE rb_hash_rassoc(VALUE hash, VALUE obj)
Definition: hash.c:4078
#define GET_ENVIRON(e)
Definition: hash.c:4646
MJIT_FUNC_EXPORTED struct st_table * rb_hash_tbl_raw(VALUE hash)
Definition: hash.c:1594
VALUE rb_hash_set_ifnone(VALUE hash, VALUE ifnone)
Definition: hash.c:99
MJIT_FUNC_EXPORTED VALUE rb_hash_resurrect(VALUE hash)
Definition: hash.c:1575
void rb_hash_st_table_set(VALUE hash, st_table *st)
Definition: hash.c:558
#define env_name(s)
Definition: hash.c:4762
VALUE rb_hash_key_str(VALUE key)
Definition: hash.c:2802
#define RHASH_AR_TABLE_BOUND(h)
Definition: hash.c:429
size_t rb_hash_ar_table_size(void)
Definition: hash.c:355
VALUE rb_check_hash_type(VALUE hash)
Definition: hash.c:1852
int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:4547
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
Definition: hash.c:2050
#define rb_ident_cmp
Definition: hash.c:302
struct st_table * rb_hash_tbl(VALUE hash, const char *file, int line)
Definition: hash.c:1601
NOINLINE(static int ar_equal(VALUE x, VALUE y))
#define to_hash
Definition: hash.c:1849
int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval)
Definition: hash.c:2310
#define ENVNMATCH(s1, s2, n)
Definition: hash.c:4654
#define RHASH_ST_TABLE_SET(h, s)
Definition: hash.c:432
#define RHASH_AR_TABLE_REF(hash, n)
Definition: hash.c:341
#define RHASH_AR_TABLE_BOUND_RAW(h)
Definition: hash.c:425
VALUE rb_ident_hash_new(void)
Definition: hash.c:4278
int(* tbl_update_func)(st_data_t *, st_data_t *, st_data_t, int)
Definition: hash.c:1648
void rb_ivar_set_internal(VALUE obj, ID id, VALUE val)
Definition: variable.c:1308
VALUE rb_hash_rehash(VALUE hash)
Definition: hash.c:1958
#define COPY_DEFAULT(hash, hash2)
Definition: hash.c:52
#define RHASH_AR_TABLE_MAX_BOUND
Definition: hash.c:339
int rb_env_path_tainted(void)
Definition: hash.c:4904
#define SET_PROC_DEFAULT(hash, proc)
Definition: hash.c:50
VALUE rb_hash_set_pair(VALUE hash, VALUE arg)
Definition: hash.c:3332
void rb_hash_foreach(VALUE hash, rb_foreach_func *func, VALUE farg)
Definition: hash.c:1483
#define NOINSERT_UPDATE_CALLBACK(func)
Definition: hash.c:1625
#define RHASH_AR_TABLE_SIZE(h)
Definition: hash.c:422
VALUE rb_hash_delete(VALUE hash, VALUE key)
Definition: hash.c:2344
VALUE rb_hash_select_bang(VALUE hash)
Definition: hash.c:2714
VALUE rb_cHash
Definition: hash.c:92
#define RHASH_AR_CLEARED_HINT
Definition: hash.c:342
MJIT_FUNC_EXPORTED VALUE rb_hash_has_key(VALUE hash, VALUE key)
Definition: hash.c:3507
#define get_env_ptr(var, val)
Definition: hash.c:4749
void rb_hash_transient_heap_evacuate(VALUE hash, int promote)
Definition: hash.c:1244
VALUE rb_hash_fetch(VALUE hash, VALUE key)
Definition: hash.c:2134
struct ar_table_struct ar_table
int st_foreach_func(st_data_t, st_data_t, st_data_t)
Definition: hash.c:1271
VALUE rb_hash_assoc(VALUE hash, VALUE key)
Definition: hash.c:4017
VALUE rb_hash_keep_if(VALUE hash)
Definition: hash.c:2741
MJIT_FUNC_EXPORTED VALUE rb_hash_compare_by_id_p(VALUE hash)
Definition: hash.c:4267
VALUE rb_hash_reject(VALUE hash)
Definition: hash.c:2550
VALUE rb_hash_delete_if(VALUE hash)
Definition: hash.c:2493
#define rb_intern(str)
VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc)
Definition: hash.c:2242
char ** environ
VALUE rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func)
Definition: hash.c:3910
MJIT_FUNC_EXPORTED int rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval)
Definition: hash.c:2017
void Init_Hash(void)
Definition: hash.c:6313
#define FREE_ENVIRON(e)
Definition: hash.c:4647
#define hash_verify(h)
Definition: hash.c:510
MJIT_FUNC_EXPORTED VALUE rb_hash_keys(VALUE hash)
Definition: hash.c:3409
int rb_hash_ar_table_p(VALUE hash)
Definition: hash.c:532
#define HAS_EXTRA_STATES(hash, klass)
Definition: hash.c:41
st_table * rb_hash_st_table(VALUE hash)
Definition: hash.c:551
int rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg)
Definition: hash.c:1442
VALUE rb_hash_delete_entry(VALUE hash, VALUE key)
Definition: hash.c:2326
VALUE rb_hash_aref(VALUE hash, VALUE key)
Definition: hash.c:2037
struct ar_table_pair_struct ar_table_pair
#define RHASH_AR_TABLE_SIZE_INC(h)
Definition: hash.c:607
bool ruby_tz_uptodate_p
Definition: time.c:674
VALUE rb_hash_freeze(VALUE hash)
Definition: hash.c:87
st_index_t st_hash_t
Definition: hash.c:327
#define ENVMATCH(n1, n2)
Definition: hash.c:4653
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:2852
VALUE rb_hash_reject_bang(VALUE hash)
Definition: hash.c:2513
void ruby_unsetenv(const char *name)
Definition: hash.c:5137
int rb_foreach_func(VALUE, VALUE, VALUE)
Definition: hash.c:1306
#define RHASH_UPDATE(hash, key, func, arg)
Definition: hash.c:1694
NORETURN(static void no_new_key(void))
int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func func, st_data_t arg)
Definition: hash.c:1651
VALUE rb_hash_fetch_values(int argc, VALUE *argv, VALUE hash)
Definition: hash.c:2640
#define st_index_hash(index)
Definition: hash.c:265
long rb_dbl_long_hash(double d)
Definition: hash.c:160
VALUE rb_env_clear(void)
Definition: hash.c:5628
VALUE rb_hash_lookup(VALUE hash, VALUE key)
Definition: hash.c:2063
VALUE rb_hash_dup(VALUE hash)
Definition: hash.c:1564
VALUE rb_hash(VALUE obj)
Definition: hash.c:129
VALUE rb_hash_clear(VALUE hash)
Definition: hash.c:2769
const struct st_hash_type rb_hashtype_ident
Definition: hash.c:322
size_t rb_hash_size_num(VALUE hash)
Definition: hash.c:2945
VALUE rb_hash_select(VALUE hash)
Definition: hash.c:2679
#define HASH_ASSERT(expr)
Definition: hash.c:435
VALUE rb_hash_new(void)
Definition: hash.c:1523
#define SET_DEFAULT(hash, ifnone)
Definition: hash.c:46
st_table * rb_init_identtable(void)
Definition: hash.c:4286
void st_foreach_safe(st_table *table, st_foreach_func *func, st_data_t a)
Definition: hash.c:1294
void ruby_setenv(const char *name, const char *value)
Definition: hash.c:4998
#define RHASH_UPDATE_ITER(h, iter_lev, key, func, a)
Definition: hash.c:1690
ar_table * rb_hash_ar_table(VALUE hash)
Definition: hash.c:544
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
const char * name
Definition: nkf.c:208
double rb_float_value(VALUE v)
Definition: numeric.c:5841
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
#define RARRAY_LEN(a)
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
Definition: bignum.c:3547
__uint32_t uint32_t
#define SafeStringValue(v)
void * memchr(const void *, int, size_t)
#define rb_str_new2
#define RHASH_AR_TABLE_SIZE_RAW(h)
#define RHASH_TRANSIENT_P(hash)
#define NULL
VALUE rb_exec_recursive_paired(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE, VALUE)
Definition: thread.c:5085
#define rb_funcallv(recv, mid, argc, argv)
#define RBASIC_CLEAR_CLASS(obj)
#define uint128_t
#define RHASH_ST_CLEAR(h)
#define UNLIMITED_ARGUMENTS
#define RSTRING_LEN(str)
#define rb_str_buf_cat2
#define FL_EXIVAR
#define _(args)
char * rb_str_fill_terminator(VALUE str, const int termlen)
Definition: string.c:2306
#define RHASH_TBL_RAW(h)
#define OBJ_WB_UNPROTECT(x)
#define NEWOBJ_OF(obj, type, klass, flags)
#define RTEST(v)
#define ALLOCV_END(v)
#define PATH_ENV
#define rb_hash_uint(h, i)
VALUE rb_exec_recursive_outer(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
Definition: thread.c:5097
#define RHASH_AR_TABLE(hash)
#define RHASH_ST_TABLE_P(h)
#define RCLASS_SUPER(c)
#define RHASH_SET_IFNONE(h, ifnone)
#define FL_TEST(x, f)
enum ruby_tag_type st
#define RHASH_AR_TABLE_SIZE_SHIFT
VALUE rb_big_hash(VALUE)
Definition: bignum.c:6726
void rb_copy_generic_ivar(VALUE, VALUE)
Definition: variable.c:1447
unsigned long st_data_t
#define RBASIC(obj)
int setenv(const char *__string, const char *__value, int __overwrite)
size_t strlen(const char *)
#define T_STRING
#define rb_hash_end(h)
void * malloc(size_t) __attribute__((__malloc__)) __attribute__((__warn_unused_result__)) __attribute__((__alloc_size__(1)))
VALUE rb_assoc_new(VALUE, VALUE)
Definition: array.c:896
#define RB_FL_ANY_RAW(x, f)
#define rb_yield_values(argc,...)
#define RHASH_UNSET_TRANSIENT_FLAG(h)
int st_foreach_check_callback_func(st_data_t, st_data_t, st_data_t, int)
#define RHASH_IFNONE(h)
#define PRIuSIZE
#define xfree
int rb_proc_arity(VALUE)
Definition: proc.c:1112
#define EINVAL
#define RHASH_AR_TABLE_BOUND_SHIFT
VALUE rb_ary_cat(VALUE, const VALUE *, long)
Definition: array.c:1208
#define LONG2FIX(i)
#define INTEGER_PACK_NATIVE_BYTE_ORDER
#define Qundef
#define CHAR_BIT
#define MAYBE_UNUSED(x)
void rb_warn_deprecated(const char *fmt, const char *suggest,...) __attribute__((format(printf
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1070
const VALUE VALUE obj
#define rb_check_frozen(obj)
#define T_FLOAT
const char * rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
Definition: gc.c:11477
#define RSTRING_PTR(str)
const rb_iseq_t const char * error
#define T_BIGNUM
#define rb_str_buf_new2
int snprintf(char *__restrict__, size_t, const char *__restrict__,...) __attribute__((__format__(__printf__
#define RGENGC_WB_PROTECTED_HASH
#define RHASH_SET_TRANSIENT_FLAG(h)
#define RHASH_AR_TABLE_P(hash)
VALUE rb_obj_is_proc(VALUE)
Definition: proc.c:152
st_index_t rb_memhash(const void *ptr, long len)
Definition: random.c:1444
int rb_block_arity(void)
Definition: proc.c:1144
#define rb_str_new(str, len)
#define NIL_P(v)
#define rb_str_buf_cat
int putenv(char *__string)
VALUE rb_hash_update_func(VALUE newkey, VALUE oldkey, VALUE value)
void ruby_register_rollback_func_for_ensure(VALUE(*ensure_func)(VALUE), VALUE(*rollback_func)(VALUE))
int unsetenv(const char *)
#define REALLOC_N(var, type, n)
int fprintf(FILE *__restrict__, const char *__restrict__,...) __attribute__((__format__(__printf__
void rb_ary_set_len(VALUE, long)
Definition: array.c:1932
const char size_t n
#define T_DATA
#define ruby_verbose
st_index_t rb_hash_start(st_index_t)
Definition: random.c:1438
void rb_define_global_const(const char *, VALUE)
Definition: variable.c:2903
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:2207
unsigned long VALUE
VALUE rb_ary_push(VALUE, VALUE)
Definition: array.c:1195
#define stderr
const rb_iseq_t const char const VALUE keys
VALUE rb_check_string_type(VALUE)
Definition: string.c:2314
VALUE rb_obj_id(VALUE)
Definition: gc.c:3786
#define STATIC_SYM_P(x)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
uint32_t i
VALUE rb_fstring(VALUE)
Definition: string.c:312
#define RSTRING_GETMEM(str, ptrvar, lenvar)
int strncmp(const char *, const char *, size_t)
__inline__ const void *__restrict__ size_t len
__uint64_t uint64_t
const char * rb_obj_classname(VALUE)
Definition: variable.c:289
#define FL_TEST_RAW(x, f)
unsigned char ar_hint_t
#define ALLOC_N(type, n)
VALUE rb_block_proc(void)
Definition: proc.c:837
#define RB_OBJ_WRITE(a, slot, b)
#define FLONUM_P(x)
#define T_HASH
#define long
#define NUM2INT(x)
void rb_define_singleton_method(VALUE, const char *, VALUE(*)(), int)
#define RHASH_ITER_LEV(h)
#define RB_GC_GUARD(v)
#define RUBY_DTRACE_CREATE_HOOK(name, arg)
#define PRIsVALUE
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
#define rb_funcall(recv, mid, argc,...)
#define FIX2INT(x)
int VALUE v
#define rb_method_basic_definition_p(klass, mid)
VALUE rb_ary_new(void)
Definition: array.c:723
#define ID_SCOPE_SHIFT
#define rb_usascii_str_new2
VALUE rb_proc_lambda_p(VALUE)
Definition: proc.c:275
#define RHASH_AR_TABLE_MAX_SIZE
VALUE rb_yield_values2(int n, const VALUE *argv)
Definition: vm_eval.c:1271
VALUE rb_func_proc_new(rb_block_call_func_t func, VALUE val)
Definition: proc.c:728
VALUE rb_ary_new_capa(long capa)
Definition: array.c:717
#define ALLOCV_N(type, v, n)
char * strchr(const char *, int)
Definition: strchr.c:8
void rb_obj_info_dump(VALUE obj)
Definition: gc.c:11719
#define rb_key_err_raise(mesg, recv, name)
#define TRUE
#define FALSE
#define RHASH_ST_TABLE(hash)
VALUE rb_str_ellipsize(VALUE, long)
Shortens str and adds three dots, an ellipsis, if it is longer than len characters.
Definition: string.c:10185
#define RHASH_SIZE(h)
unsigned int size
#define Qtrue
ID rb_make_internal_id(void)
Definition: symbol.c:810
#define UNLIKELY(x)
struct rb_call_cache buf
VALUE rb_str_buf_cat_ascii(VALUE, const char *)
Definition: string.c:2926
const char * rb_obj_info(VALUE obj)
Definition: gc.c:11713
int st_update_callback_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
VALUE rb_str_new_frozen(VALUE)
Definition: string.c:1203
FILE * fopen(const char *__restrict__ _name, const char *__restrict__ _type)
#define Qnil
#define Qfalse
#define ST_DATA_COMPATIBLE_P(type)
VALUE rb_str_buf_append(VALUE, VALUE)
Definition: string.c:2950
int rb_str_hash_cmp(VALUE, VALUE)
Definition: string.c:3173
st_data_t st_index_t
#define RB_TYPE_P(obj, type)
#define RHASH(obj)
@ RHASH_PASS_AS_KEYWORDS
#define FL_WB_PROTECTED
#define INT2FIX(i)
#define SPECIAL_CONST_P(x)
pid_t getpid(void)
VALUE rb_check_array_type(VALUE)
Definition: array.c:909
#define NUM2LL(x)
void rb_gc_force_recycle(VALUE)
Definition: gc.c:7027
#define T_SYMBOL
#define MJIT_FUNC_EXPORTED
const VALUE * argv
void void ruby_xfree(void *)
Definition: gc.c:10183
#define SYMBOL_P(x)
__inline__ int
VALUE rb_ary_delete_at(VALUE, long)
Definition: array.c:3419
#define FIXNUM_P(f)
#define CLASS_OF(v)
int st_foreach_callback_func(st_data_t, st_data_t, st_data_t)
#define RB_OBJ_FROZEN(x)
void rb_gc_writebarrier_remember(VALUE obj)
Definition: gc.c:6891
if((__builtin_expect(!!(!me), 0)))
#define Check_Type(v, t)
#define rb_check_arity
VALUE rb_sprintf(const char *,...) __attribute__((format(printf
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
Definition: thread.c:5074
#define RBASIC_CLASS(obj)
st_index_t rb_str_hash(VALUE)
Definition: string.c:3163
unsigned long ID
VALUE rb_yield(VALUE)
Definition: vm_eval.c:1237
#define RHASH_EMPTY_P(h)
const char *void rb_warning(const char *,...) __attribute__((format(printf
size_t st_index_t h
#define FIX2LONG(x)
#define NUM2LONG(x)
void rb_define_method(VALUE, const char *, VALUE(*)(), int)
#define rb_ary_new2
#define RARRAY_AREF(a, i)
#define BUILTIN_TYPE(x)
#define RARRAY_PTR_USE_TRANSIENT(ary, ptr_name, expr)
#define ST2FIX(h)
void rb_hash_bulk_insert_into_st_table(long, const VALUE *, VALUE)
Definition: st.c:2379
#define RB_OBJ_WRITTEN(a, oldv, b)
#define FL_SET_RAW(x, f)
#define RSHIFT(x, y)
void * ruby_xmalloc(size_t) __attribute__((__malloc__)) __attribute__((__returns_nonnull__)) __attribute__((alloc_size(1)))
Definition: gc.c:12008
#define RB_DEBUG_COUNTER_INC(type)
rb_atomic_t cnt[RUBY_NSIG]
Definition: signal.c:503
char bin[32]
Definition: siphash.c:135
#define uint64_t
Definition: siphash.h:15
#define f
void st_free_table(st_table *tab)
Definition: st.c:709
int st_delete(st_table *tab, st_data_t *key, st_data_t *value)
Definition: st.c:1418
st_index_t st_keys(st_table *tab, st_data_t *keys, st_index_t size)
Definition: st.c:1756
int st_shift(st_table *tab, st_data_t *key, st_data_t *value)
Definition: st.c:1440
void st_add_direct(st_table *tab, st_data_t key, st_data_t value)
Definition: st.c:1251
int st_insert(st_table *tab, st_data_t key, st_data_t value)
Definition: st.c:1171
st_index_t st_values(st_table *tab, st_data_t *values, st_index_t size)
Definition: st.c:1794
void st_clear(st_table *tab)
Definition: st.c:698
st_index_t st_hash(const void *ptr, size_t len, st_index_t h)
Definition: st.c:1896
int st_lookup(st_table *tab, st_data_t key, st_data_t *value)
Definition: st.c:1101
int st_foreach(st_table *tab, st_foreach_callback_func *func, st_data_t arg)
Definition: st.c:1717
st_table * st_init_table(const struct st_hash_type *type)
Definition: st.c:645
int st_foreach_with_replace(st_table *tab, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
Definition: st.c:1699
int st_update(st_table *tab, st_data_t key, st_update_callback_func *func, st_data_t arg)
Definition: st.c:1509
int st_foreach_check(st_table *tab, st_foreach_check_callback_func *func, st_data_t arg, st_data_t never ATTRIBUTE_UNUSED)
Definition: st.c:1725
st_table * st_copy(st_table *old_tab)
Definition: st.c:1320
st_table * st_init_table_with_size(const struct st_hash_type *type, st_index_t size)
Definition: st.c:577
VALUE rb_str_initialize(VALUE str, const char *ptr, long len, rb_encoding *enc)
Definition: string.c:964
VALUE rb_str_cat_conv_enc_opts(VALUE newstr, long ofs, const char *ptr, long len, rb_encoding *from, int ecflags, VALUE ecopts)
Definition: string.c:943
struct RBasic basic
ar_table_pair pairs[RHASH_AR_TABLE_MAX_SIZE]
Definition: hash.c:351
VALUE result
Definition: hash.c:3554
VALUE hash
Definition: hash.c:3555
int eql
Definition: hash.c:3556
st_foreach_func * func
Definition: hash.c:1275
st_data_t arg
Definition: hash.c:1276
st_table * tbl
Definition: hash.c:1274
Definition: hash.c:909
st_foreach_callback_func * func
Definition: hash.c:910
st_data_t arg
Definition: hash.c:911
rb_foreach_func * func
Definition: hash.c:1310
VALUE hash
Definition: hash.c:1309
st_table * tbl
Definition: hash.c:1922
VALUE hash
Definition: hash.c:1921
const struct st_hash_type * orighash
Definition: hash.c:3978
VALUE val
Definition: hash.c:2397
VALUE key
Definition: hash.c:2396
st_index_t(* hash)(st_data_t)
int(* compare)(st_data_t, st_data_t)
const struct st_hash_type * type
VALUE old_value
Definition: hash.c:1645
VALUE old_key
Definition: hash.c:1643
st_data_t arg
Definition: hash.c:1640
VALUE new_key
Definition: hash.c:1642
VALUE hash
Definition: hash.c:1641
VALUE new_value
Definition: hash.c:1644
st_data_t arg
Definition: hash.c:1622
VALUE value
Definition: hash.c:3874
VALUE hash
Definition: hash.c:3873
rb_hash_update_func * func
Definition: hash.c:3875
#define RSYMBOL(obj)
Definition: symbol.h:33
void * rb_transient_heap_alloc(VALUE obj, size_t req_size)
int rb_transient_heap_managed_ptr_p(const void *ptr)
char * ruby_strdup(const char *)
Definition: util.c:527
#define object_id
Definition: vm_method.c:31
#define getenv(name)
Definition: win32.c:73
#define env
char * rb_w32_getenv(const char *)
Definition: win32.c:5267
char * rb_w32_ugetenv(const char *)
Definition: win32.c:5260
DWORD rb_w32_osver(void)
Definition: win32.c:319