Skip to content
This repository
Newer
Older
100644 746 lines (671 sloc) 18.898 kb
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
1 /* -*-c-*- */
2 /*
3 * This file is included by vm_eval.c
4 */
5
6 static ID __send__, object_id;
7 static ID removed, singleton_removed, undefined, singleton_undefined;
8 static ID eqq, each, aref, aset, match, missing;
9 static ID added, singleton_added;
10
11 static void
12 remove_method(VALUE klass, ID mid)
13 {
14 if (klass == rb_cObject) {
15 rb_secure(4);
16 }
17 if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
18 rb_raise(rb_eSecurityError, "Insecure: can't remove method");
19 }
e732379f » Laurent Sansonetti
2009-11-05 moved the removed_method code to the VM + fixed undef_method callbacks
20 if (OBJ_FROZEN(klass)) {
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
21 rb_error_frozen("class/module");
e732379f » Laurent Sansonetti
2009-11-05 moved the removed_method code to the VM + fixed undef_method callbacks
22 }
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
23 if (mid == object_id || mid == __send__ || mid == idInitialize) {
24 rb_warn("removing `%s' may cause serious problem", rb_id2name(mid));
25 }
26
e732379f » Laurent Sansonetti
2009-11-05 moved the removed_method code to the VM + fixed undef_method callbacks
27 rb_vm_remove_method((Class)klass, mid);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
28 }
29
30 void
31 rb_remove_method(VALUE klass, const char *name)
32 {
33 remove_method(klass, rb_intern(name));
34 }
35
36 /*
37 * call-seq:
38 * remove_method(symbol) => self
39 *
40 * Removes the method identified by _symbol_ from the current
41 * class. For an example, see <code>Module.undef_method</code>.
42 */
43
44 static VALUE
45 rb_mod_remove_method(VALUE mod, SEL sel, int argc, VALUE *argv)
46 {
e732379f » Laurent Sansonetti
2009-11-05 moved the removed_method code to the VM + fixed undef_method callbacks
47 for (int i = 0; i < argc; i++) {
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
48 remove_method(mod, rb_to_id(argv[i]));
49 }
50 return mod;
51 }
52
53 #undef rb_disable_super
54 #undef rb_enable_super
55
56 void
57 rb_disable_super(VALUE klass, const char *name)
58 {
59 /* obsolete - no use */
60 }
61
62 void
63 rb_enable_super(VALUE klass, const char *name)
64 {
65 rb_warning("rb_enable_super() is obsolete");
66 }
67
68 void rb_print_undef(VALUE, ID, int);
69
70 static void
71 rb_export_method(VALUE klass, ID name, ID noex)
72 {
69ef4199 » Laurent Sansonetti
2009-05-22 added AOT compilation support for method definitions and constants
73 rb_vm_method_node_t *node;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
74 SEL sel;
75
76 if (klass == rb_cObject) {
77 rb_secure(4);
78 }
79
80 if (!rb_vm_lookup_method2((Class)klass, name, &sel, NULL, &node)) {
81 if (TYPE(klass) != T_MODULE
82 || !rb_vm_lookup_method2((Class)rb_cObject, name, &sel, NULL, &node)) {
83 rb_print_undef(klass, name, 0);
84 }
85 }
86
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
87 if (node == NULL) {
88 rb_raise(rb_eRuntimeError,
89 "can't change visibility of non Ruby method `%s'",
90 sel_getName(sel));
91 }
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
92
6aab6c5b » Laurent Sansonetti
2010-09-27 fix a bug when changing a method's visibility to public would not be …
93 long flags = (node->flags & ~VM_METHOD_PRIVATE) & ~VM_METHOD_PROTECTED;
846054c9 » Laurent Sansonetti
2009-11-03 when changing the visibility of a method that is included in classes,…
94 switch (noex) {
95 case NOEX_PRIVATE:
96 flags |= VM_METHOD_PRIVATE;
97 break;
98
99 case NOEX_PROTECTED:
100 flags |= VM_METHOD_PROTECTED;
101 break;
102
103 default:
104 break;
105 }
106
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
107 VALUE sklass = RCLASS_SUPER(klass);
108 if (sklass != 0) {
d3eea39c » Laurent Sansonetti
2009-12-23 when changing the visibility of a method and duplicating its entry in…
109 IMP imp;
110 rb_vm_method_node_t *snode;
111 if (rb_vm_lookup_method((Class)sklass, sel, &imp, &snode)
112 && imp == node->objc_imp) {
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
113 // The method actually exists on a superclass, we need to duplicate
d3eea39c » Laurent Sansonetti
2009-12-23 when changing the visibility of a method and duplicating its entry in…
114 // it to the current class, keeping the same flags.
115 if (snode != NULL) {
116 if (snode->flags & VM_METHOD_EMPTY) {
117 flags |= VM_METHOD_EMPTY;
118 }
119 if (snode->flags & VM_METHOD_FBODY) {
120 flags |= VM_METHOD_FBODY;
121 }
122 }
846054c9 » Laurent Sansonetti
2009-11-03 when changing the visibility of a method that is included in classes,…
123 rb_vm_define_method2((Class)klass, sel, node, flags, false);
124 return;
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
125 }
126 }
127
6aab6c5b » Laurent Sansonetti
2010-09-27 fix a bug when changing a method's visibility to public would not be …
128 node->flags = flags;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
129 }
130
131 void
132 rb_attr(VALUE klass, ID id, int read, int write, int ex)
133 {
134 if (!rb_is_local_id(id) && !rb_is_const_id(id)) {
135 rb_name_error(id, "invalid attribute name `%s'", rb_id2name(id));
136 }
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
137 const char *name = rb_id2name(id);
138 if (name == NULL) {
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
139 rb_raise(rb_eArgError, "argument needs to be symbol or string");
140 }
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
141 rb_vm_define_attr((Class)klass, name, read, write);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
142 if (write) {
143 rb_objc_define_kvo_setter(klass, id);
144 }
145 }
146
147 void
148 rb_undef(VALUE klass, ID id)
149 {
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
150 if (klass == rb_cObject) {
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
151 rb_secure(4);
152 }
153 if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
154 rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'",
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
155 rb_id2name(id));
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
156 }
157 rb_frozen_class_p(klass);
158 if (id == object_id || id == __send__ || id == idInitialize) {
159 rb_warn("undefining `%s' may cause serious problem", rb_id2name(id));
160 }
161
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
162 rb_vm_undef_method((Class)klass, id, true);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
163 }
164
165 /*
166 * call-seq:
167 * undef_method(symbol) => self
168 *
169 * Prevents the current class from responding to calls to the named
170 * method. Contrast this with <code>remove_method</code>, which deletes
171 * the method from the particular class; Ruby will still search
172 * superclasses and mixed-in modules for a possible receiver.
173 *
174 * class Parent
175 * def hello
176 * puts "In parent"
177 * end
178 * end
179 * class Child < Parent
180 * def hello
181 * puts "In child"
182 * end
183 * end
184 *
185 *
186 * c = Child.new
187 * c.hello
188 *
189 *
190 * class Child
191 * remove_method :hello # remove from child, still in parent
192 * end
193 * c.hello
194 *
195 *
196 * class Child
197 * undef_method :hello # prevent any calls to 'hello'
198 * end
199 * c.hello
200 *
201 * <em>produces:</em>
202 *
203 * In child
204 * In parent
205 * prog.rb:23: undefined method `hello' for #<Child:0x401b3bb4> (NoMethodError)
206 */
207
208 static VALUE
209 rb_mod_undef_method(VALUE mod, SEL sel, int argc, VALUE *argv)
210 {
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
211 for (int i = 0; i < argc; i++) {
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
212 rb_undef(mod, rb_to_id(argv[i]));
213 }
214 return mod;
215 }
216
217 /*
218 * call-seq:
219 * mod.method_defined?(symbol) => true or false
220 *
221 * Returns +true+ if the named method is defined by
222 * _mod_ (or its included modules and, if _mod_ is a class,
223 * its ancestors). Public and protected methods are matched.
224 *
225 * module A
226 * def method1() end
227 * end
228 * class B
229 * def method2() end
230 * end
231 * class C < B
232 * include A
233 * def method3() end
234 * end
235 *
236 * A.method_defined? :method1 #=> true
237 * C.method_defined? "method1" #=> true
238 * C.method_defined? "method2" #=> true
239 * C.method_defined? "method3" #=> true
240 * C.method_defined? "method4" #=> false
241 */
242
59fba254 » Laurent Sansonetti
2010-02-13 Kernel#respond_to_missing?: added
243 static SEL selRespondToDefault = 0;
244
9e76215b » Laurent Sansonetti
2009-11-23 fixed Module#method_defined?
245 static bool
468a2ea9 » Thibault Martin-Lagardette
2010-07-08 Move Obj-C related headers around.
246 rb_obj_respond_to2(VALUE obj, VALUE klass, ID id, int priv, int check_override)
9e76215b » Laurent Sansonetti
2009-11-23 fixed Module#method_defined?
247 {
248 const char *id_name = rb_id2name(id);
249 SEL sel = sel_registerName(id_name);
250 if (!rb_vm_respond_to2(obj, klass, sel, priv, check_override)) {
251 char buf[100];
252 snprintf(buf, sizeof buf, "%s:", id_name);
253 sel = sel_registerName(buf);
59fba254 » Laurent Sansonetti
2010-02-13 Kernel#respond_to_missing?: added
254 if (!rb_vm_respond_to2(obj, klass, sel, priv, check_override)) {
255 VALUE args[2];
256 args[0] = ID2SYM(id);
257 args[1] = priv ? Qtrue : Qfalse;
70ea0b5a » Laurent Sansonetti
2010-06-01 per-vm method cache + misc fixes/improvements
258 return RTEST(rb_vm_call(obj, selRespondToDefault, 2, args));
59fba254 » Laurent Sansonetti
2010-02-13 Kernel#respond_to_missing?: added
259 }
9e76215b » Laurent Sansonetti
2009-11-23 fixed Module#method_defined?
260 }
261 return true;
262 }
263
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
264 static VALUE
265 rb_mod_method_defined(VALUE mod, SEL sel, VALUE mid)
266 {
914ab2b8 » Laurent Sansonetti
2009-08-25 fixed Module#method_defined?
267 ID id = rb_to_id(mid);
9e76215b » Laurent Sansonetti
2009-11-23 fixed Module#method_defined?
268 return rb_obj_respond_to2(Qnil, mod, id, true, false) ? Qtrue : Qfalse;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
269 }
270
271 #define VISI_CHECK(x,f) (((x)&NOEX_MASK) == (f))
272
273 /*
274 * call-seq:
275 * mod.public_method_defined?(symbol) => true or false
276 *
277 * Returns +true+ if the named public method is defined by
278 * _mod_ (or its included modules and, if _mod_ is a class,
279 * its ancestors).
280 *
281 * module A
282 * def method1() end
283 * end
284 * class B
285 * protected
286 * def method2() end
287 * end
288 * class C < B
289 * include A
290 * def method3() end
291 * end
292 *
293 * A.method_defined? :method1 #=> true
294 * C.public_method_defined? "method1" #=> true
295 * C.public_method_defined? "method2" #=> false
296 * C.method_defined? "method2" #=> true
297 */
298
299 static VALUE
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
300 check_method_visibility(VALUE mod, ID id, int visi)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
301 {
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
302 rb_vm_method_node_t *node;
303 if (rb_vm_lookup_method2((Class)mod, id, NULL, NULL, &node)) {
304 if (node != NULL) {
305 if (node->flags & rb_vm_noex_flag(visi)) {
306 return Qtrue;
307 }
308 }
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
309 }
310 return Qfalse;
311 }
312
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
313 static VALUE
314 rb_mod_public_method_defined(VALUE mod, SEL sel, VALUE mid)
315 {
316 ID id = rb_to_id(mid);
317 return check_method_visibility(mod, id, NOEX_PUBLIC);
318 }
319
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
320 /*
321 * call-seq:
322 * mod.private_method_defined?(symbol) => true or false
323 *
324 * Returns +true+ if the named private method is defined by
325 * _ mod_ (or its included modules and, if _mod_ is a class,
326 * its ancestors).
327 *
328 * module A
329 * def method1() end
330 * end
331 * class B
332 * private
333 * def method2() end
334 * end
335 * class C < B
336 * include A
337 * def method3() end
338 * end
339 *
340 * A.method_defined? :method1 #=> true
341 * C.private_method_defined? "method1" #=> false
342 * C.private_method_defined? "method2" #=> true
343 * C.method_defined? "method2" #=> false
344 */
345
346 static VALUE
347 rb_mod_private_method_defined(VALUE mod, SEL sel, VALUE mid)
348 {
349 ID id = rb_to_id(mid);
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
350 return check_method_visibility(mod, id, NOEX_PRIVATE);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
351 }
352
353 /*
354 * call-seq:
355 * mod.protected_method_defined?(symbol) => true or false
356 *
357 * Returns +true+ if the named protected method is defined
358 * by _mod_ (or its included modules and, if _mod_ is a
359 * class, its ancestors).
360 *
361 * module A
362 * def method1() end
363 * end
364 * class B
365 * protected
366 * def method2() end
367 * end
368 * class C < B
369 * include A
370 * def method3() end
371 * end
372 *
373 * A.method_defined? :method1 #=> true
374 * C.protected_method_defined? "method1" #=> false
375 * C.protected_method_defined? "method2" #=> true
376 * C.method_defined? "method2" #=> true
377 */
378
379 static VALUE
380 rb_mod_protected_method_defined(VALUE mod, SEL sel, VALUE mid)
381 {
382 ID id = rb_to_id(mid);
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
383 return check_method_visibility(mod, id, NOEX_PROTECTED);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
384 }
385
386 void
387 rb_alias(VALUE klass, ID name, ID def)
388 {
389 rb_vm_alias(klass, name, def);
390 }
391
392 /*
393 * call-seq:
394 * alias_method(new_name, old_name) => self
395 *
396 * Makes <i>new_name</i> a new copy of the method <i>old_name</i>. This can
397 * be used to retain access to methods that are overridden.
398 *
399 * module Mod
400 * alias_method :orig_exit, :exit
401 * def exit(code=0)
402 * puts "Exiting with code #{code}"
403 * orig_exit(code)
404 * end
405 * end
406 * include Mod
407 * exit(99)
408 *
409 * <em>produces:</em>
410 *
411 * Exiting with code 99
412 */
413
414 static VALUE
415 rb_mod_alias_method(VALUE mod, SEL sel, VALUE newname, VALUE oldname)
416 {
417 rb_alias(mod, rb_to_id(newname), rb_to_id(oldname));
418 return mod;
419 }
420
421 static void
422 secure_visibility(VALUE self)
423 {
424 if (rb_safe_level() >= 4 && !OBJ_TAINTED(self)) {
425 rb_raise(rb_eSecurityError,
426 "Insecure: can't change method visibility");
427 }
428 }
429
430 static void
431 set_method_visibility(VALUE self, int argc, VALUE *argv, ID ex)
432 {
433 secure_visibility(self);
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
434 for (int i = 0; i < argc; i++) {
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
435 rb_export_method(self, rb_to_id(argv[i]), ex);
436 }
437 }
438
439 /*
440 * call-seq:
441 * public => self
442 * public(symbol, ...) => self
443 *
444 * With no arguments, sets the default visibility for subsequently
445 * defined methods to public. With arguments, sets the named methods to
446 * have public visibility.
447 */
448
449 static VALUE
450 rb_mod_public(VALUE module, SEL sel, int argc, VALUE *argv)
451 {
452 secure_visibility(module);
453 if (argc == 0) {
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
454 rb_vm_set_current_scope(module, SCOPE_PUBLIC);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
455 }
456 else {
457 set_method_visibility(module, argc, argv, NOEX_PUBLIC);
458 }
459 return module;
460 }
461
462 /*
463 * call-seq:
464 * protected => self
465 * protected(symbol, ...) => self
466 *
467 * With no arguments, sets the default visibility for subsequently
468 * defined methods to protected. With arguments, sets the named methods
469 * to have protected visibility.
470 */
471
472 static VALUE
473 rb_mod_protected(VALUE module, SEL sel, int argc, VALUE *argv)
474 {
475 secure_visibility(module);
476 if (argc == 0) {
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
477 rb_vm_set_current_scope(module, SCOPE_PROTECTED);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
478 }
479 else {
480 set_method_visibility(module, argc, argv, NOEX_PROTECTED);
481 }
482 return module;
483 }
484
485 /*
486 * call-seq:
487 * private => self
488 * private(symbol, ...) => self
489 *
490 * With no arguments, sets the default visibility for subsequently
491 * defined methods to private. With arguments, sets the named methods
492 * to have private visibility.
493 *
494 * module Mod
495 * def a() end
496 * def b() end
497 * private
498 * def c() end
499 * private :a
500 * end
501 * Mod.private_instance_methods #=> [:a, :c]
502 */
503
504 static VALUE
505 rb_mod_private(VALUE module, SEL sel, int argc, VALUE *argv)
506 {
507 secure_visibility(module);
508 if (argc == 0) {
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
509 rb_vm_set_current_scope(module, SCOPE_PRIVATE);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
510 }
511 else {
512 set_method_visibility(module, argc, argv, NOEX_PRIVATE);
513 }
514 return module;
515 }
516
517 /*
518 * call-seq:
519 * mod.public_class_method(symbol, ...) => mod
520 *
521 * Makes a list of existing class methods public.
522 */
523
524 static VALUE
525 rb_mod_public_method(VALUE obj, SEL sel, int argc, VALUE *argv)
526 {
527 set_method_visibility(CLASS_OF(obj), argc, argv, NOEX_PUBLIC);
528 return obj;
529 }
530
531 /*
532 * call-seq:
533 * mod.private_class_method(symbol, ...) => mod
534 *
535 * Makes existing class methods private. Often used to hide the default
536 * constructor <code>new</code>.
537 *
538 * class SimpleSingleton # Not thread safe
539 * private_class_method :new
540 * def SimpleSingleton.create(*args, &block)
541 * @me = new(*args, &block) if ! @me
542 * @me
543 * end
544 * end
545 */
546
547 static VALUE
548 rb_mod_private_method(VALUE obj, SEL sel, int argc, VALUE *argv)
549 {
550 set_method_visibility(CLASS_OF(obj), argc, argv, NOEX_PRIVATE);
551 return obj;
552 }
553
554 /*
555 * call-seq:
556 * public
557 * public(symbol, ...)
558 *
559 * With no arguments, sets the default visibility for subsequently
560 * defined methods to public. With arguments, sets the named methods to
561 * have public visibility.
562 */
563
564 static VALUE
565 top_public(VALUE recv, SEL sel, int argc, VALUE *argv)
566 {
567 return rb_mod_public(rb_cObject, 0, argc, argv);
568 }
569
570 static VALUE
571 top_private(VALUE recv, SEL sel, int argc, VALUE *argv)
572 {
573 return rb_mod_private(rb_cObject, 0, argc, argv);
574 }
575
576 /*
577 * call-seq:
578 * module_function(symbol, ...) => self
579 *
580 * Creates module functions for the named methods. These functions may
581 * be called with the module as a receiver, and also become available
582 * as instance methods to classes that mix in the module. Module
583 * functions are copies of the original, and so may be changed
584 * independently. The instance-method versions are made private. If
585 * used with no arguments, subsequently defined methods become module
586 * functions.
587 *
588 * module Mod
589 * def one
590 * "This is one"
591 * end
592 * module_function :one
593 * end
594 * class Cls
595 * include Mod
596 * def callOne
597 * one
598 * end
599 * end
600 * Mod.one #=> "This is one"
601 * c = Cls.new
602 * c.callOne #=> "This is one"
603 * module Mod
604 * def one
605 * "This is the new one"
606 * end
607 * end
608 * Mod.one #=> "This is one"
609 * c.callOne #=> "This is the new one"
610 */
611
612 static VALUE
613 rb_mod_modfunc(VALUE module, SEL sel, int argc, VALUE *argv)
614 {
615 if (TYPE(module) != T_MODULE) {
616 rb_raise(rb_eTypeError, "module_function must be called for modules");
617 }
618
619 secure_visibility(module);
620 if (argc == 0) {
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
621 rb_vm_set_current_scope(module, SCOPE_MODULE_FUNC);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
622 return module;
623 }
624
625 set_method_visibility(module, argc, argv, NOEX_PRIVATE);
626
9590d405 » Laurent Sansonetti
2009-08-22 fixing and adding several missing ruby method features
627 for (int i = 0; i < argc; i++) {
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
628 ID id = rb_to_id(argv[i]);
629 IMP imp;
69ef4199 » Laurent Sansonetti
2009-05-22 added AOT compilation support for method definitions and constants
630 rb_vm_method_node_t *node;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
631 SEL sel;
632
633 if (!rb_vm_lookup_method2((Class)module, id, &sel, &imp, &node)) {
634 // Methods are checked in set_method_visibility().
635 rb_bug("undefined method `%s'; can't happen", rb_id2name(id));
636 }
637
846054c9 » Laurent Sansonetti
2009-11-03 when changing the visibility of a method that is included in classes,…
638 rb_vm_define_method2(*(Class *)module, sel, node, -1, false);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
639 }
640
641 return module;
642 }
643
644 /*
645 * call-seq:
646 * obj.respond_to?(symbol, include_private=false) => true or false
647 *
59fba254 » Laurent Sansonetti
2010-02-13 Kernel#respond_to_missing?: added
648 * Returns +true+ if _obj_ responds to the given
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
649 * method. Private methods are included in the search only if the
650 * optional second parameter evaluates to +true+.
59fba254 » Laurent Sansonetti
2010-02-13 Kernel#respond_to_missing?: added
651 *
652 * If the method is not implemented,
653 * as Process.fork on Windows, File.lchmod on GNU/Linux, etc.,
654 * false is returned.
655 *
656 * If the method is not defined, <code>respond_to_missing?</code>
657 * method is called and the result is returned.
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
658 */
659
468a2ea9 » Thibault Martin-Lagardette
2010-07-08 Move Obj-C related headers around.
660 int
661 rb_obj_respond_to(VALUE obj, ID id, int priv)
28db5987 » Laurent Sansonetti
2009-11-03 make sure Kernel#respond_to? doesn't call itself stupid^Wrecursively
662 {
9e76215b » Laurent Sansonetti
2009-11-23 fixed Module#method_defined?
663 return rb_obj_respond_to2(obj, Qnil, id, priv, true);
28db5987 » Laurent Sansonetti
2009-11-03 make sure Kernel#respond_to? doesn't call itself stupid^Wrecursively
664 }
665
468a2ea9 » Thibault Martin-Lagardette
2010-07-08 Move Obj-C related headers around.
666 int
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
667 rb_respond_to(VALUE obj, ID id)
668 {
28db5987 » Laurent Sansonetti
2009-11-03 make sure Kernel#respond_to? doesn't call itself stupid^Wrecursively
669 return rb_obj_respond_to(obj, id, false);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
670 }
671
672 static VALUE
673 obj_respond_to(VALUE obj, SEL sel, int argc, VALUE *argv)
674 {
675 VALUE mid, priv;
676 ID id;
677
678 rb_scan_args(argc, argv, "11", &mid, &priv);
679 id = rb_to_id(mid);
9e76215b » Laurent Sansonetti
2009-11-23 fixed Module#method_defined?
680 return rb_obj_respond_to2(obj, Qnil, id, RTEST(priv), false) ? Qtrue : Qfalse;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
681 }
682
59fba254 » Laurent Sansonetti
2010-02-13 Kernel#respond_to_missing?: added
683 /*
684 * call-seq:
685 * obj.respond_to_missing?(symbol, include_private) => true or false
686 *
687 * Hook method to return whether the _obj_ can respond to _id_ method
688 * or not.
689 *
690 * See #respond_to?.
691 */
692
693 static VALUE
694 obj_respond_to_missing(VALUE obj, SEL sel, VALUE sym, VALUE priv)
695 {
696 return Qfalse;
697 }
698
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
699 IMP basic_respond_to_imp = NULL;
700
701 void
702 Init_eval_method(void)
703 {
704 rb_objc_define_method(rb_mKernel, "respond_to?", obj_respond_to, -1);
59fba254 » Laurent Sansonetti
2010-02-13 Kernel#respond_to_missing?: added
705 rb_objc_define_method(rb_mKernel, "respond_to_missing?", obj_respond_to_missing, 2);
706 selRespondToDefault = sel_registerName("respond_to_missing?:");
707 basic_respond_to_imp = class_getMethodImplementation((Class)rb_mKernel,
708 selRespondTo);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
709
710 rb_objc_define_private_method(rb_cModule, "remove_method", rb_mod_remove_method, -1);
711 rb_objc_define_private_method(rb_cModule, "undef_method", rb_mod_undef_method, -1);
712 rb_objc_define_private_method(rb_cModule, "alias_method", rb_mod_alias_method, 2);
713 rb_objc_define_private_method(rb_cModule, "public", rb_mod_public, -1);
714 rb_objc_define_private_method(rb_cModule, "protected", rb_mod_protected, -1);
715 rb_objc_define_private_method(rb_cModule, "private", rb_mod_private, -1);
716 rb_objc_define_private_method(rb_cModule, "module_function", rb_mod_modfunc, -1);
717
718 rb_objc_define_method(rb_cModule, "method_defined?", rb_mod_method_defined, 1);
59fba254 » Laurent Sansonetti
2010-02-13 Kernel#respond_to_missing?: added
719 rb_objc_define_method(rb_cModule, "public_method_defined?",
720 rb_mod_public_method_defined, 1);
721 rb_objc_define_method(rb_cModule, "private_method_defined?",
722 rb_mod_private_method_defined, 1);
723 rb_objc_define_method(rb_cModule, "protected_method_defined?",
724 rb_mod_protected_method_defined, 1);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
725 rb_objc_define_method(rb_cModule, "public_class_method", rb_mod_public_method, -1);
726 rb_objc_define_method(rb_cModule, "private_class_method", rb_mod_private_method, -1);
727
728 VALUE cTopLevel = *(VALUE *)rb_vm_top_self();
729 rb_objc_define_method(cTopLevel, "public", top_public, -1);
730 rb_objc_define_method(cTopLevel, "private", top_private, -1);
731
732 object_id = rb_intern("object_id");
733 __send__ = rb_intern("__send__");
734 eqq = rb_intern("===");
735 each = rb_intern("each");
736 aref = rb_intern("[]");
737 aset = rb_intern("[]=");
738 match = rb_intern("=~");
739 missing = rb_intern("method_missing");
740 added = rb_intern("method_added");
741 singleton_added = rb_intern("singleton_method_added");
742 removed = rb_intern("method_removed");
743 singleton_removed = rb_intern("singleton_method_removed");
744 undefined = rb_intern("method_undefined");
745 singleton_undefined = rb_intern("singleton_method_undefined");
746 }
747
Something went wrong with that request. Please try again.