summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog19
-rw-r--r--array.c55
-rw-r--r--error.c12
-rw-r--r--eval.c40
-rw-r--r--ext/curses/curses.c6
-rw-r--r--ext/dbm/dbm.c1
-rw-r--r--ext/md5/md5init.c1
-rw-r--r--ext/socket/socket.c49
-rw-r--r--file.c1
-rw-r--r--hash.c13
-rw-r--r--intern.h1
-rw-r--r--io.c8
-rw-r--r--object.c62
-rw-r--r--range.c1
-rw-r--r--re.c3
-rw-r--r--sample/test.rb9
-rw-r--r--string.c1
-rw-r--r--struct.c7
-rw-r--r--time.c1
19 files changed, 255 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog
index 40f87b464a..e377fec10c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,22 @@
+Thu Apr 2 18:31:46 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * eval.c (obj_call_init): every object call `initialize'.
+
+Wed Apr 1 01:20:31 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * object.c (true_and): boolean operators &, | and ^.
+
Tue Mar 31 13:23:58 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
- * numeric.c (num2int): raise exception for too big Fixnums on
- platforms that sizeof(int) < sizeof(INT).
+ * array.c (ary_compact_bang): returns nil, if it does not modify
+ the array like String's bang methods.
+
+ * array.c (ary_uniq_bang): new method to remove duplicate items.
+
+ * eval.c (bind_s_new): new method.
+
+ * numeric.c (num2int): raise exception if Fixnums too big to
+ convert into `int' in case that sizeof(int) < sizeof(INT).
* string.c (str_center): SEGV on negative width.
diff --git a/array.c b/array.c
index 9ef50cfee7..02f0af36f9 100644
--- a/array.c
+++ b/array.c
@@ -155,6 +155,7 @@ ary_s_new(argc, argv, klass)
ary->capa = NIL_P(size)?ARY_DEFAULT_SIZE:NUM2INT(size);
ary->ptr = ALLOC_N(VALUE, ary->capa);
memclear(ary->ptr, ary->capa);
+ obj_call_init((VALUE)ary);
return (VALUE)ary;
}
@@ -739,7 +740,8 @@ ary_sort_bang(ary)
if (RARRAY(ary)->len == 0) return ary;
ary_modify(ary);
- qsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE), iterator_p()?sort_1:sort_2);
+ qsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE),
+ iterator_p()?sort_1:sort_2);
return ary;
}
@@ -1118,6 +1120,46 @@ ary_or(ary1, ary2)
}
static VALUE
+ary_uniq_bang(ary)
+ VALUE ary;
+{
+ VALUE *p, *q, *t, *end;
+ VALUE v;
+ int i;
+
+ ary_modify(ary);
+ p = RARRAY(ary)->ptr;
+ end = p + RARRAY(ary)->len;
+
+ while (p < end) {
+ v = *p++;
+ q = t = p;
+ while (q < end) {
+ if (rb_equal(*q, v)) q++;
+ else *t++ = *q++;
+ }
+ end = t;
+ }
+ if (RARRAY(ary)->len = (end - RARRAY(ary)->ptr)) {
+ return Qnil;
+ }
+
+ RARRAY(ary)->len = (end - RARRAY(ary)->ptr);
+
+ return ary;
+}
+
+static VALUE
+ary_uniq(ary)
+ VALUE ary;
+{
+ VALUE v = ary_uniq_bang(ary_clone(ary));
+
+ if (NIL_P(v)) return ary;
+ return v;
+}
+
+static VALUE
ary_compact_bang(ary)
VALUE ary;
{
@@ -1130,6 +1172,9 @@ ary_compact_bang(ary)
if (NIL_P(*t)) t++;
else *p++ = *t++;
}
+ if (RARRAY(ary)->len == (p - RARRAY(ary)->ptr)) {
+ return Qnil;
+ }
RARRAY(ary)->len = RARRAY(ary)->capa = (p - RARRAY(ary)->ptr);
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
@@ -1140,7 +1185,10 @@ static VALUE
ary_compact(ary)
VALUE ary;
{
- return ary_compact_bang(ary_clone(ary));
+ VALUE v = ary_compact_bang(ary_clone(ary));
+
+ if (NIL_P(v)) return ary;
+ return v;
}
static VALUE
@@ -1224,7 +1272,8 @@ Init_Array()
rb_define_method(cArray, "&", ary_and, 1);
rb_define_method(cArray, "|", ary_or, 1);
- rb_define_method(cArray, "compact", ary_compact, 0);
+ rb_define_method(cArray, "uniq!", ary_uniq_bang, 0);
+ rb_define_method(cArray, "uniq", ary_uniq, 0);
rb_define_method(cArray, "compact!", ary_compact_bang, 0);
rb_define_method(cArray, "nitems", ary_nitems, 0);
diff --git a/error.c b/error.c
index 9e8f54479c..74c2cbb8be 100644
--- a/error.c
+++ b/error.c
@@ -268,13 +268,17 @@ exc_s_new(argc, argv, etype)
VALUE *argv;
VALUE etype;
{
- VALUE arg;
+ VALUE arg, exc;
if (rb_scan_args(argc, argv, "01", &arg) == 0) {
- return exc_new(etype, 0, 0);
+ exc = exc_new(etype, 0, 0);
}
- Check_Type(arg, T_STRING);
- return exc_new3(etype, arg);
+ else {
+ Check_Type(arg, T_STRING);
+ exc = exc_new3(etype, arg);
+ }
+ obj_call_init(exc);
+ return exc;
}
static VALUE
diff --git a/eval.c b/eval.c
index 95f5d4ad5f..0d49cb6b28 100644
--- a/eval.c
+++ b/eval.c
@@ -4344,6 +4344,15 @@ mod_include(argc, argv, module)
return module;
}
+void
+obj_call_init(obj)
+ VALUE obj;
+{
+ PUSH_ITER(iterator_p()?ITER_PRE:ITER_NOT);
+ rb_funcall2(obj, init, the_frame->argc, the_frame->argv);
+ POP_ITER();
+}
+
VALUE
class_new_instance(argc, argv, klass)
int argc;
@@ -4356,9 +4365,8 @@ class_new_instance(argc, argv, klass)
TypeError("can't create instance of virtual class");
}
obj = obj_alloc(klass);
- PUSH_ITER(iterator_p()?ITER_PRE:ITER_NOT);
- rb_funcall2(obj, init, argc, argv);
- POP_ITER();
+ obj_call_init(obj);
+
return obj;
}
@@ -4667,6 +4675,30 @@ blk_copy_prev(block)
}
}
+
+static VALUE
+bind_clone(self)
+ VALUE self;
+{
+ struct BLOCK *orig, *data;
+ VALUE bind;
+
+ Data_Get_Struct(self, struct BLOCK, orig);
+ bind = Data_Make_Struct(self, struct BLOCK, blk_mark,blk_free,data);
+ MEMCPY(data, orig, struct BLOCK, 1);
+ data->frame.argv = ALLOC_N(VALUE, orig->frame.argc);
+ MEMCPY(data->frame.argv, orig->frame.argv, VALUE, orig->frame.argc);
+
+ if (data->iter) {
+ blk_copy_prev(data);
+ }
+ else {
+ data->prev = 0;
+ }
+
+ return bind;
+}
+
static VALUE
f_binding(self)
VALUE self;
@@ -5076,6 +5108,8 @@ Init_Proc()
rb_define_global_function("lambda", f_lambda, 0);
rb_define_global_function("binding", f_binding, 0);
cBinding = rb_define_class("Binding", cObject);
+ rb_undef_method(CLASS_OF(cMethod), "new");
+ rb_define_method(cBinding, "clone", bind_clone, 0);
cMethod = rb_define_class("Method", cObject);
rb_undef_method(CLASS_OF(cMethod), "new");
diff --git a/ext/curses/curses.c b/ext/curses/curses.c
index 7826450e8c..4c29202277 100644
--- a/ext/curses/curses.c
+++ b/ext/curses/curses.c
@@ -390,11 +390,15 @@ window_s_new(class, lines, cols, top, left)
VALUE top;
VALUE left;
{
+ VALUE w;
WINDOW *window;
window = newwin(NUM2INT(lines), NUM2INT(cols), NUM2INT(top), NUM2INT(left));
wclear(window);
- return prep_window(class, window);
+ w = prep_window(class, window);
+ obj_call_init(w);
+
+ return w;
}
/* def subwin(lines, cols, top, left) */
diff --git a/ext/dbm/dbm.c b/ext/dbm/dbm.c
index cb6a63475a..98c406ace0 100644
--- a/ext/dbm/dbm.c
+++ b/ext/dbm/dbm.c
@@ -83,6 +83,7 @@ fdbm_s_open(argc, argv, class)
obj = Data_Make_Struct(class,struct dbmdata,0,free_dbm,dbmp);
dbmp->di_dbm = dbm;
dbmp->di_size = -1;
+ obj_call_init(obj);
return obj;
}
diff --git a/ext/md5/md5init.c b/ext/md5/md5init.c
index 348f64bcda..894f52a849 100644
--- a/ext/md5/md5init.c
+++ b/ext/md5/md5init.c
@@ -74,6 +74,7 @@ md5_new(argc, argv, class)
if (!NIL_P(arg)) {
md5_update(obj, arg);
}
+ obj_call_init(obj);
return obj;
}
diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index fc82854a4d..0b3090124a 100644
--- a/ext/socket/socket.c
+++ b/ext/socket/socket.c
@@ -540,8 +540,11 @@ static VALUE
tcp_s_open(class, host, serv)
VALUE class, host, serv;
{
+ VALUE s;
Check_SafeStr(host);
- return open_inet(class, host, serv, INET_CLIENT);
+ s = open_inet(class, host, serv, INET_CLIENT);
+ obj_call_init(s);
+ return s;
}
#ifdef SOCKS
@@ -550,6 +553,7 @@ socks_s_open(class, host, serv)
VALUE class, host, serv;
{
static init = 0;
+ VALUE s;
if (init == 0) {
SOCKSinit("ruby");
@@ -557,7 +561,9 @@ socks_s_open(class, host, serv)
}
Check_SafeStr(host);
- return open_inet(class, host, serv, INET_SOCKS);
+ s = open_inet(class, host, serv, INET_SOCKS);
+ obj_call_init(s);
+ return s;
}
#endif
@@ -567,12 +573,14 @@ tcp_svr_s_open(argc, argv, class)
VALUE *argv;
VALUE class;
{
- VALUE arg1, arg2;
+ VALUE arg1, arg2, s;
if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2)
- return open_inet(class, arg1, arg2, INET_SERVER);
+ s = open_inet(class, arg1, arg2, INET_SERVER);
else
- return open_inet(class, 0, arg1, INET_SERVER);
+ s = open_inet(class, 0, arg1, INET_SERVER);
+ obj_call_init(s);
+ return s;
}
static VALUE
@@ -801,7 +809,11 @@ static VALUE
udp_s_open(class)
VALUE class;
{
- return sock_new(class, socket(AF_INET, SOCK_DGRAM, 0));
+ VALUE s;
+
+ s = sock_new(class, socket(AF_INET, SOCK_DGRAM, 0));
+ obj_call_init(s);
+ return s;
}
static void
@@ -944,7 +956,10 @@ static VALUE
unix_s_sock_open(sock, path)
VALUE sock, path;
{
- return open_unix(sock, path, 0);
+ VALUE s;
+ s = open_unix(sock, path, 0);
+ obj_call_init(s);
+ return s;
}
static VALUE
@@ -965,10 +980,13 @@ unix_path(sock)
}
static VALUE
-unix_svr_s_open(class, path)
- VALUE class, path;
+unix_svr_s_open(sock, path)
+ VALUE sock, path;
{
- return open_unix(class, path, 1);
+ VALUE s;
+ s = open_unix(sock, path, 1);
+ obj_call_init(s);
+ return s;
}
static VALUE
@@ -1121,18 +1139,25 @@ sock_s_open(class, domain, type, protocol)
{
int fd;
int d, t;
+ VALUE s;
setup_domain_and_type(domain, &d, type, &t);
fd = socket(d, t, NUM2INT(protocol));
if (fd < 0) rb_sys_fail("socket(2)");
- return sock_new(class, fd);
+ s = sock_new(class, fd);
+ obj_call_init(s);
+
+ return s;
}
static VALUE
sock_s_for_fd(class, fd)
VALUE class, fd;
{
- return sock_new(class, NUM2INT(fd));
+ VALUE s = sock_new(class, NUM2INT(fd));
+
+ obj_call_init(s);
+ return s;
}
static VALUE
diff --git a/file.c b/file.c
index be3ab652bb..338a1dd557 100644
--- a/file.c
+++ b/file.c
@@ -101,6 +101,7 @@ file_s_open(argc, argv, klass)
if (iterator_p()) {
rb_ensure(rb_yield, file, io_close, file);
}
+ obj_call_init(file);
return file;
}
diff --git a/hash.c b/hash.c
index 0e5abb78ef..4d170873f8 100644
--- a/hash.c
+++ b/hash.c
@@ -205,6 +205,7 @@ hash_s_new(argc, argv, klass)
hash->status = 0;
hash->tbl = 0; /* avoid GC crashing */
hash->tbl = st_init_table_with_size(&objhash, size);
+ obj_call_init((VALUE)hash);
return (VALUE)hash;
}
@@ -213,7 +214,15 @@ static VALUE
hash_new2(klass)
VALUE klass;
{
- return hash_s_new(0, 0, klass);
+ NEWOBJ(hash, struct RHash);
+ OBJSETUP(hash, klass, T_HASH);
+
+ hash->iter_lev = 0;
+ hash->status = 0;
+ hash->tbl = 0; /* avoid GC crashing */
+ hash->tbl = st_init_table(&objhash);
+
+ return (VALUE)hash;
}
VALUE
@@ -241,6 +250,7 @@ hash_s_create(argc, argv, klass)
hash->status = 0;
hash->tbl = 0; /* avoid GC crashing */
hash->tbl = (st_table*)st_copy(RHASH(argv[0])->tbl);
+ obj_call_init((VALUE)hash);
return (VALUE)hash;
}
}
@@ -253,6 +263,7 @@ hash_s_create(argc, argv, klass)
for (i=0; i<argc; i+=2) {
st_insert(RHASH(hash)->tbl, argv[i], argv[i+1]);
}
+ obj_call_init(hash);
return hash;
}
diff --git a/intern.h b/intern.h
index 600d0fc213..d4123a8633 100644
--- a/intern.h
+++ b/intern.h
@@ -121,6 +121,7 @@ ID rb_frame_last_func _((void));
VALUE f_load _((VALUE, VALUE));
void rb_provide _((char *));
VALUE f_require _((VALUE, VALUE));
+void obj_call_init _((VALUE));
VALUE class_new_instance _((int, VALUE *, VALUE));
VALUE f_lambda _((void));
void rb_set_end_proc _((void (*)(),VALUE));
diff --git a/io.c b/io.c
index b187bfec31..9f7be6777a 100644
--- a/io.c
+++ b/io.c
@@ -1533,8 +1533,8 @@ io_s_new(argc, argv)
VALUE *argv;
{
VALUE fnum, mode;
- FILE *f;
char *m = "r";
+ VALUE io;
rb_scan_args(argc, argv, "11", &fnum, &mode);
@@ -1542,8 +1542,10 @@ io_s_new(argc, argv)
Check_SafeStr(mode);
m = RSTRING(mode)->ptr;
}
- f = rb_fdopen(NUM2INT(fnum), m);
- return prep_stdio(f, io_mode_flags(m));
+ io = prep_stdio(rb_fdopen(NUM2INT(fnum), m), io_mode_flags(m));
+ obj_call_init(io);
+
+ return io;
}
static VALUE filename, file;
diff --git a/object.c b/object.c
index 7de7225caf..afd51f8f22 100644
--- a/object.c
+++ b/object.c
@@ -331,6 +331,27 @@ true_type(obj)
}
static VALUE
+true_and(obj, obj2)
+ VALUE obj, obj2;
+{
+ return RTEST(obj2)?TRUE:FALSE;
+}
+
+static VALUE
+true_or(obj, obj2)
+ VALUE obj, obj2;
+{
+ return TRUE;
+}
+
+static VALUE
+true_xor(obj, obj2)
+ VALUE obj, obj2;
+{
+ return RTEST(obj2)?FALSE:TRUE;
+}
+
+static VALUE
false_to_s(obj)
VALUE obj;
{
@@ -352,6 +373,27 @@ false_type(obj)
}
static VALUE
+false_and(obj, obj2)
+ VALUE obj, obj2;
+{
+ return FALSE;
+}
+
+static VALUE
+false_or(obj, obj2)
+ VALUE obj, obj2;
+{
+ return RTEST(obj2)?TRUE:FALSE;
+}
+
+static VALUE
+false_xor(obj, obj2)
+ VALUE obj, obj2;
+{
+ return RTEST(obj2)?TRUE:FALSE;
+}
+
+static VALUE
rb_true(obj)
VALUE obj;
{
@@ -480,7 +522,14 @@ mod_cmp(mod, arg)
return INT2FIX(1);
}
-VALUE module_new();
+VALUE module_s_new()
+{
+ VALUE mod = module_new();
+
+ obj_call_init(mod);
+ return mod;
+}
+
VALUE class_new_instance();
static VALUE
@@ -500,6 +549,7 @@ class_s_new(argc, argv)
/* make metaclass */
RBASIC(klass)->klass = singleton_class_new(RBASIC(super)->klass);
singleton_class_attached(RBASIC(klass)->klass, klass);
+ obj_call_init(klass);
return klass;
}
@@ -917,7 +967,7 @@ Init_Object()
rb_define_private_method(cModule, "attr_writer", mod_attr_writer, -1);
rb_define_private_method(cModule, "attr_accessor", mod_attr_accessor, -1);
- rb_define_singleton_method(cModule, "new", module_new, 0);
+ rb_define_singleton_method(cModule, "new", module_s_new, 0);
rb_define_method(cModule, "instance_methods", class_instance_methods, -1);
rb_define_method(cModule, "private_instance_methods", class_private_instance_methods, -1);
@@ -933,8 +983,6 @@ Init_Object()
rb_undef_method(cClass, "extend_object");
rb_undef_method(cClass, "append_features");
- rb_define_singleton_method(cClass, "new", class_s_new, -1);
-
cData = rb_define_class("Data", cObject);
rb_undef_method(CLASS_OF(cData), "new");
@@ -946,6 +994,9 @@ Init_Object()
rb_define_method(cTrueClass, "to_s", true_to_s, 0);
rb_define_method(cTrueClass, "to_i", true_to_i, 0);
rb_define_method(cTrueClass, "type", true_type, 0);
+ rb_define_method(cTrueClass, "&", true_and, 1);
+ rb_define_method(cTrueClass, "|", true_or, 1);
+ rb_define_method(cTrueClass, "^", true_xor, 1);
rb_undef_method(CLASS_OF(cTrueClass), "new");
rb_define_global_const("TRUE", TRUE);
@@ -953,6 +1004,9 @@ Init_Object()
rb_define_method(cFalseClass, "to_s", false_to_s, 0);
rb_define_method(cFalseClass, "to_i", false_to_i, 0);
rb_define_method(cFalseClass, "type", false_type, 0);
+ rb_define_method(cFalseClass, "&", false_and, 1);
+ rb_define_method(cFalseClass, "|", false_or, 1);
+ rb_define_method(cFalseClass, "^", false_xor, 1);
rb_undef_method(CLASS_OF(cFalseClass), "new");
rb_define_global_const("FALSE", FALSE);
diff --git a/range.c b/range.c
index fc5ae364e5..c9a79d52ea 100644
--- a/range.c
+++ b/range.c
@@ -45,6 +45,7 @@ range_s_new(klass, first, last)
rb_iv_set(obj, "first", first);
rb_iv_set(obj, "last", last);
+ obj_call_init(obj);
return obj;
}
diff --git a/re.c b/re.c
index b69f74ae9a..b34e5e6fc5 100644
--- a/re.c
+++ b/re.c
@@ -659,6 +659,7 @@ reg_new_1(klass, s, len, flag)
memcpy(re->str, s, len);
re->str[len] = '\0';
re->len = len;
+ obj_call_init((VALUE)re);
return (VALUE)re;
}
@@ -795,7 +796,7 @@ reg_s_new(argc, argv, self)
Check_Type(src, T_STRING);
}
- return Qnil;
+ return Qnil; /* not reached */
}
static VALUE
diff --git a/sample/test.rb b/sample/test.rb
index 69a168f2c4..98c913667a 100644
--- a/sample/test.rb
+++ b/sample/test.rb
@@ -277,11 +277,20 @@ ok($x[0] == -1 && $x[1] == 10)
$x[-1, 1] = 20
ok($x[-1] == 20 && $x.pop == 20)
+# array and/or
+ok(([1,2,3]&[2,4,6]) == [2])
+ok(([1,2,3]|[2,4,6]) == [1,2,3,4,6])
+
# compact
$x = [nil, 1, nil, nil, 5, nil, nil]
$x.compact!
ok($x == [1, 5])
+# uniq
+$x = [1, 1, 4, 2, 5, 4, 5, 1, 2]
+$x.uniq!
+ok($x == [1, 4, 2, 5])
+
# empty?
ok(!$x.empty?)
$x = []
diff --git a/string.c b/string.c
index 43c8aaac37..178c256798 100644
--- a/string.c
+++ b/string.c
@@ -177,6 +177,7 @@ str_s_new(klass, orig)
if (rb_safe_level() >= 3) {
FL_SET(str, STR_TAINT);
}
+ obj_call_init((VALUE)str);
return (VALUE)str;
}
diff --git a/struct.c b/struct.c
index 1819c3c1dc..6d31896d37 100644
--- a/struct.c
+++ b/struct.c
@@ -185,6 +185,7 @@ struct_s_def(argc, argv)
struct RString *name;
struct RArray *rest;
int i;
+ VALUE st;
rb_scan_args(argc, argv, "1*", &name, &rest);
Check_Type(name, T_STRING);
@@ -192,7 +193,10 @@ struct_s_def(argc, argv)
ID id = rb_to_id(rest->ptr[i]);
rest->ptr[i] = INT2FIX(id);
}
- return make_struct(name, rest);
+ st = make_struct(name, rest);
+ obj_call_init((VALUE)st);
+
+ return st;
}
VALUE
@@ -215,6 +219,7 @@ struct_alloc(klass, values)
st->len = n;
MEMCPY(st->ptr, RARRAY(values)->ptr, VALUE, RARRAY(values)->len);
memclear(st->ptr+RARRAY(values)->len, n - RARRAY(values)->len);
+ obj_call_init((VALUE)st);
return (VALUE)st;
}
diff --git a/time.c b/time.c
index a18cb9675c..bd13cdceb3 100644
--- a/time.c
+++ b/time.c
@@ -62,6 +62,7 @@ time_s_now(klass)
if (gettimeofday(&(tobj->tv), 0) == -1) {
rb_sys_fail("gettimeofday");
}
+ obj_call_init(obj);
return obj;
}