/* * call-seq: * ObjectSpace.define_finalizer(obj, aProc=proc()) * * Adds <i>aProc</i> as a finalizer, to be called after <i>obj</i> * was destroyed. * */ static VALUE define_final(argc, argv, os) int argc; VALUE *argv; VALUE os; { VALUE obj, block, table; rb_scan_args(argc, argv, "11", &obj, &block); if (argc == 1) { block = rb_block_proc(); } else if (!rb_respond_to(block, rb_intern("call"))) { rb_raise(rb_eArgError, "wrong type argument %s (should be callable)", rb_obj_classname(block)); } need_call_final = 1; if (!FL_ABLE(obj)) { rb_raise(rb_eArgError, "cannot define finalizer for %s", rb_obj_classname(obj)); } RBASIC(obj)->flags |= FL_FINALIZE; block = rb_ary_new3(2, INT2FIX(ruby_safe_level), block); OBJ_FREEZE(block); if (!finalizer_table) { finalizer_table = st_init_numtable(); } if (st_lookup(finalizer_table, obj, &table)) { rb_ary_push(table, block); } else { table = rb_ary_new3(1, block); RBASIC(table)->klass = 0; st_add_direct(finalizer_table, obj, table); } return block; }