|
Ruby
1.9.3p448(2013-06-27revision41675)
|
00001 /********************************************************************** 00002 00003 proc.c - Proc, Binding, Env 00004 00005 $Author: usa $ 00006 created at: Wed Jan 17 12:13:14 2007 00007 00008 Copyright (C) 2004-2007 Koichi Sasada 00009 00010 **********************************************************************/ 00011 00012 #include "eval_intern.h" 00013 #include "internal.h" 00014 #include "gc.h" 00015 #include "iseq.h" 00016 00017 struct METHOD { 00018 VALUE recv; 00019 VALUE rclass; 00020 ID id; 00021 rb_method_entry_t *me; 00022 struct unlinked_method_entry_list_entry *ume; 00023 }; 00024 00025 VALUE rb_cUnboundMethod; 00026 VALUE rb_cMethod; 00027 VALUE rb_cBinding; 00028 VALUE rb_cProc; 00029 00030 static VALUE bmcall(VALUE, VALUE, int, VALUE *, VALUE); 00031 static int method_arity(VALUE); 00032 00033 /* Proc */ 00034 00035 #define IS_METHOD_PROC_NODE(node) (nd_type(node) == NODE_IFUNC && (node)->nd_cfnc == bmcall) 00036 00037 static void 00038 proc_free(void *ptr) 00039 { 00040 RUBY_FREE_ENTER("proc"); 00041 if (ptr) { 00042 ruby_xfree(ptr); 00043 } 00044 RUBY_FREE_LEAVE("proc"); 00045 } 00046 00047 static void 00048 proc_mark(void *ptr) 00049 { 00050 rb_proc_t *proc; 00051 RUBY_MARK_ENTER("proc"); 00052 if (ptr) { 00053 proc = ptr; 00054 RUBY_MARK_UNLESS_NULL(proc->envval); 00055 RUBY_MARK_UNLESS_NULL(proc->blockprocval); 00056 RUBY_MARK_UNLESS_NULL(proc->block.proc); 00057 RUBY_MARK_UNLESS_NULL(proc->block.self); 00058 if (proc->block.iseq && RUBY_VM_IFUNC_P(proc->block.iseq)) { 00059 RUBY_MARK_UNLESS_NULL((VALUE)(proc->block.iseq)); 00060 } 00061 } 00062 RUBY_MARK_LEAVE("proc"); 00063 } 00064 00065 static size_t 00066 proc_memsize(const void *ptr) 00067 { 00068 return ptr ? sizeof(rb_proc_t) : 0; 00069 } 00070 00071 static const rb_data_type_t proc_data_type = { 00072 "proc", 00073 { 00074 proc_mark, 00075 proc_free, 00076 proc_memsize, 00077 }, 00078 }; 00079 00080 VALUE 00081 rb_proc_alloc(VALUE klass) 00082 { 00083 rb_proc_t *proc; 00084 return TypedData_Make_Struct(klass, rb_proc_t, &proc_data_type, proc); 00085 } 00086 00087 VALUE 00088 rb_obj_is_proc(VALUE proc) 00089 { 00090 if (rb_typeddata_is_kind_of(proc, &proc_data_type)) { 00091 return Qtrue; 00092 } 00093 else { 00094 return Qfalse; 00095 } 00096 } 00097 00098 /* :nodoc: */ 00099 static VALUE 00100 proc_dup(VALUE self) 00101 { 00102 VALUE procval = rb_proc_alloc(rb_cProc); 00103 rb_proc_t *src, *dst; 00104 GetProcPtr(self, src); 00105 GetProcPtr(procval, dst); 00106 00107 dst->block = src->block; 00108 dst->block.proc = procval; 00109 dst->blockprocval = src->blockprocval; 00110 dst->envval = src->envval; 00111 dst->safe_level = src->safe_level; 00112 dst->is_lambda = src->is_lambda; 00113 00114 return procval; 00115 } 00116 00117 /* :nodoc: */ 00118 static VALUE 00119 proc_clone(VALUE self) 00120 { 00121 VALUE procval = proc_dup(self); 00122 CLONESETUP(procval, self); 00123 return procval; 00124 } 00125 00126 /* 00127 * call-seq: 00128 * prc.lambda? -> true or false 00129 * 00130 * Returns +true+ for a Proc object for which argument handling is rigid. 00131 * Such procs are typically generated by +lambda+. 00132 * 00133 * A Proc object generated by +proc+ ignores extra arguments. 00134 * 00135 * proc {|a,b| [a,b] }.call(1,2,3) #=> [1,2] 00136 * 00137 * It provides +nil+ for missing arguments. 00138 * 00139 * proc {|a,b| [a,b] }.call(1) #=> [1,nil] 00140 * 00141 * It expands a single array argument. 00142 * 00143 * proc {|a,b| [a,b] }.call([1,2]) #=> [1,2] 00144 * 00145 * A Proc object generated by +lambda+ doesn't have such tricks. 00146 * 00147 * lambda {|a,b| [a,b] }.call(1,2,3) #=> ArgumentError 00148 * lambda {|a,b| [a,b] }.call(1) #=> ArgumentError 00149 * lambda {|a,b| [a,b] }.call([1,2]) #=> ArgumentError 00150 * 00151 * Proc#lambda? is a predicate for the tricks. 00152 * It returns +true+ if no tricks apply. 00153 * 00154 * lambda {}.lambda? #=> true 00155 * proc {}.lambda? #=> false 00156 * 00157 * Proc.new is the same as +proc+. 00158 * 00159 * Proc.new {}.lambda? #=> false 00160 * 00161 * +lambda+, +proc+ and Proc.new preserve the tricks of 00162 * a Proc object given by <code>&</code> argument. 00163 * 00164 * lambda(&lambda {}).lambda? #=> true 00165 * proc(&lambda {}).lambda? #=> true 00166 * Proc.new(&lambda {}).lambda? #=> true 00167 * 00168 * lambda(&proc {}).lambda? #=> false 00169 * proc(&proc {}).lambda? #=> false 00170 * Proc.new(&proc {}).lambda? #=> false 00171 * 00172 * A Proc object generated by <code>&</code> argument has the tricks 00173 * 00174 * def n(&b) b.lambda? end 00175 * n {} #=> false 00176 * 00177 * The <code>&</code> argument preserves the tricks if a Proc object 00178 * is given by <code>&</code> argument. 00179 * 00180 * n(&lambda {}) #=> true 00181 * n(&proc {}) #=> false 00182 * n(&Proc.new {}) #=> false 00183 * 00184 * A Proc object converted from a method has no tricks. 00185 * 00186 * def m() end 00187 * method(:m).to_proc.lambda? #=> true 00188 * 00189 * n(&method(:m)) #=> true 00190 * n(&method(:m).to_proc) #=> true 00191 * 00192 * +define_method+ is treated the same as method definition. 00193 * The defined method has no tricks. 00194 * 00195 * class C 00196 * define_method(:d) {} 00197 * end 00198 * C.new.d(1,2) #=> ArgumentError 00199 * C.new.method(:d).to_proc.lambda? #=> true 00200 * 00201 * +define_method+ always defines a method without the tricks, 00202 * even if a non-lambda Proc object is given. 00203 * This is the only exception for which the tricks are not preserved. 00204 * 00205 * class C 00206 * define_method(:e, &proc {}) 00207 * end 00208 * C.new.e(1,2) #=> ArgumentError 00209 * C.new.method(:e).to_proc.lambda? #=> true 00210 * 00211 * This exception insures that methods never have tricks 00212 * and makes it easy to have wrappers to define methods that behave as usual. 00213 * 00214 * class C 00215 * def self.def2(name, &body) 00216 * define_method(name, &body) 00217 * end 00218 * 00219 * def2(:f) {} 00220 * end 00221 * C.new.f(1,2) #=> ArgumentError 00222 * 00223 * The wrapper <i>def2</i> defines a method which has no tricks. 00224 * 00225 */ 00226 00227 VALUE 00228 rb_proc_lambda_p(VALUE procval) 00229 { 00230 rb_proc_t *proc; 00231 GetProcPtr(procval, proc); 00232 00233 return proc->is_lambda ? Qtrue : Qfalse; 00234 } 00235 00236 /* Binding */ 00237 00238 static void 00239 binding_free(void *ptr) 00240 { 00241 rb_binding_t *bind; 00242 RUBY_FREE_ENTER("binding"); 00243 if (ptr) { 00244 bind = ptr; 00245 ruby_xfree(ptr); 00246 } 00247 RUBY_FREE_LEAVE("binding"); 00248 } 00249 00250 static void 00251 binding_mark(void *ptr) 00252 { 00253 rb_binding_t *bind; 00254 RUBY_MARK_ENTER("binding"); 00255 if (ptr) { 00256 bind = ptr; 00257 RUBY_MARK_UNLESS_NULL(bind->env); 00258 RUBY_MARK_UNLESS_NULL(bind->filename); 00259 } 00260 RUBY_MARK_LEAVE("binding"); 00261 } 00262 00263 static size_t 00264 binding_memsize(const void *ptr) 00265 { 00266 return ptr ? sizeof(rb_binding_t) : 0; 00267 } 00268 00269 static const rb_data_type_t binding_data_type = { 00270 "binding", 00271 { 00272 binding_mark, 00273 binding_free, 00274 binding_memsize, 00275 }, 00276 }; 00277 00278 static VALUE 00279 binding_alloc(VALUE klass) 00280 { 00281 VALUE obj; 00282 rb_binding_t *bind; 00283 obj = TypedData_Make_Struct(klass, rb_binding_t, &binding_data_type, bind); 00284 return obj; 00285 } 00286 00287 /* :nodoc: */ 00288 static VALUE 00289 binding_dup(VALUE self) 00290 { 00291 VALUE bindval = binding_alloc(rb_cBinding); 00292 rb_binding_t *src, *dst; 00293 GetBindingPtr(self, src); 00294 GetBindingPtr(bindval, dst); 00295 dst->env = src->env; 00296 dst->filename = src->filename; 00297 dst->line_no = src->line_no; 00298 return bindval; 00299 } 00300 00301 /* :nodoc: */ 00302 static VALUE 00303 binding_clone(VALUE self) 00304 { 00305 VALUE bindval = binding_dup(self); 00306 CLONESETUP(bindval, self); 00307 return bindval; 00308 } 00309 00310 VALUE 00311 rb_binding_new(void) 00312 { 00313 rb_thread_t *th = GET_THREAD(); 00314 rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp); 00315 VALUE bindval = binding_alloc(rb_cBinding); 00316 rb_binding_t *bind; 00317 00318 if (cfp == 0) { 00319 rb_raise(rb_eRuntimeError, "Can't create Binding Object on top of Fiber."); 00320 } 00321 00322 GetBindingPtr(bindval, bind); 00323 bind->env = rb_vm_make_env_object(th, cfp); 00324 bind->filename = cfp->iseq->filename; 00325 bind->line_no = rb_vm_get_sourceline(cfp); 00326 return bindval; 00327 } 00328 00329 /* 00330 * call-seq: 00331 * binding -> a_binding 00332 * 00333 * Returns a +Binding+ object, describing the variable and 00334 * method bindings at the point of call. This object can be used when 00335 * calling +eval+ to execute the evaluated command in this 00336 * environment. See also the description of class +Binding+. 00337 * 00338 * def get_binding(param) 00339 * return binding 00340 * end 00341 * b = get_binding("hello") 00342 * eval("param", b) #=> "hello" 00343 */ 00344 00345 static VALUE 00346 rb_f_binding(VALUE self) 00347 { 00348 return rb_binding_new(); 00349 } 00350 00351 /* 00352 * call-seq: 00353 * binding.eval(string [, filename [,lineno]]) -> obj 00354 * 00355 * Evaluates the Ruby expression(s) in <em>string</em>, in the 00356 * <em>binding</em>'s context. If the optional <em>filename</em> and 00357 * <em>lineno</em> parameters are present, they will be used when 00358 * reporting syntax errors. 00359 * 00360 * def get_binding(param) 00361 * return binding 00362 * end 00363 * b = get_binding("hello") 00364 * b.eval("param") #=> "hello" 00365 */ 00366 00367 static VALUE 00368 bind_eval(int argc, VALUE *argv, VALUE bindval) 00369 { 00370 VALUE args[4]; 00371 00372 rb_scan_args(argc, argv, "12", &args[0], &args[2], &args[3]); 00373 args[1] = bindval; 00374 return rb_f_eval(argc+1, args, Qnil /* self will be searched in eval */); 00375 } 00376 00377 static VALUE 00378 proc_new(VALUE klass, int is_lambda) 00379 { 00380 VALUE procval = Qnil; 00381 rb_thread_t *th = GET_THREAD(); 00382 rb_control_frame_t *cfp = th->cfp; 00383 rb_block_t *block; 00384 00385 if ((GC_GUARDED_PTR_REF(cfp->lfp[0])) != 0) { 00386 00387 block = GC_GUARDED_PTR_REF(cfp->lfp[0]); 00388 } 00389 else { 00390 cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); 00391 00392 if ((GC_GUARDED_PTR_REF(cfp->lfp[0])) != 0) { 00393 00394 block = GC_GUARDED_PTR_REF(cfp->lfp[0]); 00395 00396 if (is_lambda) { 00397 rb_warn("tried to create Proc object without a block"); 00398 } 00399 } 00400 else { 00401 rb_raise(rb_eArgError, 00402 "tried to create Proc object without a block"); 00403 } 00404 } 00405 00406 procval = block->proc; 00407 00408 if (procval) { 00409 if (RBASIC(procval)->klass == klass) { 00410 return procval; 00411 } 00412 else { 00413 VALUE newprocval = proc_dup(procval); 00414 RBASIC(newprocval)->klass = klass; 00415 return newprocval; 00416 } 00417 } 00418 00419 procval = rb_vm_make_proc(th, block, klass); 00420 00421 if (is_lambda) { 00422 rb_proc_t *proc; 00423 GetProcPtr(procval, proc); 00424 proc->is_lambda = TRUE; 00425 } 00426 return procval; 00427 } 00428 00429 /* 00430 * call-seq: 00431 * Proc.new {|...| block } -> a_proc 00432 * Proc.new -> a_proc 00433 * 00434 * Creates a new <code>Proc</code> object, bound to the current 00435 * context. <code>Proc::new</code> may be called without a block only 00436 * within a method with an attached block, in which case that block is 00437 * converted to the <code>Proc</code> object. 00438 * 00439 * def proc_from 00440 * Proc.new 00441 * end 00442 * proc = proc_from { "hello" } 00443 * proc.call #=> "hello" 00444 */ 00445 00446 static VALUE 00447 rb_proc_s_new(int argc, VALUE *argv, VALUE klass) 00448 { 00449 VALUE block = proc_new(klass, FALSE); 00450 00451 rb_obj_call_init(block, argc, argv); 00452 return block; 00453 } 00454 00455 /* 00456 * call-seq: 00457 * proc { |...| block } -> a_proc 00458 * 00459 * Equivalent to <code>Proc.new</code>. 00460 */ 00461 00462 VALUE 00463 rb_block_proc(void) 00464 { 00465 return proc_new(rb_cProc, FALSE); 00466 } 00467 00468 /* 00469 * call-seq: 00470 * lambda { |...| block } -> a_proc 00471 * 00472 * Equivalent to <code>Proc.new</code>, except the resulting Proc objects 00473 * check the number of parameters passed when called. 00474 */ 00475 00476 VALUE 00477 rb_block_lambda(void) 00478 { 00479 return proc_new(rb_cProc, TRUE); 00480 } 00481 00482 VALUE 00483 rb_f_lambda(void) 00484 { 00485 rb_warn("rb_f_lambda() is deprecated; use rb_block_proc() instead"); 00486 return rb_block_lambda(); 00487 } 00488 00489 /* Document-method: === 00490 * 00491 * call-seq: 00492 * proc === obj -> result_of_proc 00493 * 00494 * Invokes the block with +obj+ as the proc's parameter like Proc#call. It 00495 * is to allow a proc object to be a target of +when+ clause in a case 00496 * statement. 00497 */ 00498 00499 /* CHECKME: are the argument checking semantics correct? */ 00500 00501 /* 00502 * call-seq: 00503 * prc.call(params,...) -> obj 00504 * prc[params,...] -> obj 00505 * prc.(params,...) -> obj 00506 * 00507 * Invokes the block, setting the block's parameters to the values in 00508 * <i>params</i> using something close to method calling semantics. 00509 * Generates a warning if multiple values are passed to a proc that 00510 * expects just one (previously this silently converted the parameters 00511 * to an array). Note that prc.() invokes prc.call() with the parameters 00512 * given. It's a syntax sugar to hide "call". 00513 * 00514 * For procs created using <code>lambda</code> or <code>->()</code> an error 00515 * is generated if the wrong number of parameters are passed to a Proc with 00516 * multiple parameters. For procs created using <code>Proc.new</code> or 00517 * <code>Kernel.proc</code>, extra parameters are silently discarded. 00518 * 00519 * Returns the value of the last expression evaluated in the block. See 00520 * also <code>Proc#yield</code>. 00521 * 00522 * a_proc = Proc.new {|a, *b| b.collect {|i| i*a }} 00523 * a_proc.call(9, 1, 2, 3) #=> [9, 18, 27] 00524 * a_proc[9, 1, 2, 3] #=> [9, 18, 27] 00525 * a_proc = lambda {|a,b| a} 00526 * a_proc.call(1,2,3) 00527 * 00528 * <em>produces:</em> 00529 * 00530 * prog.rb:4:in `block in <main>': wrong number of arguments (3 for 2) (ArgumentError) 00531 * from prog.rb:5:in `call' 00532 * from prog.rb:5:in `<main>' 00533 * 00534 */ 00535 00536 static VALUE 00537 proc_call(int argc, VALUE *argv, VALUE procval) 00538 { 00539 rb_proc_t *proc; 00540 rb_block_t *blockptr = 0; 00541 rb_iseq_t *iseq; 00542 VALUE passed_procval; 00543 GetProcPtr(procval, proc); 00544 00545 iseq = proc->block.iseq; 00546 if (BUILTIN_TYPE(iseq) == T_NODE || iseq->arg_block != -1) { 00547 if (rb_block_given_p()) { 00548 rb_proc_t *passed_proc; 00549 RB_GC_GUARD(passed_procval) = rb_block_proc(); 00550 GetProcPtr(passed_procval, passed_proc); 00551 blockptr = &passed_proc->block; 00552 } 00553 } 00554 00555 return rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self, 00556 argc, argv, blockptr); 00557 } 00558 00559 #if SIZEOF_LONG > SIZEOF_INT 00560 static inline int 00561 check_argc(long argc) 00562 { 00563 if (argc > INT_MAX || argc < 0) { 00564 rb_raise(rb_eArgError, "too many arguments (%lu)", 00565 (unsigned long)argc); 00566 } 00567 return (int)argc; 00568 } 00569 #else 00570 #define check_argc(argc) (argc) 00571 #endif 00572 00573 VALUE 00574 rb_proc_call(VALUE self, VALUE args) 00575 { 00576 rb_proc_t *proc; 00577 GetProcPtr(self, proc); 00578 return rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self, 00579 check_argc(RARRAY_LEN(args)), RARRAY_PTR(args), 0); 00580 } 00581 00582 VALUE 00583 rb_proc_call_with_block(VALUE self, int argc, VALUE *argv, VALUE pass_procval) 00584 { 00585 rb_proc_t *proc; 00586 rb_block_t *block = 0; 00587 GetProcPtr(self, proc); 00588 00589 if (!NIL_P(pass_procval)) { 00590 rb_proc_t *pass_proc; 00591 GetProcPtr(pass_procval, pass_proc); 00592 block = &pass_proc->block; 00593 } 00594 00595 return rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self, 00596 argc, argv, block); 00597 } 00598 00599 /* 00600 * call-seq: 00601 * prc.arity -> fixnum 00602 * 00603 * Returns the number of arguments that would not be ignored. If the block 00604 * is declared to take no arguments, returns 0. If the block is known 00605 * to take exactly n arguments, returns n. If the block has optional 00606 * arguments, return -n-1, where n is the number of mandatory 00607 * arguments. A <code>proc</code> with no argument declarations 00608 * is the same a block declaring <code>||</code> as its arguments. 00609 * 00610 * Proc.new {}.arity #=> 0 00611 * Proc.new {||}.arity #=> 0 00612 * Proc.new {|a|}.arity #=> 1 00613 * Proc.new {|a,b|}.arity #=> 2 00614 * Proc.new {|a,b,c|}.arity #=> 3 00615 * Proc.new {|*a|}.arity #=> -1 00616 * Proc.new {|a,*b|}.arity #=> -2 00617 * Proc.new {|a,*b, c|}.arity #=> -3 00618 */ 00619 00620 static VALUE 00621 proc_arity(VALUE self) 00622 { 00623 int arity = rb_proc_arity(self); 00624 return INT2FIX(arity); 00625 } 00626 00627 int 00628 rb_proc_arity(VALUE self) 00629 { 00630 rb_proc_t *proc; 00631 rb_iseq_t *iseq; 00632 GetProcPtr(self, proc); 00633 iseq = proc->block.iseq; 00634 if (iseq) { 00635 if (BUILTIN_TYPE(iseq) != T_NODE) { 00636 if (iseq->arg_rest < 0) { 00637 return iseq->argc; 00638 } 00639 else { 00640 return -(iseq->argc + 1 + iseq->arg_post_len); 00641 } 00642 } 00643 else { 00644 NODE *node = (NODE *)iseq; 00645 if (IS_METHOD_PROC_NODE(node)) { 00646 /* method(:foo).to_proc.arity */ 00647 return method_arity(node->nd_tval); 00648 } 00649 } 00650 } 00651 return -1; 00652 } 00653 00654 #define get_proc_iseq rb_proc_get_iseq 00655 00656 rb_iseq_t * 00657 rb_proc_get_iseq(VALUE self, int *is_proc) 00658 { 00659 rb_proc_t *proc; 00660 rb_iseq_t *iseq; 00661 00662 GetProcPtr(self, proc); 00663 iseq = proc->block.iseq; 00664 if (is_proc) *is_proc = !proc->is_lambda; 00665 if (!RUBY_VM_NORMAL_ISEQ_P(iseq)) { 00666 NODE *node = (NODE *)iseq; 00667 iseq = 0; 00668 if (IS_METHOD_PROC_NODE(node)) { 00669 /* method(:foo).to_proc */ 00670 iseq = rb_method_get_iseq(node->nd_tval); 00671 if (is_proc) *is_proc = 0; 00672 } 00673 } 00674 return iseq; 00675 } 00676 00677 static VALUE 00678 iseq_location(rb_iseq_t *iseq) 00679 { 00680 VALUE loc[2]; 00681 00682 if (!iseq) return Qnil; 00683 loc[0] = iseq->filename; 00684 if (iseq->insn_info_table) { 00685 loc[1] = INT2FIX(rb_iseq_first_lineno(iseq)); 00686 } 00687 else { 00688 loc[1] = Qnil; 00689 } 00690 return rb_ary_new4(2, loc); 00691 } 00692 00693 /* 00694 * call-seq: 00695 * prc.source_location -> [String, Fixnum] 00696 * 00697 * Returns the Ruby source filename and line number containing this proc 00698 * or +nil+ if this proc was not defined in Ruby (i.e. native) 00699 */ 00700 00701 VALUE 00702 rb_proc_location(VALUE self) 00703 { 00704 return iseq_location(get_proc_iseq(self, 0)); 00705 } 00706 00707 static VALUE 00708 unnamed_parameters(int arity) 00709 { 00710 VALUE a, param = rb_ary_new2((arity < 0) ? -arity : arity); 00711 int n = (arity < 0) ? ~arity : arity; 00712 ID req, rest; 00713 CONST_ID(req, "req"); 00714 a = rb_ary_new3(1, ID2SYM(req)); 00715 OBJ_FREEZE(a); 00716 for (; n; --n) { 00717 rb_ary_push(param, a); 00718 } 00719 if (arity < 0) { 00720 CONST_ID(rest, "rest"); 00721 rb_ary_store(param, ~arity, rb_ary_new3(1, ID2SYM(rest))); 00722 } 00723 return param; 00724 } 00725 00726 /* 00727 * call-seq: 00728 * prc.parameters -> array 00729 * 00730 * Returns the parameter information of this proc. 00731 * 00732 * prc = lambda{|x, y=42, *other|} 00733 * prc.parameters #=> [[:req, :x], [:opt, :y], [:rest, :other]] 00734 */ 00735 00736 static VALUE 00737 rb_proc_parameters(VALUE self) 00738 { 00739 int is_proc; 00740 rb_iseq_t *iseq = get_proc_iseq(self, &is_proc); 00741 if (!iseq) { 00742 return unnamed_parameters(rb_proc_arity(self)); 00743 } 00744 return rb_iseq_parameters(iseq, is_proc); 00745 } 00746 00747 /* 00748 * call-seq: 00749 * prc == other_proc -> true or false 00750 * 00751 * Returns <code>true</code> if <i>prc</i> is the same object as 00752 * <i>other_proc</i>, or if they are both procs with the same body. 00753 */ 00754 00755 static VALUE 00756 proc_eq(VALUE self, VALUE other) 00757 { 00758 if (self == other) { 00759 return Qtrue; 00760 } 00761 else { 00762 if (rb_obj_is_proc(other)) { 00763 rb_proc_t *p1, *p2; 00764 GetProcPtr(self, p1); 00765 GetProcPtr(other, p2); 00766 if (p1->envval == p2->envval && 00767 p1->block.iseq->iseq_size == p2->block.iseq->iseq_size && 00768 p1->block.iseq->local_size == p2->block.iseq->local_size && 00769 MEMCMP(p1->block.iseq->iseq, p2->block.iseq->iseq, VALUE, 00770 p1->block.iseq->iseq_size) == 0) { 00771 return Qtrue; 00772 } 00773 } 00774 } 00775 return Qfalse; 00776 } 00777 00778 /* 00779 * call-seq: 00780 * prc.hash -> integer 00781 * 00782 * Returns a hash value corresponding to proc body. 00783 */ 00784 00785 static VALUE 00786 proc_hash(VALUE self) 00787 { 00788 st_index_t hash; 00789 rb_proc_t *proc; 00790 GetProcPtr(self, proc); 00791 hash = rb_hash_start((st_index_t)proc->block.iseq); 00792 hash = rb_hash_uint(hash, (st_index_t)proc->envval); 00793 hash = rb_hash_uint(hash, (st_index_t)proc->block.lfp >> 16); 00794 hash = rb_hash_end(hash); 00795 return LONG2FIX(hash); 00796 } 00797 00798 /* 00799 * call-seq: 00800 * prc.to_s -> string 00801 * 00802 * Returns the unique identifier for this proc, along with 00803 * an indication of where the proc was defined. 00804 */ 00805 00806 static VALUE 00807 proc_to_s(VALUE self) 00808 { 00809 VALUE str = 0; 00810 rb_proc_t *proc; 00811 const char *cname = rb_obj_classname(self); 00812 rb_iseq_t *iseq; 00813 const char *is_lambda; 00814 00815 GetProcPtr(self, proc); 00816 iseq = proc->block.iseq; 00817 is_lambda = proc->is_lambda ? " (lambda)" : ""; 00818 00819 if (RUBY_VM_NORMAL_ISEQ_P(iseq)) { 00820 int line_no = 0; 00821 00822 if (iseq->insn_info_table) { 00823 line_no = rb_iseq_first_lineno(iseq); 00824 } 00825 str = rb_sprintf("#<%s:%p@%s:%d%s>", cname, (void *)self, 00826 RSTRING_PTR(iseq->filename), 00827 line_no, is_lambda); 00828 } 00829 else { 00830 str = rb_sprintf("#<%s:%p%s>", cname, (void *)proc->block.iseq, 00831 is_lambda); 00832 } 00833 00834 if (OBJ_TAINTED(self)) { 00835 OBJ_TAINT(str); 00836 } 00837 return str; 00838 } 00839 00840 /* 00841 * call-seq: 00842 * prc.to_proc -> prc 00843 * 00844 * Part of the protocol for converting objects to <code>Proc</code> 00845 * objects. Instances of class <code>Proc</code> simply return 00846 * themselves. 00847 */ 00848 00849 static VALUE 00850 proc_to_proc(VALUE self) 00851 { 00852 return self; 00853 } 00854 00855 static void 00856 bm_mark(void *ptr) 00857 { 00858 struct METHOD *data = ptr; 00859 rb_gc_mark(data->rclass); 00860 rb_gc_mark(data->recv); 00861 if (data->me) rb_mark_method_entry(data->me); 00862 } 00863 00864 static void 00865 bm_free(void *ptr) 00866 { 00867 struct METHOD *data = ptr; 00868 struct unlinked_method_entry_list_entry *ume = data->ume; 00869 ume->me = data->me; 00870 ume->next = GET_VM()->unlinked_method_entry_list; 00871 GET_VM()->unlinked_method_entry_list = ume; 00872 xfree(ptr); 00873 } 00874 00875 static size_t 00876 bm_memsize(const void *ptr) 00877 { 00878 return ptr ? sizeof(struct METHOD) : 0; 00879 } 00880 00881 static const rb_data_type_t method_data_type = { 00882 "method", 00883 { 00884 bm_mark, 00885 bm_free, 00886 bm_memsize, 00887 }, 00888 }; 00889 00890 VALUE 00891 rb_obj_is_method(VALUE m) 00892 { 00893 if (rb_typeddata_is_kind_of(m, &method_data_type)) { 00894 return Qtrue; 00895 } 00896 else { 00897 return Qfalse; 00898 } 00899 } 00900 00901 static VALUE 00902 mnew(VALUE klass, VALUE obj, ID id, VALUE mclass, int scope) 00903 { 00904 VALUE method; 00905 VALUE rclass = klass; 00906 ID rid = id; 00907 struct METHOD *data; 00908 rb_method_entry_t *me, meb; 00909 rb_method_definition_t *def = 0; 00910 rb_method_flag_t flag = NOEX_UNDEF; 00911 00912 again: 00913 me = rb_method_entry(klass, id); 00914 if (UNDEFINED_METHOD_ENTRY_P(me)) { 00915 ID rmiss = rb_intern("respond_to_missing?"); 00916 VALUE sym = ID2SYM(id); 00917 00918 if (obj != Qundef && !rb_method_basic_definition_p(klass, rmiss)) { 00919 if (RTEST(rb_funcall(obj, rmiss, 2, sym, scope ? Qfalse : Qtrue))) { 00920 def = ALLOC(rb_method_definition_t); 00921 def->type = VM_METHOD_TYPE_MISSING; 00922 def->original_id = id; 00923 def->alias_count = 0; 00924 00925 meb.flag = 0; 00926 meb.mark = 0; 00927 meb.called_id = id; 00928 meb.klass = klass; 00929 meb.def = def; 00930 me = &meb; 00931 def = 0; 00932 00933 goto gen_method; 00934 } 00935 } 00936 rb_print_undef(klass, id, 0); 00937 } 00938 def = me->def; 00939 if (flag == NOEX_UNDEF) { 00940 flag = me->flag; 00941 if (scope && (flag & NOEX_MASK) != NOEX_PUBLIC) { 00942 const char *v = ""; 00943 switch (flag & NOEX_MASK) { 00944 case NOEX_PRIVATE: v = "private"; break; 00945 case NOEX_PROTECTED: v = "protected"; break; 00946 } 00947 rb_name_error(id, "method `%s' for %s `%s' is %s", 00948 rb_id2name(id), 00949 (TYPE(klass) == T_MODULE) ? "module" : "class", 00950 rb_class2name(klass), 00951 v); 00952 } 00953 } 00954 if (def && def->type == VM_METHOD_TYPE_ZSUPER) { 00955 klass = RCLASS_SUPER(me->klass); 00956 id = def->original_id; 00957 goto again; 00958 } 00959 00960 klass = me->klass; 00961 00962 while (rclass != klass && 00963 (FL_TEST(rclass, FL_SINGLETON) || TYPE(rclass) == T_ICLASS)) { 00964 rclass = RCLASS_SUPER(rclass); 00965 } 00966 00967 if (TYPE(klass) == T_ICLASS) { 00968 klass = RBASIC(klass)->klass; 00969 } 00970 00971 gen_method: 00972 method = TypedData_Make_Struct(mclass, struct METHOD, &method_data_type, data); 00973 00974 data->recv = obj; 00975 data->rclass = rclass; 00976 data->id = rid; 00977 data->me = ALLOC(rb_method_entry_t); 00978 *data->me = *me; 00979 data->me->def->alias_count++; 00980 data->ume = ALLOC(struct unlinked_method_entry_list_entry); 00981 00982 OBJ_INFECT(method, klass); 00983 00984 return method; 00985 } 00986 00987 00988 /********************************************************************** 00989 * 00990 * Document-class : Method 00991 * 00992 * Method objects are created by <code>Object#method</code>, and are 00993 * associated with a particular object (not just with a class). They 00994 * may be used to invoke the method within the object, and as a block 00995 * associated with an iterator. They may also be unbound from one 00996 * object (creating an <code>UnboundMethod</code>) and bound to 00997 * another. 00998 * 00999 * class Thing 01000 * def square(n) 01001 * n*n 01002 * end 01003 * end 01004 * thing = Thing.new 01005 * meth = thing.method(:square) 01006 * 01007 * meth.call(9) #=> 81 01008 * [ 1, 2, 3 ].collect(&meth) #=> [1, 4, 9] 01009 * 01010 */ 01011 01012 /* 01013 * call-seq: 01014 * meth == other_meth -> true or false 01015 * 01016 * Two method objects are equal if they are bound to the same 01017 * object and refer to the same method definition. 01018 */ 01019 01020 static VALUE 01021 method_eq(VALUE method, VALUE other) 01022 { 01023 struct METHOD *m1, *m2; 01024 01025 if (!rb_obj_is_method(other)) 01026 return Qfalse; 01027 if (CLASS_OF(method) != CLASS_OF(other)) 01028 return Qfalse; 01029 01030 Check_TypedStruct(method, &method_data_type); 01031 m1 = (struct METHOD *)DATA_PTR(method); 01032 m2 = (struct METHOD *)DATA_PTR(other); 01033 01034 if (!rb_method_entry_eq(m1->me, m2->me) || 01035 m1->rclass != m2->rclass || 01036 m1->recv != m2->recv) { 01037 return Qfalse; 01038 } 01039 01040 return Qtrue; 01041 } 01042 01043 /* 01044 * call-seq: 01045 * meth.hash -> integer 01046 * 01047 * Returns a hash value corresponding to the method object. 01048 */ 01049 01050 static VALUE 01051 method_hash(VALUE method) 01052 { 01053 struct METHOD *m; 01054 st_index_t hash; 01055 01056 TypedData_Get_Struct(method, struct METHOD, &method_data_type, m); 01057 hash = rb_hash_start((st_index_t)m->rclass); 01058 hash = rb_hash_uint(hash, (st_index_t)m->recv); 01059 hash = rb_hash_uint(hash, (st_index_t)m->me->def); 01060 hash = rb_hash_end(hash); 01061 01062 return INT2FIX(hash); 01063 } 01064 01065 /* 01066 * call-seq: 01067 * meth.unbind -> unbound_method 01068 * 01069 * Dissociates <i>meth</i> from its current receiver. The resulting 01070 * <code>UnboundMethod</code> can subsequently be bound to a new object 01071 * of the same class (see <code>UnboundMethod</code>). 01072 */ 01073 01074 static VALUE 01075 method_unbind(VALUE obj) 01076 { 01077 VALUE method; 01078 struct METHOD *orig, *data; 01079 01080 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, orig); 01081 method = TypedData_Make_Struct(rb_cUnboundMethod, struct METHOD, 01082 &method_data_type, data); 01083 data->recv = Qundef; 01084 data->id = orig->id; 01085 data->me = ALLOC(rb_method_entry_t); 01086 *data->me = *orig->me; 01087 if (orig->me->def) orig->me->def->alias_count++; 01088 data->rclass = orig->rclass; 01089 data->ume = ALLOC(struct unlinked_method_entry_list_entry); 01090 OBJ_INFECT(method, obj); 01091 01092 return method; 01093 } 01094 01095 /* 01096 * call-seq: 01097 * meth.receiver -> object 01098 * 01099 * Returns the bound receiver of the method object. 01100 */ 01101 01102 static VALUE 01103 method_receiver(VALUE obj) 01104 { 01105 struct METHOD *data; 01106 01107 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data); 01108 return data->recv; 01109 } 01110 01111 /* 01112 * call-seq: 01113 * meth.name -> symbol 01114 * 01115 * Returns the name of the method. 01116 */ 01117 01118 static VALUE 01119 method_name(VALUE obj) 01120 { 01121 struct METHOD *data; 01122 01123 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data); 01124 return ID2SYM(data->id); 01125 } 01126 01127 /* 01128 * call-seq: 01129 * meth.owner -> class_or_module 01130 * 01131 * Returns the class or module that defines the method. 01132 */ 01133 01134 static VALUE 01135 method_owner(VALUE obj) 01136 { 01137 struct METHOD *data; 01138 01139 TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data); 01140 return data->me->klass; 01141 } 01142 01143 /* 01144 * call-seq: 01145 * obj.method(sym) -> method 01146 * 01147 * Looks up the named method as a receiver in <i>obj</i>, returning a 01148 * <code>Method</code> object (or raising <code>NameError</code>). The 01149 * <code>Method</code> object acts as a closure in <i>obj</i>'s object 01150 * instance, so instance variables and the value of <code>self</code> 01151 * remain available. 01152 * 01153 * class Demo 01154 * def initialize(n) 01155 * @iv = n 01156 * end 01157 * def hello() 01158 * "Hello, @iv = #{@iv}" 01159 * end 01160 * end 01161 * 01162 * k = Demo.new(99) 01163 * m = k.method(:hello) 01164 * m.call #=> "Hello, @iv = 99" 01165 * 01166 * l = Demo.new('Fred') 01167 * m = l.method("hello") 01168 * m.call #=> "Hello, @iv = Fred" 01169 */ 01170 01171 VALUE 01172 rb_obj_method(VALUE obj, VALUE vid) 01173 { 01174 return mnew(CLASS_OF(obj), obj, rb_to_id(vid), rb_cMethod, FALSE); 01175 } 01176 01177 /* 01178 * call-seq: 01179 * obj.public_method(sym) -> method 01180 * 01181 * Similar to _method_, searches public method only. 01182 */ 01183 01184 VALUE 01185 rb_obj_public_method(VALUE obj, VALUE vid) 01186 { 01187 return mnew(CLASS_OF(obj), obj, rb_to_id(vid), rb_cMethod, TRUE); 01188 } 01189 01190 /* 01191 * call-seq: 01192 * mod.instance_method(symbol) -> unbound_method 01193 * 01194 * Returns an +UnboundMethod+ representing the given 01195 * instance method in _mod_. 01196 * 01197 * class Interpreter 01198 * def do_a() print "there, "; end 01199 * def do_d() print "Hello "; end 01200 * def do_e() print "!\n"; end 01201 * def do_v() print "Dave"; end 01202 * Dispatcher = { 01203 * "a" => instance_method(:do_a), 01204 * "d" => instance_method(:do_d), 01205 * "e" => instance_method(:do_e), 01206 * "v" => instance_method(:do_v) 01207 * } 01208 * def interpret(string) 01209 * string.each_char {|b| Dispatcher[b].bind(self).call } 01210 * end 01211 * end 01212 * 01213 * interpreter = Interpreter.new 01214 * interpreter.interpret('dave') 01215 * 01216 * <em>produces:</em> 01217 * 01218 * Hello there, Dave! 01219 */ 01220 01221 static VALUE 01222 rb_mod_instance_method(VALUE mod, VALUE vid) 01223 { 01224 return mnew(mod, Qundef, rb_to_id(vid), rb_cUnboundMethod, FALSE); 01225 } 01226 01227 /* 01228 * call-seq: 01229 * mod.public_instance_method(symbol) -> unbound_method 01230 * 01231 * Similar to _instance_method_, searches public method only. 01232 */ 01233 01234 static VALUE 01235 rb_mod_public_instance_method(VALUE mod, VALUE vid) 01236 { 01237 return mnew(mod, Qundef, rb_to_id(vid), rb_cUnboundMethod, TRUE); 01238 } 01239 01240 /* 01241 * call-seq: 01242 * define_method(symbol, method) -> new_method 01243 * define_method(symbol) { block } -> proc 01244 * 01245 * Defines an instance method in the receiver. The _method_ 01246 * parameter can be a +Proc+, a +Method+ or an +UnboundMethod+ object. 01247 * If a block is specified, it is used as the method body. This block 01248 * is evaluated using <code>instance_eval</code>, a point that is 01249 * tricky to demonstrate because <code>define_method</code> is private. 01250 * (This is why we resort to the +send+ hack in this example.) 01251 * 01252 * class A 01253 * def fred 01254 * puts "In Fred" 01255 * end 01256 * def create_method(name, &block) 01257 * self.class.send(:define_method, name, &block) 01258 * end 01259 * define_method(:wilma) { puts "Charge it!" } 01260 * end 01261 * class B < A 01262 * define_method(:barney, instance_method(:fred)) 01263 * end 01264 * a = B.new 01265 * a.barney 01266 * a.wilma 01267 * a.create_method(:betty) { p self } 01268 * a.betty 01269 * 01270 * <em>produces:</em> 01271 * 01272 * In Fred 01273 * Charge it! 01274 * #<B:0x401b39e8> 01275 */ 01276 01277 static VALUE 01278 rb_mod_define_method(int argc, VALUE *argv, VALUE mod) 01279 { 01280 ID id; 01281 VALUE body; 01282 int noex = NOEX_PUBLIC; 01283 01284 if (argc == 1) { 01285 id = rb_to_id(argv[0]); 01286 body = rb_block_lambda(); 01287 } 01288 else if (argc == 2) { 01289 id = rb_to_id(argv[0]); 01290 body = argv[1]; 01291 if (!rb_obj_is_method(body) && !rb_obj_is_proc(body)) { 01292 rb_raise(rb_eTypeError, 01293 "wrong argument type %s (expected Proc/Method)", 01294 rb_obj_classname(body)); 01295 } 01296 } 01297 else { 01298 rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc); 01299 } 01300 01301 if (rb_obj_is_method(body)) { 01302 struct METHOD *method = (struct METHOD *)DATA_PTR(body); 01303 VALUE rclass = method->rclass; 01304 if (rclass != mod && !RTEST(rb_class_inherited_p(mod, rclass))) { 01305 if (FL_TEST(rclass, FL_SINGLETON)) { 01306 rb_raise(rb_eTypeError, 01307 "can't bind singleton method to a different class"); 01308 } 01309 else { 01310 rb_raise(rb_eTypeError, 01311 "bind argument must be a subclass of %s", 01312 rb_class2name(rclass)); 01313 } 01314 } 01315 rb_method_entry_set(mod, id, method->me, noex); 01316 } 01317 else if (rb_obj_is_proc(body)) { 01318 rb_proc_t *proc; 01319 body = proc_dup(body); 01320 GetProcPtr(body, proc); 01321 if (BUILTIN_TYPE(proc->block.iseq) != T_NODE) { 01322 proc->block.iseq->defined_method_id = id; 01323 proc->block.iseq->klass = mod; 01324 proc->is_lambda = TRUE; 01325 proc->is_from_method = TRUE; 01326 } 01327 rb_add_method(mod, id, VM_METHOD_TYPE_BMETHOD, (void *)body, noex); 01328 } 01329 else { 01330 /* type error */ 01331 rb_raise(rb_eTypeError, "wrong argument type (expected Proc/Method)"); 01332 } 01333 01334 return body; 01335 } 01336 01337 /* 01338 * call-seq: 01339 * define_singleton_method(symbol, method) -> new_method 01340 * define_singleton_method(symbol) { block } -> proc 01341 * 01342 * Defines a singleton method in the receiver. The _method_ 01343 * parameter can be a +Proc+, a +Method+ or an +UnboundMethod+ object. 01344 * If a block is specified, it is used as the method body. 01345 * 01346 * class A 01347 * class << self 01348 * def class_name 01349 * to_s 01350 * end 01351 * end 01352 * end 01353 * A.define_singleton_method(:who_am_i) do 01354 * "I am: #{class_name}" 01355 * end 01356 * A.who_am_i # ==> "I am: A" 01357 * 01358 * guy = "Bob" 01359 * guy.define_singleton_method(:hello) { "#{self}: Hello there!" } 01360 * guy.hello #=> "Bob: Hello there!" 01361 */ 01362 01363 static VALUE 01364 rb_obj_define_method(int argc, VALUE *argv, VALUE obj) 01365 { 01366 VALUE klass = rb_singleton_class(obj); 01367 01368 return rb_mod_define_method(argc, argv, klass); 01369 } 01370 01371 01372 /* 01373 * MISSING: documentation 01374 */ 01375 01376 static VALUE 01377 method_clone(VALUE self) 01378 { 01379 VALUE clone; 01380 struct METHOD *orig, *data; 01381 01382 TypedData_Get_Struct(self, struct METHOD, &method_data_type, orig); 01383 clone = TypedData_Make_Struct(CLASS_OF(self), struct METHOD, &method_data_type, data); 01384 CLONESETUP(clone, self); 01385 *data = *orig; 01386 data->me = ALLOC(rb_method_entry_t); 01387 *data->me = *orig->me; 01388 if (data->me->def) data->me->def->alias_count++; 01389 data->ume = ALLOC(struct unlinked_method_entry_list_entry); 01390 01391 return clone; 01392 } 01393 01394 /* 01395 * call-seq: 01396 * meth.call(args, ...) -> obj 01397 * meth[args, ...] -> obj 01398 * 01399 * Invokes the <i>meth</i> with the specified arguments, returning the 01400 * method's return value. 01401 * 01402 * m = 12.method("+") 01403 * m.call(3) #=> 15 01404 * m.call(20) #=> 32 01405 */ 01406 01407 VALUE 01408 rb_method_call(int argc, VALUE *argv, VALUE method) 01409 { 01410 VALUE proc = rb_block_given_p() ? rb_block_proc() : Qnil; 01411 return rb_method_call_with_block(argc, argv, method, proc); 01412 } 01413 01414 VALUE 01415 rb_method_call_with_block(int argc, VALUE *argv, VALUE method, VALUE pass_procval) 01416 { 01417 VALUE result = Qnil; /* OK */ 01418 struct METHOD *data; 01419 int state; 01420 volatile int safe = -1; 01421 01422 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); 01423 if (data->recv == Qundef) { 01424 rb_raise(rb_eTypeError, "can't call unbound method; bind first"); 01425 } 01426 PUSH_TAG(); 01427 if (OBJ_TAINTED(method)) { 01428 safe = rb_safe_level(); 01429 if (rb_safe_level() < 4) { 01430 rb_set_safe_level_force(4); 01431 } 01432 } 01433 if ((state = EXEC_TAG()) == 0) { 01434 rb_thread_t *th = GET_THREAD(); 01435 rb_block_t *block = 0; 01436 01437 if (!NIL_P(pass_procval)) { 01438 rb_proc_t *pass_proc; 01439 GetProcPtr(pass_procval, pass_proc); 01440 block = &pass_proc->block; 01441 } 01442 01443 th->passed_block = block; 01444 result = rb_vm_call(th, data->recv, data->id, argc, argv, data->me); 01445 } 01446 POP_TAG(); 01447 if (safe >= 0) 01448 rb_set_safe_level_force(safe); 01449 if (state) 01450 JUMP_TAG(state); 01451 return result; 01452 } 01453 01454 /********************************************************************** 01455 * 01456 * Document-class: UnboundMethod 01457 * 01458 * Ruby supports two forms of objectified methods. Class 01459 * <code>Method</code> is used to represent methods that are associated 01460 * with a particular object: these method objects are bound to that 01461 * object. Bound method objects for an object can be created using 01462 * <code>Object#method</code>. 01463 * 01464 * Ruby also supports unbound methods; methods objects that are not 01465 * associated with a particular object. These can be created either by 01466 * calling <code>Module#instance_method</code> or by calling 01467 * <code>unbind</code> on a bound method object. The result of both of 01468 * these is an <code>UnboundMethod</code> object. 01469 * 01470 * Unbound methods can only be called after they are bound to an 01471 * object. That object must be be a kind_of? the method's original 01472 * class. 01473 * 01474 * class Square 01475 * def area 01476 * @side * @side 01477 * end 01478 * def initialize(side) 01479 * @side = side 01480 * end 01481 * end 01482 * 01483 * area_un = Square.instance_method(:area) 01484 * 01485 * s = Square.new(12) 01486 * area = area_un.bind(s) 01487 * area.call #=> 144 01488 * 01489 * Unbound methods are a reference to the method at the time it was 01490 * objectified: subsequent changes to the underlying class will not 01491 * affect the unbound method. 01492 * 01493 * class Test 01494 * def test 01495 * :original 01496 * end 01497 * end 01498 * um = Test.instance_method(:test) 01499 * class Test 01500 * def test 01501 * :modified 01502 * end 01503 * end 01504 * t = Test.new 01505 * t.test #=> :modified 01506 * um.bind(t).call #=> :original 01507 * 01508 */ 01509 01510 /* 01511 * call-seq: 01512 * umeth.bind(obj) -> method 01513 * 01514 * Bind <i>umeth</i> to <i>obj</i>. If <code>Klass</code> was the class 01515 * from which <i>umeth</i> was obtained, 01516 * <code>obj.kind_of?(Klass)</code> must be true. 01517 * 01518 * class A 01519 * def test 01520 * puts "In test, class = #{self.class}" 01521 * end 01522 * end 01523 * class B < A 01524 * end 01525 * class C < B 01526 * end 01527 * 01528 * 01529 * um = B.instance_method(:test) 01530 * bm = um.bind(C.new) 01531 * bm.call 01532 * bm = um.bind(B.new) 01533 * bm.call 01534 * bm = um.bind(A.new) 01535 * bm.call 01536 * 01537 * <em>produces:</em> 01538 * 01539 * In test, class = C 01540 * In test, class = B 01541 * prog.rb:16:in `bind': bind argument must be an instance of B (TypeError) 01542 * from prog.rb:16 01543 */ 01544 01545 static VALUE 01546 umethod_bind(VALUE method, VALUE recv) 01547 { 01548 struct METHOD *data, *bound; 01549 01550 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); 01551 01552 if (data->rclass != CLASS_OF(recv) && !rb_obj_is_kind_of(recv, data->rclass)) { 01553 if (FL_TEST(data->rclass, FL_SINGLETON)) { 01554 rb_raise(rb_eTypeError, 01555 "singleton method called for a different object"); 01556 } 01557 else { 01558 rb_raise(rb_eTypeError, "bind argument must be an instance of %s", 01559 rb_class2name(data->rclass)); 01560 } 01561 } 01562 01563 method = TypedData_Make_Struct(rb_cMethod, struct METHOD, &method_data_type, bound); 01564 *bound = *data; 01565 bound->me = ALLOC(rb_method_entry_t); 01566 *bound->me = *data->me; 01567 if (bound->me->def) bound->me->def->alias_count++; 01568 bound->recv = recv; 01569 bound->rclass = CLASS_OF(recv); 01570 data->ume = ALLOC(struct unlinked_method_entry_list_entry); 01571 01572 return method; 01573 } 01574 01575 int 01576 rb_method_entry_arity(const rb_method_entry_t *me) 01577 { 01578 const rb_method_definition_t *def = me->def; 01579 if (!def) return 0; 01580 switch (def->type) { 01581 case VM_METHOD_TYPE_CFUNC: 01582 if (def->body.cfunc.argc < 0) 01583 return -1; 01584 return check_argc(def->body.cfunc.argc); 01585 case VM_METHOD_TYPE_ZSUPER: 01586 return -1; 01587 case VM_METHOD_TYPE_ATTRSET: 01588 return 1; 01589 case VM_METHOD_TYPE_IVAR: 01590 return 0; 01591 case VM_METHOD_TYPE_BMETHOD: 01592 return rb_proc_arity(def->body.proc); 01593 case VM_METHOD_TYPE_ISEQ: { 01594 rb_iseq_t *iseq = def->body.iseq; 01595 if (iseq->arg_rest == -1 && iseq->arg_opts == 0) { 01596 return iseq->argc; 01597 } 01598 else { 01599 return -(iseq->argc + 1 + iseq->arg_post_len); 01600 } 01601 } 01602 case VM_METHOD_TYPE_UNDEF: 01603 case VM_METHOD_TYPE_NOTIMPLEMENTED: 01604 return 0; 01605 case VM_METHOD_TYPE_MISSING: 01606 return -1; 01607 case VM_METHOD_TYPE_OPTIMIZED: { 01608 switch (def->body.optimize_type) { 01609 case OPTIMIZED_METHOD_TYPE_SEND: 01610 return -1; 01611 default: 01612 break; 01613 } 01614 } 01615 } 01616 rb_bug("rb_method_entry_arity: invalid method entry type (%d)", def->type); 01617 } 01618 01619 /* 01620 * call-seq: 01621 * meth.arity -> fixnum 01622 * 01623 * Returns an indication of the number of arguments accepted by a 01624 * method. Returns a nonnegative integer for methods that take a fixed 01625 * number of arguments. For Ruby methods that take a variable number of 01626 * arguments, returns -n-1, where n is the number of required 01627 * arguments. For methods written in C, returns -1 if the call takes a 01628 * variable number of arguments. 01629 * 01630 * class C 01631 * def one; end 01632 * def two(a); end 01633 * def three(*a); end 01634 * def four(a, b); end 01635 * def five(a, b, *c); end 01636 * def six(a, b, *c, &d); end 01637 * end 01638 * c = C.new 01639 * c.method(:one).arity #=> 0 01640 * c.method(:two).arity #=> 1 01641 * c.method(:three).arity #=> -1 01642 * c.method(:four).arity #=> 2 01643 * c.method(:five).arity #=> -3 01644 * c.method(:six).arity #=> -3 01645 * 01646 * "cat".method(:size).arity #=> 0 01647 * "cat".method(:replace).arity #=> 1 01648 * "cat".method(:squeeze).arity #=> -1 01649 * "cat".method(:count).arity #=> -1 01650 */ 01651 01652 static VALUE 01653 method_arity_m(VALUE method) 01654 { 01655 int n = method_arity(method); 01656 return INT2FIX(n); 01657 } 01658 01659 static int 01660 method_arity(VALUE method) 01661 { 01662 struct METHOD *data; 01663 01664 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); 01665 return rb_method_entry_arity(data->me); 01666 } 01667 01668 int 01669 rb_mod_method_arity(VALUE mod, ID id) 01670 { 01671 rb_method_entry_t *me = rb_method_entry(mod, id); 01672 return rb_method_entry_arity(me); 01673 } 01674 01675 int 01676 rb_obj_method_arity(VALUE obj, ID id) 01677 { 01678 return rb_mod_method_arity(CLASS_OF(obj), id); 01679 } 01680 01681 static inline rb_method_definition_t * 01682 method_get_def(VALUE method) 01683 { 01684 struct METHOD *data; 01685 01686 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); 01687 return data->me->def; 01688 } 01689 01690 static rb_iseq_t * 01691 method_get_iseq(rb_method_definition_t *def) 01692 { 01693 switch (def->type) { 01694 case VM_METHOD_TYPE_BMETHOD: 01695 return get_proc_iseq(def->body.proc, 0); 01696 case VM_METHOD_TYPE_ISEQ: 01697 return def->body.iseq; 01698 default: 01699 return 0; 01700 } 01701 } 01702 01703 rb_iseq_t * 01704 rb_method_get_iseq(VALUE method) 01705 { 01706 return method_get_iseq(method_get_def(method)); 01707 } 01708 01709 /* 01710 * call-seq: 01711 * meth.source_location -> [String, Fixnum] 01712 * 01713 * Returns the Ruby source filename and line number containing this method 01714 * or nil if this method was not defined in Ruby (i.e. native) 01715 */ 01716 01717 VALUE 01718 rb_method_location(VALUE method) 01719 { 01720 rb_method_definition_t *def = method_get_def(method); 01721 if (def->type == VM_METHOD_TYPE_ATTRSET || def->type == VM_METHOD_TYPE_IVAR) { 01722 if (!def->body.attr.location) 01723 return Qnil; 01724 return rb_ary_dup(def->body.attr.location); 01725 } 01726 return iseq_location(method_get_iseq(def)); 01727 } 01728 01729 /* 01730 * call-seq: 01731 * meth.parameters -> array 01732 * 01733 * Returns the parameter information of this method. 01734 */ 01735 01736 static VALUE 01737 rb_method_parameters(VALUE method) 01738 { 01739 rb_iseq_t *iseq = rb_method_get_iseq(method); 01740 if (!iseq) { 01741 return unnamed_parameters(method_arity(method)); 01742 } 01743 return rb_iseq_parameters(iseq, 0); 01744 } 01745 01746 /* 01747 * call-seq: 01748 * meth.to_s -> string 01749 * meth.inspect -> string 01750 * 01751 * Returns the name of the underlying method. 01752 * 01753 * "cat".method(:count).inspect #=> "#<Method: String#count>" 01754 */ 01755 01756 static VALUE 01757 method_inspect(VALUE method) 01758 { 01759 struct METHOD *data; 01760 VALUE str; 01761 const char *s; 01762 const char *sharp = "#"; 01763 01764 TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); 01765 str = rb_str_buf_new2("#<"); 01766 s = rb_obj_classname(method); 01767 rb_str_buf_cat2(str, s); 01768 rb_str_buf_cat2(str, ": "); 01769 01770 if (FL_TEST(data->me->klass, FL_SINGLETON)) { 01771 VALUE v = rb_iv_get(data->me->klass, "__attached__"); 01772 01773 if (data->recv == Qundef) { 01774 rb_str_buf_append(str, rb_inspect(data->me->klass)); 01775 } 01776 else if (data->recv == v) { 01777 rb_str_buf_append(str, rb_inspect(v)); 01778 sharp = "."; 01779 } 01780 else { 01781 rb_str_buf_append(str, rb_inspect(data->recv)); 01782 rb_str_buf_cat2(str, "("); 01783 rb_str_buf_append(str, rb_inspect(v)); 01784 rb_str_buf_cat2(str, ")"); 01785 sharp = "."; 01786 } 01787 } 01788 else { 01789 rb_str_buf_cat2(str, rb_class2name(data->rclass)); 01790 if (data->rclass != data->me->klass) { 01791 rb_str_buf_cat2(str, "("); 01792 rb_str_buf_cat2(str, rb_class2name(data->me->klass)); 01793 rb_str_buf_cat2(str, ")"); 01794 } 01795 } 01796 rb_str_buf_cat2(str, sharp); 01797 rb_str_append(str, rb_id2str(data->me->def->original_id)); 01798 if (data->me->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) { 01799 rb_str_buf_cat2(str, " (not-implemented)"); 01800 } 01801 rb_str_buf_cat2(str, ">"); 01802 01803 return str; 01804 } 01805 01806 static VALUE 01807 mproc(VALUE method) 01808 { 01809 return rb_funcall2(rb_mRubyVMFrozenCore, idProc, 0, 0); 01810 } 01811 01812 static VALUE 01813 mlambda(VALUE method) 01814 { 01815 return rb_funcall(rb_mRubyVMFrozenCore, idLambda, 0, 0); 01816 } 01817 01818 static VALUE 01819 bmcall(VALUE args, VALUE method, int argc, VALUE *argv, VALUE passed_proc) 01820 { 01821 volatile VALUE a; 01822 VALUE ret; 01823 01824 if (CLASS_OF(args) != rb_cArray) { 01825 args = rb_ary_new3(1, args); 01826 argc = 1; 01827 } 01828 else { 01829 argc = check_argc(RARRAY_LEN(args)); 01830 } 01831 ret = rb_method_call_with_block(argc, RARRAY_PTR(args), method, passed_proc); 01832 RB_GC_GUARD(a) = args; 01833 return ret; 01834 } 01835 01836 VALUE 01837 rb_proc_new( 01838 VALUE (*func)(ANYARGS), /* VALUE yieldarg[, VALUE procarg] */ 01839 VALUE val) 01840 { 01841 VALUE procval = rb_iterate(mproc, 0, func, val); 01842 return procval; 01843 } 01844 01845 /* 01846 * call-seq: 01847 * meth.to_proc -> prc 01848 * 01849 * Returns a <code>Proc</code> object corresponding to this method. 01850 */ 01851 01852 static VALUE 01853 method_proc(VALUE method) 01854 { 01855 VALUE procval; 01856 rb_proc_t *proc; 01857 /* 01858 * class Method 01859 * def to_proc 01860 * proc{|*args| 01861 * self.call(*args) 01862 * } 01863 * end 01864 * end 01865 */ 01866 procval = rb_iterate(mlambda, 0, bmcall, method); 01867 GetProcPtr(procval, proc); 01868 proc->is_from_method = 1; 01869 return procval; 01870 } 01871 01872 /* 01873 * call_seq: 01874 * local_jump_error.exit_value -> obj 01875 * 01876 * Returns the exit value associated with this +LocalJumpError+. 01877 */ 01878 static VALUE 01879 localjump_xvalue(VALUE exc) 01880 { 01881 return rb_iv_get(exc, "@exit_value"); 01882 } 01883 01884 /* 01885 * call-seq: 01886 * local_jump_error.reason -> symbol 01887 * 01888 * The reason this block was terminated: 01889 * :break, :redo, :retry, :next, :return, or :noreason. 01890 */ 01891 01892 static VALUE 01893 localjump_reason(VALUE exc) 01894 { 01895 return rb_iv_get(exc, "@reason"); 01896 } 01897 01898 /* 01899 * call-seq: 01900 * prc.binding -> binding 01901 * 01902 * Returns the binding associated with <i>prc</i>. Note that 01903 * <code>Kernel#eval</code> accepts either a <code>Proc</code> or a 01904 * <code>Binding</code> object as its second parameter. 01905 * 01906 * def fred(param) 01907 * proc {} 01908 * end 01909 * 01910 * b = fred(99) 01911 * eval("param", b.binding) #=> 99 01912 */ 01913 static VALUE 01914 proc_binding(VALUE self) 01915 { 01916 rb_proc_t *proc; 01917 VALUE bindval; 01918 rb_binding_t *bind; 01919 01920 GetProcPtr(self, proc); 01921 if (TYPE(proc->block.iseq) == T_NODE) { 01922 if (!IS_METHOD_PROC_NODE((NODE *)proc->block.iseq)) { 01923 rb_raise(rb_eArgError, "Can't create Binding from C level Proc"); 01924 } 01925 } 01926 01927 bindval = binding_alloc(rb_cBinding); 01928 GetBindingPtr(bindval, bind); 01929 bind->env = proc->envval; 01930 if (RUBY_VM_NORMAL_ISEQ_P(proc->block.iseq)) { 01931 bind->filename = proc->block.iseq->filename; 01932 bind->line_no = rb_iseq_first_lineno(proc->block.iseq); 01933 } 01934 else { 01935 bind->filename = Qnil; 01936 bind->line_no = 0; 01937 } 01938 return bindval; 01939 } 01940 01941 static VALUE curry(VALUE dummy, VALUE args, int argc, VALUE *argv, VALUE passed_proc); 01942 01943 static VALUE 01944 make_curry_proc(VALUE proc, VALUE passed, VALUE arity) 01945 { 01946 VALUE args = rb_ary_new3(3, proc, passed, arity); 01947 rb_proc_t *procp; 01948 int is_lambda; 01949 01950 GetProcPtr(proc, procp); 01951 is_lambda = procp->is_lambda; 01952 rb_ary_freeze(passed); 01953 rb_ary_freeze(args); 01954 proc = rb_proc_new(curry, args); 01955 GetProcPtr(proc, procp); 01956 procp->is_lambda = is_lambda; 01957 return proc; 01958 } 01959 01960 static VALUE 01961 curry(VALUE dummy, VALUE args, int argc, VALUE *argv, VALUE passed_proc) 01962 { 01963 VALUE proc, passed, arity; 01964 proc = RARRAY_PTR(args)[0]; 01965 passed = RARRAY_PTR(args)[1]; 01966 arity = RARRAY_PTR(args)[2]; 01967 01968 passed = rb_ary_plus(passed, rb_ary_new4(argc, argv)); 01969 rb_ary_freeze(passed); 01970 01971 if (RARRAY_LEN(passed) < FIX2INT(arity)) { 01972 if (!NIL_P(passed_proc)) { 01973 rb_warn("given block not used"); 01974 } 01975 arity = make_curry_proc(proc, passed, arity); 01976 return arity; 01977 } 01978 else { 01979 return rb_proc_call_with_block(proc, check_argc(RARRAY_LEN(passed)), 01980 RARRAY_PTR(passed), passed_proc); 01981 } 01982 } 01983 01984 /* 01985 * call-seq: 01986 * prc.curry -> a_proc 01987 * prc.curry(arity) -> a_proc 01988 * 01989 * Returns a curried proc. If the optional <i>arity</i> argument is given, 01990 * it determines the number of arguments. 01991 * A curried proc receives some arguments. If a sufficient number of 01992 * arguments are supplied, it passes the supplied arguments to the original 01993 * proc and returns the result. Otherwise, returns another curried proc that 01994 * takes the rest of arguments. 01995 * 01996 * b = proc {|x, y, z| (x||0) + (y||0) + (z||0) } 01997 * p b.curry[1][2][3] #=> 6 01998 * p b.curry[1, 2][3, 4] #=> 6 01999 * p b.curry(5)[1][2][3][4][5] #=> 6 02000 * p b.curry(5)[1, 2][3, 4][5] #=> 6 02001 * p b.curry(1)[1] #=> 1 02002 * 02003 * b = proc {|x, y, z, *w| (x||0) + (y||0) + (z||0) + w.inject(0, &:+) } 02004 * p b.curry[1][2][3] #=> 6 02005 * p b.curry[1, 2][3, 4] #=> 10 02006 * p b.curry(5)[1][2][3][4][5] #=> 15 02007 * p b.curry(5)[1, 2][3, 4][5] #=> 15 02008 * p b.curry(1)[1] #=> 1 02009 * 02010 * b = lambda {|x, y, z| (x||0) + (y||0) + (z||0) } 02011 * p b.curry[1][2][3] #=> 6 02012 * p b.curry[1, 2][3, 4] #=> wrong number of arguments (4 for 3) 02013 * p b.curry(5) #=> wrong number of arguments (5 for 3) 02014 * p b.curry(1) #=> wrong number of arguments (1 for 3) 02015 * 02016 * b = lambda {|x, y, z, *w| (x||0) + (y||0) + (z||0) + w.inject(0, &:+) } 02017 * p b.curry[1][2][3] #=> 6 02018 * p b.curry[1, 2][3, 4] #=> 10 02019 * p b.curry(5)[1][2][3][4][5] #=> 15 02020 * p b.curry(5)[1, 2][3, 4][5] #=> 15 02021 * p b.curry(1) #=> wrong number of arguments (1 for 3) 02022 * 02023 * b = proc { :foo } 02024 * p b.curry[] #=> :foo 02025 */ 02026 static VALUE 02027 proc_curry(int argc, VALUE *argv, VALUE self) 02028 { 02029 int sarity, marity = rb_proc_arity(self); 02030 VALUE arity, opt = Qfalse; 02031 02032 if (marity < 0) { 02033 marity = -marity - 1; 02034 opt = Qtrue; 02035 } 02036 02037 rb_scan_args(argc, argv, "01", &arity); 02038 if (NIL_P(arity)) { 02039 arity = INT2FIX(marity); 02040 } 02041 else { 02042 sarity = FIX2INT(arity); 02043 if (rb_proc_lambda_p(self) && (sarity < marity || (sarity > marity && !opt))) { 02044 rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", sarity, marity); 02045 } 02046 } 02047 02048 return make_curry_proc(self, rb_ary_new(), arity); 02049 } 02050 02051 /* 02052 * Document-class: LocalJumpError 02053 * 02054 * Raised when Ruby can't yield as requested. 02055 * 02056 * A typical scenario is attempting to yield when no block is given: 02057 * 02058 * def call_block 02059 * yield 42 02060 * end 02061 * call_block 02062 * 02063 * <em>raises the exception:</em> 02064 * 02065 * LocalJumpError: no block given (yield) 02066 * 02067 * A more subtle example: 02068 * 02069 * def get_me_a_return 02070 * Proc.new { return 42 } 02071 * end 02072 * get_me_a_return.call 02073 * 02074 * <em>raises the exception:</em> 02075 * 02076 * LocalJumpError: unexpected return 02077 */ 02078 02079 /* 02080 * Document-class: SystemStackError 02081 * 02082 * Raised in case of a stack overflow. 02083 * 02084 * def me_myself_and_i 02085 * me_myself_and_i 02086 * end 02087 * me_myself_and_i 02088 * 02089 * <em>raises the exception:</em> 02090 * 02091 * SystemStackError: stack level too deep 02092 */ 02093 02094 /* 02095 * <code>Proc</code> objects are blocks of code that have been bound to 02096 * a set of local variables. Once bound, the code may be called in 02097 * different contexts and still access those variables. 02098 * 02099 * def gen_times(factor) 02100 * return Proc.new {|n| n*factor } 02101 * end 02102 * 02103 * times3 = gen_times(3) 02104 * times5 = gen_times(5) 02105 * 02106 * times3.call(12) #=> 36 02107 * times5.call(5) #=> 25 02108 * times3.call(times5.call(4)) #=> 60 02109 * 02110 */ 02111 02112 void 02113 Init_Proc(void) 02114 { 02115 /* Proc */ 02116 rb_cProc = rb_define_class("Proc", rb_cObject); 02117 rb_undef_alloc_func(rb_cProc); 02118 rb_define_singleton_method(rb_cProc, "new", rb_proc_s_new, -1); 02119 02120 #if 0 /* incomplete. */ 02121 rb_add_method(rb_cProc, rb_intern("call"), VM_METHOD_TYPE_OPTIMIZED, 02122 (void *)OPTIMIZED_METHOD_TYPE_CALL, 0); 02123 rb_add_method(rb_cProc, rb_intern("[]"), VM_METHOD_TYPE_OPTIMIZED, 02124 (void *)OPTIMIZED_METHOD_TYPE_CALL, 0); 02125 rb_add_method(rb_cProc, rb_intern("==="), VM_METHOD_TYPE_OPTIMIZED, 02126 (void *)OPTIMIZED_METHOD_TYPE_CALL, 0); 02127 rb_add_method(rb_cProc, rb_intern("yield"), VM_METHOD_TYPE_OPTIMIZED, 02128 (void *)OPTIMIZED_METHOD_TYPE_CALL, 0); 02129 #else 02130 rb_define_method(rb_cProc, "call", proc_call, -1); 02131 rb_define_method(rb_cProc, "[]", proc_call, -1); 02132 rb_define_method(rb_cProc, "===", proc_call, -1); 02133 rb_define_method(rb_cProc, "yield", proc_call, -1); 02134 #endif 02135 rb_define_method(rb_cProc, "to_proc", proc_to_proc, 0); 02136 rb_define_method(rb_cProc, "arity", proc_arity, 0); 02137 rb_define_method(rb_cProc, "clone", proc_clone, 0); 02138 rb_define_method(rb_cProc, "dup", proc_dup, 0); 02139 rb_define_method(rb_cProc, "==", proc_eq, 1); 02140 rb_define_method(rb_cProc, "eql?", proc_eq, 1); 02141 rb_define_method(rb_cProc, "hash", proc_hash, 0); 02142 rb_define_method(rb_cProc, "to_s", proc_to_s, 0); 02143 rb_define_method(rb_cProc, "lambda?", rb_proc_lambda_p, 0); 02144 rb_define_method(rb_cProc, "binding", proc_binding, 0); 02145 rb_define_method(rb_cProc, "curry", proc_curry, -1); 02146 rb_define_method(rb_cProc, "source_location", rb_proc_location, 0); 02147 rb_define_method(rb_cProc, "parameters", rb_proc_parameters, 0); 02148 02149 /* Exceptions */ 02150 rb_eLocalJumpError = rb_define_class("LocalJumpError", rb_eStandardError); 02151 rb_define_method(rb_eLocalJumpError, "exit_value", localjump_xvalue, 0); 02152 rb_define_method(rb_eLocalJumpError, "reason", localjump_reason, 0); 02153 02154 rb_eSysStackError = rb_define_class("SystemStackError", rb_eException); 02155 sysstack_error = rb_exc_new3(rb_eSysStackError, 02156 rb_obj_freeze(rb_str_new2("stack level too deep"))); 02157 OBJ_TAINT(sysstack_error); 02158 02159 /* utility functions */ 02160 rb_define_global_function("proc", rb_block_proc, 0); 02161 rb_define_global_function("lambda", rb_block_lambda, 0); 02162 02163 /* Method */ 02164 rb_cMethod = rb_define_class("Method", rb_cObject); 02165 rb_undef_alloc_func(rb_cMethod); 02166 rb_undef_method(CLASS_OF(rb_cMethod), "new"); 02167 rb_define_method(rb_cMethod, "==", method_eq, 1); 02168 rb_define_method(rb_cMethod, "eql?", method_eq, 1); 02169 rb_define_method(rb_cMethod, "hash", method_hash, 0); 02170 rb_define_method(rb_cMethod, "clone", method_clone, 0); 02171 rb_define_method(rb_cMethod, "call", rb_method_call, -1); 02172 rb_define_method(rb_cMethod, "[]", rb_method_call, -1); 02173 rb_define_method(rb_cMethod, "arity", method_arity_m, 0); 02174 rb_define_method(rb_cMethod, "inspect", method_inspect, 0); 02175 rb_define_method(rb_cMethod, "to_s", method_inspect, 0); 02176 rb_define_method(rb_cMethod, "to_proc", method_proc, 0); 02177 rb_define_method(rb_cMethod, "receiver", method_receiver, 0); 02178 rb_define_method(rb_cMethod, "name", method_name, 0); 02179 rb_define_method(rb_cMethod, "owner", method_owner, 0); 02180 rb_define_method(rb_cMethod, "unbind", method_unbind, 0); 02181 rb_define_method(rb_cMethod, "source_location", rb_method_location, 0); 02182 rb_define_method(rb_cMethod, "parameters", rb_method_parameters, 0); 02183 rb_define_method(rb_mKernel, "method", rb_obj_method, 1); 02184 rb_define_method(rb_mKernel, "public_method", rb_obj_public_method, 1); 02185 02186 /* UnboundMethod */ 02187 rb_cUnboundMethod = rb_define_class("UnboundMethod", rb_cObject); 02188 rb_undef_alloc_func(rb_cUnboundMethod); 02189 rb_undef_method(CLASS_OF(rb_cUnboundMethod), "new"); 02190 rb_define_method(rb_cUnboundMethod, "==", method_eq, 1); 02191 rb_define_method(rb_cUnboundMethod, "eql?", method_eq, 1); 02192 rb_define_method(rb_cUnboundMethod, "hash", method_hash, 0); 02193 rb_define_method(rb_cUnboundMethod, "clone", method_clone, 0); 02194 rb_define_method(rb_cUnboundMethod, "arity", method_arity_m, 0); 02195 rb_define_method(rb_cUnboundMethod, "inspect", method_inspect, 0); 02196 rb_define_method(rb_cUnboundMethod, "to_s", method_inspect, 0); 02197 rb_define_method(rb_cUnboundMethod, "name", method_name, 0); 02198 rb_define_method(rb_cUnboundMethod, "owner", method_owner, 0); 02199 rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1); 02200 rb_define_method(rb_cUnboundMethod, "source_location", rb_method_location, 0); 02201 rb_define_method(rb_cUnboundMethod, "parameters", rb_method_parameters, 0); 02202 02203 /* Module#*_method */ 02204 rb_define_method(rb_cModule, "instance_method", rb_mod_instance_method, 1); 02205 rb_define_method(rb_cModule, "public_instance_method", rb_mod_public_instance_method, 1); 02206 rb_define_private_method(rb_cModule, "define_method", rb_mod_define_method, -1); 02207 02208 /* Kernel */ 02209 rb_define_method(rb_mKernel, "define_singleton_method", rb_obj_define_method, -1); 02210 } 02211 02212 /* 02213 * Objects of class <code>Binding</code> encapsulate the execution 02214 * context at some particular place in the code and retain this context 02215 * for future use. The variables, methods, value of <code>self</code>, 02216 * and possibly an iterator block that can be accessed in this context 02217 * are all retained. Binding objects can be created using 02218 * <code>Kernel#binding</code>, and are made available to the callback 02219 * of <code>Kernel#set_trace_func</code>. 02220 * 02221 * These binding objects can be passed as the second argument of the 02222 * <code>Kernel#eval</code> method, establishing an environment for the 02223 * evaluation. 02224 * 02225 * class Demo 02226 * def initialize(n) 02227 * @secret = n 02228 * end 02229 * def get_binding 02230 * return binding() 02231 * end 02232 * end 02233 * 02234 * k1 = Demo.new(99) 02235 * b1 = k1.get_binding 02236 * k2 = Demo.new(-3) 02237 * b2 = k2.get_binding 02238 * 02239 * eval("@secret", b1) #=> 99 02240 * eval("@secret", b2) #=> -3 02241 * eval("@secret") #=> nil 02242 * 02243 * Binding objects have no class-specific methods. 02244 * 02245 */ 02246 02247 void 02248 Init_Binding(void) 02249 { 02250 rb_cBinding = rb_define_class("Binding", rb_cObject); 02251 rb_undef_alloc_func(rb_cBinding); 02252 rb_undef_method(CLASS_OF(rb_cBinding), "new"); 02253 rb_define_method(rb_cBinding, "clone", binding_clone, 0); 02254 rb_define_method(rb_cBinding, "dup", binding_dup, 0); 02255 rb_define_method(rb_cBinding, "eval", bind_eval, -1); 02256 rb_define_global_function("binding", rb_f_binding, 0); 02257 } 02258 02259
1.7.6.1