summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-06-05 07:19:39 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-06-05 07:19:39 +0000
commitd6c60dbf6d42f411a31a1c2e768a5a986a270a8c (patch)
treee8848119511789017b7c0dbf29f8cd37376737e5 /eval.c
parent21524a3fc00d0e894d0ca0b8fcb7d9c7413c5917 (diff)
* variable.c (rb_mod_const_at): use hash table as internal
data. [new] * variable.c (rb_mod_const_of): ditto. * variable.c (rb_const_list): new function to convert internal data (hash table) to array of strings. * eval.c (rb_mod_s_constants): data handling scheme has changed. * eval.c (rb_add_method): should not call rb_secure(), for last_func may not be set. * io.c (rb_io_ctl): ioctl should accept any integer within C long range. * marshal.c (r_object): wrong type check for modules. * marshal.c (w_object): should not dump anonymous classes/modules. * io.c (rb_open_file): use rb_file_sysopen_internal() if the 3rd argument (permission flags) is given. [new, should be backported?] * io.c (rb_io_mode_binmode): mode string (e.g. "r+") to flags to open(2). * eval.c (rb_eval): NODE_REXPAND expand an array of 1 element as the element itself. [new, should be backported?] * parse.y (ret_args): should treat "*[a]" in rhs expression as "a", not "[a]". * regex.c (re_compile_pattern): should push option modifier at the right place. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1504 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c53
1 files changed, 42 insertions, 11 deletions
diff --git a/eval.c b/eval.c
index 1dbd43b2d1..c4d298421c 100644
--- a/eval.c
+++ b/eval.c
@@ -228,10 +228,7 @@ rb_add_method(klass, mid, node, noex)
NODE *body;
if (NIL_P(klass)) klass = rb_cObject;
- if (klass == rb_cObject) {
- rb_secure(4);
- }
- if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
+ if (rb_safe_level() >= 4 && (klass == rb_cObject || !OBJ_TAINTED(klass))) {
rb_raise(rb_eSecurityError, "Insecure: can't define method");
}
if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
@@ -1474,15 +1471,19 @@ static VALUE
rb_mod_s_constants()
{
NODE *cbase = RNODE(ruby_frame->cbase);
- VALUE ary = rb_ary_new();
+ void *data = 0;
while (cbase) {
- if (!NIL_P(cbase->nd_clss)) rb_mod_const_at(cbase->nd_clss, ary);
+ if (!NIL_P(cbase->nd_clss)) {
+ data = rb_mod_const_at(cbase->nd_clss, data);
+ }
cbase = cbase->nd_next;
}
- if (!NIL_P(ruby_cbase)) rb_mod_const_of(ruby_cbase, ary);
- return ary;
+ if (!NIL_P(ruby_cbase)) {
+ data = rb_mod_const_of(ruby_cbase, data);
+ }
+ return rb_const_list(data);
}
void
@@ -2349,12 +2350,19 @@ rb_eval(self, n)
}
break;
+ case NODE_REXPAND:
+ result = rb_eval(self, node->nd_head);
+ if (TYPE(result) != T_ARRAY) {
+ result = rb_Array(result);
+ }
+ if (RARRAY(result)->len == 1) {
+ result = RARRAY(result)->ptr[0];
+ }
+ break;
+
case NODE_YIELD:
if (node->nd_stts) {
result = rb_eval(self, node->nd_stts);
- if (nd_type(node->nd_stts) == NODE_RESTARGS && RARRAY(result)->len == 1) {
- result = RARRAY(result)->ptr[0];
- }
}
else {
result = Qnil;
@@ -8602,6 +8610,28 @@ rb_thread_key_p(thread, id)
return Qfalse;
}
+static int
+thread_keys_i(key, value, ary)
+ ID key;
+ VALUE value, ary;
+{
+ rb_ary_push(ary, ID2SYM(key));
+ return ST_CONTINUE;
+}
+
+static VALUE
+rb_thread_keys(thread)
+ VALUE thread;
+{
+ rb_thread_t th = rb_thread_check(thread);
+ VALUE ary = rb_ary_new();
+
+ if (th->locals) {
+ st_foreach(th->locals, thread_keys_i, ary);
+ }
+ return ary;
+}
+
static VALUE
rb_thread_inspect(thread)
VALUE thread;
@@ -8823,6 +8853,7 @@ Init_Thread()
rb_define_method(rb_cThread, "[]", rb_thread_aref, 1);
rb_define_method(rb_cThread, "[]=", rb_thread_aset, 2);
rb_define_method(rb_cThread, "key?", rb_thread_key_p, 1);
+ rb_define_method(rb_cThread, "keys", rb_thread_keys, 0);
rb_define_method(rb_cThread, "inspect", rb_thread_inspect, 0);