| | 1516 | } else if(RCLASS_MODULE(klass)) { |
| | 1517 | /* If klass is a module, and it has not previously had the idPreviousKlass |
| | 1518 | * variable set in it, then we're in a module that is itself calling super, |
| | 1519 | * and which was not reached via super. E.g.: |
| | 1520 | * |
| | 1521 | * module A |
| | 1522 | * def initialize |
| | 1523 | * super # <--- RIGHT HERE |
| | 1524 | * end |
| | 1525 | * end |
| | 1526 | * |
| | 1527 | * class B |
| | 1528 | * include A |
| | 1529 | * end |
| | 1530 | * |
| | 1531 | * B.new |
| | 1532 | * |
| | 1533 | * In this case, look at the ancestors of the receiver's class, find which |
| | 1534 | * ancestor we're looking at, and then find the *next* ancestor in the list |
| | 1535 | * as the superclass. If that next ancestor is also a module, duplicate the |
| | 1536 | * behavior above and set idPreviousKlass. (This should be refactored out |
| | 1537 | * to avoid duplication.) |
| | 1538 | */ |
| | 1539 | k = CLASS_OF(recv); |
| | 1540 | ary = rb_funcall(k, rb_intern("ancestors"), 0); |
| | 1541 | int i, count = RARRAY_LEN(ary); |
| | 1542 | for (i = 0; !looked_up && i < count-1; i++) { |
| | 1543 | VALUE ancestor = RARRAY_AT(ary, i); |
| | 1544 | |
| | 1545 | if(ancestor == klass) { |
| | 1546 | int j; |
| | 1547 | for (j = i+1; !looked_up && j < count; j++) { |
| | 1548 | k = RARRAY_AT(ary, j); |
| | 1549 | if(!RCLASS_MODULE(k)) { |
| | 1550 | looked_up = 1; |
| | 1551 | } else { |
| | 1552 | VALUE saved_imod_super; |
| | 1553 | NODE *mn; |
| | 1554 | IMP imp; |
| | 1555 | SEL sel; |
| | 1556 | |
| | 1557 | saved_imod_super = RCLASS_SUPER(k); |
| | 1558 | RCLASS_SUPER(k) = 0; |
| | 1559 | mn = rb_objc_method_node(k, mid, &imp, &sel); |
| | 1560 | RCLASS_SUPER(k) = saved_imod_super; |
| | 1561 | if (imp != NULL) { |
| | 1562 | rb_ivar_set(k, idPreviousKlass, klass); |
| | 1563 | *mnp = mn; |
| | 1564 | *impp = imp; |
| | 1565 | *selp = sel; |
| | 1566 | return k; |
| | 1567 | } |
| | 1568 | } |
| | 1569 | } |
| | 1570 | } |
| | 1571 | } |