Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 780 lines (699 sloc) 17.33 kB
7d7d3e8 @ferrous26 Change ownership to The MacRuby Team and update copyrights
ferrous26 authored
1 /*
208fcab moved the ENV stuff into a separate file
Laurent Sansonetti authored
2 * MacRuby implementation of ENV.
3 *
4 * This file is covered by the Ruby license. See COPYING for more details.
7d7d3e8 @ferrous26 Change ownership to The MacRuby Team and update copyrights
ferrous26 authored
5 *
6 * Copyright (C) 2012, The MacRuby Team. All rights reserved.
9595725 update copyrights to 2011
Laurent Sansonetti authored
7 * Copyright (C) 2007-2011, Apple Inc. All rights reserved.
208fcab moved the ENV stuff into a separate file
Laurent Sansonetti authored
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
d0898dd include/ruby/macruby.h -> macruby_internal.h
Laurent Sansonetti authored
13 #include "macruby_internal.h"
208fcab moved the ENV stuff into a separate file
Laurent Sansonetti authored
14 #include "ruby/st.h"
15 #include "ruby/util.h"
16 #include "ruby/node.h"
17 #include "vm.h"
18
59746d9 cleaning up a few things
Laurent Sansonetti authored
19 char ***_NSGetEnviron();
208fcab moved the ENV stuff into a separate file
Laurent Sansonetti authored
20
21 static VALUE envtbl;
22
23 static int path_tainted = -1;
24
25 static char **origenviron;
26 #define GET_ENVIRON() (*_NSGetEnviron())
27
28 static VALUE
29 to_hash(VALUE hash)
30 {
31 return rb_convert_type(hash, T_HASH, "Hash", "to_hash");
32 }
33
34 static VALUE
35 env_str_new(const char *ptr, long len)
36 {
37 VALUE str = rb_tainted_str_new(ptr, len);
38 rb_obj_freeze(str);
39 return str;
40 }
41
42 static VALUE
43 env_str_new2(const char *ptr)
44 {
45 if (ptr == NULL) {
46 return Qnil;
47 }
48 return env_str_new(ptr, strlen(ptr));
49 }
50
51 static VALUE
52 env_delete(VALUE obj, VALUE name)
53 {
54 rb_secure(4);
55 SafeStringValue(name);
56 const char *nam = RSTRING_PTR(name);
57 if (strlen(nam) != RSTRING_LEN(name)) {
58 rb_raise(rb_eArgError, "bad environment variable name");
59 }
60 const char *val = getenv(nam);
61 if (val != NULL) {
62 VALUE value = env_str_new2(val);
63 ruby_setenv(nam, 0);
64 if (strcmp(nam, PATH_ENV) == 0) {
65 path_tainted = 0;
66 }
67 return value;
68 }
69 return Qnil;
70 }
71
72 static VALUE
73 env_delete_m(VALUE obj, SEL sel, VALUE name)
74 {
75 VALUE val = env_delete(obj, name);
76 if (NIL_P(val) && rb_block_given_p()) {
77 rb_yield(name);
78 }
79 return val;
80 }
81
82 static VALUE
83 rb_f_getenv(VALUE obj, SEL sel, VALUE name)
84 {
85 rb_secure(4);
86 SafeStringValue(name);
87 const char *nam = RSTRING_PTR(name);
88 if (strlen(nam) != RSTRING_LEN(name)) {
89 rb_raise(rb_eArgError, "bad environment variable name");
90 }
91 const char *env = getenv(nam);
92 if (env != NULL) {
93 if (strcmp(nam, PATH_ENV) == 0 && !rb_env_path_tainted()) {
94 VALUE str = rb_str_new2(env);
95 rb_obj_freeze(str);
96 return str;
97 }
98 return env_str_new2(env);
99 }
100 return Qnil;
101 }
102
103 static VALUE
104 env_fetch(VALUE rcv, SEL sel, int argc, VALUE *argv)
105 {
106 rb_secure(4);
107
108 VALUE key, if_none;
109 rb_scan_args(argc, argv, "11", &key, &if_none);
110
111 const bool block_given = rb_block_given_p();
112 if (block_given && argc == 2) {
113 rb_warn("block supersedes default value argument");
114 }
115 SafeStringValue(key);
116 const char *nam = RSTRING_PTR(key);
117 if (strlen(nam) != RSTRING_LEN(key)) {
118 rb_raise(rb_eArgError, "bad environment variable name");
119 }
120 const char *env = getenv(nam);
121 if (env == NULL) {
122 if (block_given) {
123 return rb_yield(key);
124 }
125 if (argc == 1) {
126 rb_raise(rb_eKeyError, "key not found");
127 }
128 return if_none;
129 }
130 if (strcmp(nam, PATH_ENV) == 0 && !rb_env_path_tainted()) {
131 return rb_str_new2(env);
132 }
133 return env_str_new2(env);
134 }
135
136 static void
137 path_tainted_p(const char *path)
138 {
139 path_tainted = rb_path_check(path) ? 0 : 1;
140 }
141
142 int
143 rb_env_path_tainted(void)
144 {
145 if (path_tainted < 0) {
146 path_tainted_p(getenv(PATH_ENV));
147 }
148 return path_tainted;
149 }
150
151 void
152 ruby_setenv(const char *name, const char *value)
153 {
154 if (value != NULL) {
9ce4823 @Watson1978 ENV#[]= raises an exception if the key contains the '=' like a 'foo='
Watson1978 authored
155 if (setenv(name, value, 1)) {
156 rb_sys_fail("setenv");
157 }
208fcab moved the ENV stuff into a separate file
Laurent Sansonetti authored
158 }
159 else {
9ce4823 @Watson1978 ENV#[]= raises an exception if the key contains the '=' like a 'foo='
Watson1978 authored
160 if (unsetenv(name)) {
161 rb_sys_fail("unsetenv");
162 }
208fcab moved the ENV stuff into a separate file
Laurent Sansonetti authored
163 }
164 }
165
166 void
167 ruby_unsetenv(const char *name)
168 {
169 ruby_setenv(name, 0);
170 }
171
172 static VALUE
173 env_aset(VALUE obj, SEL sel, VALUE nm, VALUE val)
174 {
175 if (rb_safe_level() >= 4) {
176 rb_raise(rb_eSecurityError, "can't change environment variable");
177 }
178
179 if (NIL_P(val)) {
180 env_delete(obj, nm);
181 return Qnil;
182 }
183 StringValue(nm);
184 StringValue(val);
185 const char *name = RSTRING_PTR(nm);
186 const char *value = RSTRING_PTR(val);
187 if (strlen(name) != RSTRING_LEN(nm)) {
188 rb_raise(rb_eArgError, "bad environment variable name");
189 }
190 if (strlen(value) != RSTRING_LEN(val)) {
191 rb_raise(rb_eArgError, "bad environment variable value");
192 }
193
194 ruby_setenv(name, value);
195 if (strcmp(name, PATH_ENV) == 0) {
196 if (OBJ_TAINTED(val)) {
197 /* already tainted, no check */
198 path_tainted = 1;
199 return val;
200 }
201 else {
202 path_tainted_p(value);
203 }
204 }
205 return val;
206 }
207
208 static VALUE
209 env_keys(VALUE rcv, SEL sel)
210 {
211 rb_secure(4);
212
213 VALUE ary = rb_ary_new();
214 char **env = GET_ENVIRON();
215 while (*env != NULL) {
216 const char *s = strchr(*env, '=');
217 if (s != NULL) {
218 rb_ary_push(ary, env_str_new(*env, s - *env));
219 }
220 env++;
221 }
222 return ary;
223 }
224
225 static VALUE
226 env_each_key(VALUE ehash, SEL sel)
227 {
228 RETURN_ENUMERATOR(ehash, 0, 0);
229 VALUE keys = env_keys(Qnil, 0); /* rb_secure(4); */
230 for (long i = 0, count = RARRAY_LEN(keys); i < count; i++) {
231 rb_yield(RARRAY_AT(keys, i));
232 RETURN_IF_BROKEN();
233 }
234 return ehash;
235 }
236
237 static VALUE
238 env_values(VALUE rcv, SEL sel)
239 {
240 rb_secure(4);
241
242 VALUE ary = rb_ary_new();
243 char **env = GET_ENVIRON();
244 while (*env != NULL) {
245 const char *s = strchr(*env, '=');
246 if (s != NULL) {
247 rb_ary_push(ary, env_str_new2(s + 1));
248 }
249 env++;
250 }
251 return ary;
252 }
253
254 static VALUE
255 env_each_value(VALUE ehash, SEL sel)
256 {
257 RETURN_ENUMERATOR(ehash, 0, 0);
258 VALUE values = env_values(Qnil, 0); /* rb_secure(4); */
259 for (long i = 0, count = RARRAY_LEN(values); i < count; i++) {
260 rb_yield(RARRAY_AT(values, i));
261 RETURN_IF_BROKEN();
262 }
263 return ehash;
264 }
265
266 static VALUE
267 env_each_pair(VALUE ehash, SEL sel)
268 {
269 RETURN_ENUMERATOR(ehash, 0, 0);
270
271 rb_secure(4);
272 VALUE ary = rb_ary_new();
273 char **env = GET_ENVIRON();
274 while (*env != NULL) {
275 const char *s = strchr(*env, '=');
276 if (s != NULL) {
277 rb_ary_push(ary, env_str_new(*env, s - *env));
278 rb_ary_push(ary, env_str_new2(s + 1));
279 }
280 env++;
281 }
282
283 for (long i = 0, count = RARRAY_LEN(ary); i < count; i += 2) {
284 rb_yield(rb_assoc_new(RARRAY_AT(ary, i), RARRAY_AT(ary, i + 1)));
285 RETURN_IF_BROKEN();
286 }
287 return ehash;
288 }
289
290 static VALUE
291 env_reject_bang(VALUE ehash, SEL sel)
292 {
293 RETURN_ENUMERATOR(ehash, 0, 0);
294 VALUE keys = env_keys(Qnil, 0); /* rb_secure(4); */
295 bool deleted = false;
296 for (long i = 0, count = RARRAY_LEN(keys); i < count; i++) {
297 VALUE key = RARRAY_AT(keys, i);
298 VALUE val = rb_f_getenv(Qnil, 0, key);
299 if (!NIL_P(val)) {
300 VALUE v = rb_yield_values(2, key, val);
301 RETURN_IF_BROKEN();
302 if (RTEST(v)) {
303 rb_obj_untaint(key);
304 env_delete(Qnil, key);
305 deleted = true;
306 }
307 }
308 }
309 return deleted ? envtbl : Qnil;
310 }
311
312 static VALUE
313 env_delete_if(VALUE ehash, SEL sel)
314 {
315 RETURN_ENUMERATOR(ehash, 0, 0);
316 env_reject_bang(ehash, 0);
317 return envtbl;
318 }
319
320 static VALUE
321 env_values_at(VALUE rcv, SEL sel, int argc, VALUE *argv)
322 {
323 rb_secure(4);
324 VALUE result = rb_ary_new();
325 for (long i = 0; i < argc; i++) {
326 rb_ary_push(result, rb_f_getenv(Qnil, 0, argv[i]));
327 }
328 return result;
329 }
330
331 static VALUE
332 env_select(VALUE ehash, SEL sel)
333 {
334 RETURN_ENUMERATOR(ehash, 0, 0);
335 rb_secure(4);
336 VALUE result = rb_hash_new();
337 char **env = GET_ENVIRON();
338 while (*env != NULL) {
339 const char *s = strchr(*env, '=');
340 if (s != NULL) {
341 VALUE k = env_str_new(*env, s - *env);
342 VALUE v = env_str_new2(s + 1);
343 VALUE v2 = rb_yield_values(2, k, v);
344 RETURN_IF_BROKEN();
345 if (RTEST(v2)) {
346 rb_hash_aset(result, k, v);
347 }
348 }
349 env++;
350 }
351 return result;
352 }
353
354 static VALUE
2839b68 @Watson1978 implement Env#select!
Watson1978 authored
355 env_select_bang(VALUE ehash, SEL sel)
356 {
357 volatile VALUE keys;
358 long i;
359 int del = 0;
360
361 RETURN_ENUMERATOR(ehash, 0, 0);
362 keys = env_keys(Qnil, 0); /* rb_secure(4); */
363 for (i=0; i<RARRAY_LEN(keys); i++) {
364 VALUE val = rb_f_getenv(Qnil, 0, RARRAY_AT(keys, i));
365 if (!NIL_P(val)) {
366 if (!RTEST(rb_yield_values(2, RARRAY_AT(keys, i), val))) {
367 rb_obj_untaint(RARRAY_AT(keys, i));
368 env_delete(Qnil, RARRAY_PTR(keys)[i]);
369 del++;
370 }
371 }
372 }
373 if (del == 0) {
374 return Qnil;
375 }
376 return envtbl;
377 }
378
379 static VALUE
b76ccff @Watson1978 implement Env#keep_if
Watson1978 authored
380 env_keep_if(VALUE ehash, SEL sel)
381 {
382 RETURN_ENUMERATOR(ehash, 0, 0);
383 env_select_bang(ehash, 0);
384 return envtbl;
385 }
386
387 static VALUE
208fcab moved the ENV stuff into a separate file
Laurent Sansonetti authored
388 rb_env_clear_imp(VALUE rcv, SEL sel)
389 {
390 VALUE keys = env_keys(Qnil, 0); /* rb_secure(4); */
391 for (long i = 0, count = RARRAY_LEN(keys); i < count; i++) {
392 VALUE val = rb_f_getenv(Qnil, 0, RARRAY_AT(keys, i));
393 if (!NIL_P(val)) {
394 env_delete(Qnil, RARRAY_AT(keys, i));
395 }
396 }
397 return envtbl;
398 }
399
400 VALUE
401 rb_env_clear(void)
402 {
403 return rb_env_clear_imp(Qnil, 0);
404 }
405
406 static VALUE
407 env_to_s(VALUE rcv, SEL sel)
408 {
409 return rb_usascii_str_new2("ENV");
410 }
411
412 static VALUE
413 env_inspect(VALUE rcv, SEL sel)
414 {
415 rb_secure(4);
416
417 VALUE str = rb_str_buf_new2("{");
418 char **env = GET_ENVIRON();
419 while (*env != NULL) {
420 const char *s = strchr(*env, '=');
421
422 if (env != GET_ENVIRON()) {
423 rb_str_buf_cat2(str, ", ");
424 }
425 if (s != NULL) {
426 rb_str_buf_cat2(str, "\"");
427 rb_str_buf_cat(str, *env, s - *env);
428 rb_str_buf_cat2(str, "\"=>");
429 VALUE i = rb_inspect(rb_str_new2(s + 1));
430 rb_str_buf_append(str, i);
431 }
432 env++;
433 }
434 rb_str_buf_cat2(str, "}");
435 OBJ_TAINT(str);
436
437 return str;
438 }
439
440 static VALUE
441 env_to_a(VALUE rcv, SEL sel)
442 {
443 rb_secure(4);
444
445 VALUE ary = rb_ary_new();
446 char **env = GET_ENVIRON();
447 while (*env != NULL) {
448 const char *s = strchr(*env, '=');
449 if (s != NULL) {
450 rb_ary_push(ary, rb_assoc_new(env_str_new(*env, s - *env),
451 env_str_new2(s + 1)));
452 }
453 env++;
454 }
455 return ary;
456 }
457
458 static VALUE
459 env_none(VALUE rcv, SEL sel)
460 {
461 return Qnil;
462 }
463
464 static VALUE
465 env_size(VALUE rcv, SEL sel)
466 {
467 rb_secure(4);
468
469 char **env = GET_ENVIRON();
470 int i = 0;
471 while (env[i] != NULL) {
472 i++;
473 }
474 return INT2FIX(i);
475 }
476
477 static VALUE
478 env_empty_p(VALUE rcv, SEL sel)
479 {
480 rb_secure(4);
481
482 char **env = GET_ENVIRON();
483 if (env[0] == NULL) {
484 return Qtrue;
485 }
486 return Qfalse;
487 }
488
489 static VALUE
490 env_has_key(VALUE env, SEL sel, VALUE key)
491 {
492 rb_secure(4);
493
494 const char *s = StringValuePtr(key);
495 if (strlen(s) != RSTRING_LEN(key)) {
496 rb_raise(rb_eArgError, "bad environment variable name");
497 }
498 if (getenv(s) != NULL) {
499 return Qtrue;
500 }
501 return Qfalse;
502 }
503
504 static VALUE
505 env_assoc(VALUE env, SEL sel, VALUE key)
506 {
507 rb_secure(4);
508
509 const char *s = StringValuePtr(key);
510 if (strlen(s) != RSTRING_LEN(key)) {
511 rb_raise(rb_eArgError, "bad environment variable name");
512 }
513 const char *e = getenv(s);
514 if (e != NULL) {
515 return rb_assoc_new(key, rb_tainted_str_new2(e));
516 }
517 return Qnil;
518 }
519
520 static VALUE
521 env_has_value(VALUE dmy, SEL sel, VALUE obj)
522 {
523 rb_secure(4);
524
525 obj = rb_check_string_type(obj);
526 if (NIL_P(obj)) {
527 return Qnil;
528 }
529 char **env = GET_ENVIRON();
530 while (*env != NULL) {
531 const char *s = strchr(*env, '=');
532 if (s++ != NULL) {
533 const long len = strlen(s);
534 if (RSTRING_LEN(obj) == len
535 && strncmp(s, RSTRING_PTR(obj), len) == 0) {
536 return Qtrue;
537 }
538 }
539 env++;
540 }
541 return Qfalse;
542 }
543
544 static VALUE
13f1b83 Add selector to the implementation of `ENV#rassoc`
Thibault Martin-Lagardette authored
545 env_rassoc(VALUE dmy, SEL sel, VALUE obj)
208fcab moved the ENV stuff into a separate file
Laurent Sansonetti authored
546 {
547 rb_secure(4);
548
549 obj = rb_check_string_type(obj);
550 if (NIL_P(obj)) {
551 return Qnil;
552 }
553 char **env = GET_ENVIRON();
554 while (*env != NULL) {
555 const char *s = strchr(*env, '=');
556 if (s++ != NULL) {
557 const long len = strlen(s);
558 if (RSTRING_LEN(obj) == len
559 && strncmp(s, RSTRING_PTR(obj), len) == 0) {
560 return rb_assoc_new(rb_tainted_str_new(*env, s - *env - 1),
561 obj);
562 }
563 }
564 env++;
565 }
566 return Qnil;
567 }
568
569 static VALUE
570 env_key(VALUE dmy, SEL sel, VALUE value)
571 {
572 rb_secure(4);
573
574 StringValue(value);
575 char **env = GET_ENVIRON();
576 while (*env != NULL) {
577 const char *s = strchr(*env, '=');
578 if (s++ != NULL) {
579 const long len = strlen(s);
580 if (RSTRING_LEN(value) == len
581 && strncmp(s, RSTRING_PTR(value), len) == 0) {
582 return env_str_new(*env, s - *env - 1);
583 }
584 }
585 env++;
586 }
587 return Qnil;
588 }
589
590 static VALUE
591 env_index(VALUE dmy, SEL sel, VALUE value)
592 {
593 rb_warn("ENV.index is deprecated; use ENV.key");
594 return env_key(dmy, 0, value);
595 }
596
597 static VALUE
598 env_to_hash(VALUE rcv, SEL sel)
599 {
600 rb_secure(4);
601
602 VALUE hash = rb_hash_new();
603 char **env = GET_ENVIRON();
604 while (*env != NULL) {
605 const char *s = strchr(*env, '=');
606 if (s != NULL) {
607 rb_hash_aset(hash, env_str_new(*env, s - *env),
608 env_str_new2(s + 1));
609 }
610 env++;
611 }
612 return hash;
613 }
614
615 static VALUE
616 env_reject(VALUE rcv, SEL sel)
617 {
618 rb_secure(4);
619
620 RETURN_ENUMERATOR(rcv, 0, 0);
621
622 VALUE hash = rb_hash_new();
623 char **env = GET_ENVIRON();
624 while (*env != NULL) {
625 const char *s = strchr(*env, '=');
626 if (s != NULL) {
627 VALUE key = env_str_new(*env, s - *env);
628 VALUE val = env_str_new2(s + 1);
629 if (!RTEST(rb_yield_values(2, key, val))) {
630 rb_hash_aset(hash, key, val);
631 }
632 }
633 env++;
634 }
635 return hash;
636 }
637
638 static VALUE
639 env_shift(VALUE rcv, SEL sel)
640 {
641 rb_secure(4);
642
643 char **env = GET_ENVIRON();
644 if (*env != NULL) {
645 const char *s = strchr(*env, '=');
646 if (s != NULL) {
647 VALUE key = env_str_new(*env, s - *env);
648 VALUE val = env_str_new2(getenv(RSTRING_PTR(key)));
649 env_delete(Qnil, key);
650 return rb_assoc_new(key, val);
651 }
652 }
653 return Qnil;
654 }
655
656 static VALUE
657 env_invert(VALUE rcv, SEL sel)
658 {
659 rb_secure(4);
660
661 VALUE hash = rb_hash_new();
662 char **env = GET_ENVIRON();
663 while (*env != NULL) {
664 const char *s = strchr(*env, '=');
665 if (s != NULL) {
666 rb_hash_aset(hash, env_str_new2(s + 1),
667 env_str_new(*env, s - *env));
668 }
669 env++;
670 }
671 return hash;
672 }
673
674 static int
675 env_replace_i(VALUE key, VALUE val, VALUE keys)
676 {
677 if (key != Qundef) {
678 env_aset(Qnil, 0, key, val);
679 if (rb_ary_includes(keys, key)) {
680 rb_ary_delete(keys, key);
681 }
682 }
683 return ST_CONTINUE;
684 }
685
686 static VALUE
687 env_replace(VALUE env, SEL sel, VALUE hash)
688 {
689 VALUE keys = env_keys(Qnil, 0); /* rb_secure(4); */
690 if (env == hash) {
691 return env;
692 }
693 hash = to_hash(hash);
694 rb_hash_foreach(hash, env_replace_i, keys);
695
696 for (long i = 0, count = RARRAY_LEN(keys); i < count; i++) {
697 env_delete(env, RARRAY_AT(keys, i));
698 }
699 return env;
700 }
701
702 static int
e8a9d92 fix problems detected by the clang lto
Laurent Sansonetti authored
703 env_update_i(VALUE key, VALUE val, VALUE ctx)
208fcab moved the ENV stuff into a separate file
Laurent Sansonetti authored
704 {
705 if (key != Qundef) {
706 if (rb_block_given_p()) {
707 val = rb_yield_values(3, key, rb_f_getenv(Qnil, 0, key), val);
708 RETURN_IF_BROKEN();
709 }
710 env_aset(Qnil, 0, key, val);
711 }
712 return ST_CONTINUE;
713 }
714
715 static VALUE
716 env_update(VALUE env, SEL sel, VALUE hash)
717 {
718 rb_secure(4);
719 if (env == hash) {
720 return env;
721 }
722 hash = to_hash(hash);
723 rb_hash_foreach(hash, env_update_i, 0);
724 return env;
725 }
726
727 void
728 Init_ENV(void)
729 {
730 origenviron = GET_ENVIRON();
731 envtbl = rb_obj_alloc(rb_cObject);
732 rb_extend_object(envtbl, rb_mEnumerable);
733
734 VALUE klass = rb_singleton_class(envtbl);
735
736 rb_objc_define_method(klass, "[]", rb_f_getenv, 1);
737 rb_objc_define_method(klass, "fetch", env_fetch, -1);
738 rb_objc_define_method(klass, "[]=", env_aset, 2);
739 rb_objc_define_method(klass, "store", env_aset, 2);
740 rb_objc_define_method(klass, "each", env_each_pair, 0);
741 rb_objc_define_method(klass, "each_pair", env_each_pair, 0);
742 rb_objc_define_method(klass, "each_key", env_each_key, 0);
743 rb_objc_define_method(klass, "each_value", env_each_value, 0);
744 rb_objc_define_method(klass, "delete", env_delete_m, 1);
745 rb_objc_define_method(klass, "delete_if", env_delete_if, 0);
b76ccff @Watson1978 implement Env#keep_if
Watson1978 authored
746 rb_objc_define_method(klass, "keep_if", env_keep_if, 0);
208fcab moved the ENV stuff into a separate file
Laurent Sansonetti authored
747 rb_objc_define_method(klass, "clear", rb_env_clear_imp, 0);
748 rb_objc_define_method(klass, "reject", env_reject, 0);
749 rb_objc_define_method(klass, "reject!", env_reject_bang, 0);
750 rb_objc_define_method(klass, "select", env_select, 0);
2839b68 @Watson1978 implement Env#select!
Watson1978 authored
751 rb_objc_define_method(klass, "select!", env_select_bang, 0);
208fcab moved the ENV stuff into a separate file
Laurent Sansonetti authored
752 rb_objc_define_method(klass, "shift", env_shift, 0);
753 rb_objc_define_method(klass, "invert", env_invert, 0);
754 rb_objc_define_method(klass, "replace", env_replace, 1);
755 rb_objc_define_method(klass, "update", env_update, 1);
756 rb_objc_define_method(klass, "inspect", env_inspect, 0);
757 rb_objc_define_method(klass, "rehash", env_none, 0);
758 rb_objc_define_method(klass, "to_a", env_to_a, 0);
759 rb_objc_define_method(klass, "to_s", env_to_s, 0);
760 rb_objc_define_method(klass, "key", env_key, 1);
761 rb_objc_define_method(klass, "index", env_index, 1);
762 rb_objc_define_method(klass, "size", env_size, 0);
763 rb_objc_define_method(klass, "length", env_size, 0);
764 rb_objc_define_method(klass, "empty?", env_empty_p, 0);
765 rb_objc_define_method(klass, "keys", env_keys, 0);
766 rb_objc_define_method(klass, "values", env_values, 0);
767 rb_objc_define_method(klass, "values_at", env_values_at, -1);
768 rb_objc_define_method(klass, "include?", env_has_key, 1);
769 rb_objc_define_method(klass, "member?", env_has_key, 1);
770 rb_objc_define_method(klass, "has_key?", env_has_key, 1);
771 rb_objc_define_method(klass, "has_value?", env_has_value, 1);
772 rb_objc_define_method(klass, "key?", env_has_key, 1);
773 rb_objc_define_method(klass, "value?", env_has_value, 1);
774 rb_objc_define_method(klass, "to_hash", env_to_hash, 0);
775 rb_objc_define_method(klass, "assoc", env_assoc, 1);
776 rb_objc_define_method(klass, "rassoc", env_rassoc, 1);
777
778 rb_define_global_const("ENV", envtbl);
779 }
Something went wrong with that request. Please try again.