Class: Object

Inherits:
BasicObject
Defined in:
(unknown)

Instance Method Summary collapse

Instance Method Details

#captureObject



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'ext/texplay/gen_eval.c', line 37

VALUE
rb_capture(VALUE self) {
    VALUE hidden_self;
    VALUE result;
    
    rb_need_block();
    
    hidden_self = retrieve_hidden_self(self);

    /* 2 cases: (1) if rb_gen_eval is active then instance_eval wrt hidden_self
                (2) otherwise simply yield to the block
    */
    if(!NIL_P(hidden_self))
        result = rb_obj_instance_eval(0, 0, hidden_self);
    else
        result = rb_yield(Qnil);

    /* we want the return value of capture to be the return value of the block */
    return result;
}

#gen_eval(*args) ⇒ Object Also known as: gen_eval_with

end of ruby 1.9 funcs *



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'ext/texplay/gen_eval.c', line 94

VALUE
rb_gen_eval(int argc, VALUE * argv, VALUE self) {
    VALUE duped_context;
    VALUE is_a_module;
    VALUE context;
    VALUE result;
    
    rb_need_block();
        
    context = rb_funcall(rb_block_proc(), rb_intern("__context__"), 0);

    /* using Class instead of Object (where possible) because Object's iv_tbl setup in 1.9 is weird */
#ifdef RUBY_19
    if(TYPE(context) == T_OBJECT)
        duped_context = rb_funcall(rb_cObject, rb_intern("new"), 0);
    else 
        duped_context = rb_funcall(rb_cClass, rb_intern("new"), 0);

#else

    duped_context = rb_funcall(rb_cClass, rb_intern("new"), 0);

#endif    
    
    
    /* the duped_context shares the context's iv_tbl.
       2 cases: (1) external iv_tbl, (2) local iv_tbl
       
       NOTE: we do not need to save original iv_tbl before replacing it, a brand new Class
       instance does not yet have an iv_tbl (the pointer is set to 0) 
    */
    if(FL_TEST(context, FL_EXIVAR)) 
        RCLASS_IV_TBL(duped_context) = (struct st_table *) rb_generic_ivar_table(context);
    else {
#ifdef RUBY_19
        if(TYPE(context) == T_OBJECT)
            redirect_iv_for_object(context, duped_context);
        else {
            RCLASS_IV_TBL(duped_context) = (struct st_table *) RCLASS_IV_TBL(context);
        }
#else
        RCLASS_IV_TBL(duped_context) = (struct st_table *) RCLASS_IV_TBL(context);
#endif        

        
    }
        
    /* ensure singleton exists */
    rb_singleton_class(context);
    
    /* set up the class hierarchy for our dup_context */
    KLASS_OF(duped_context) = rb_singleton_class_clone(context);

    /* if no args then default to mixing in 'self' */
    if(argc == 0) {
        argc = 1;
        argv = &self;
    }

    /* mix the objects (or self) into the duped context */
    rb_gen_extend(argc, argv, duped_context);

    /* store self in hidden var in duped context */
    set_hidden_self(duped_context, self);

    is_a_module = rb_funcall(duped_context, rb_intern("is_a?"), 1, rb_cModule);

    /* eval block wrt duped_context */
    if(is_a_module == Qtrue)
        result = rb_mod_module_eval(0, 0, duped_context);
    else
        result = rb_obj_instance_eval(0, 0, duped_context);

    /* clean up goes below */

    /* release context's iv_tbl from duped_context. */
#ifdef RUBY_19
    if(TYPE(duped_context) == T_OBJECT)
        release_iv_for_object(duped_context);
    else {
        RCLASS_IV_TBL(duped_context) = (struct st_table *) 0;
    }
#else
    RCLASS_IV_TBL(duped_context) = (struct st_table *) 0;
#endif

    /* delete hidden self */
    set_hidden_self(duped_context, Qnil);
    
    return result;
}

#gen_extend(*args) ⇒ Object

cannot simply forward to gen_include as need to invoke ‘extended’ hook



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'ext/texplay/object2module.c', line 123

VALUE
rb_gen_extend(int argc, VALUE * argv, VALUE self)
{
    int i;

    if (argc == 0) rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
    
    rb_singleton_class(self);

    for(i = 0; i < argc; i++) {
        VALUE mod = rb_to_module(argv[i]); 
        rb_funcall(mod, rb_intern("extend_object"), 1, self);
        rb_funcall(mod, rb_intern("extended"), 1, self);
        
        /* only redirect if argv[i] is not a module */
        if(argv[i] != mod) rb_reset_tbls(mod);
    }

    return self;
}

#reset_tblsObject

#to_moduleObject



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'ext/texplay/object2module.c', line 80

VALUE
rb_to_module(VALUE self)
{
    VALUE rclass, chain_start, jcur, klass;

    switch(BUILTIN_TYPE(self)) {
    case T_MODULE:
        return self;
    case T_CLASS:
        klass = self;
        break;
    case T_OBJECT:
    default:
        klass = rb_singleton_class(self);            
    }
            
    chain_start = j_class_new(klass, rb_cObject);

    KLASS_OF(chain_start) = rb_cModule;
    RBASIC(chain_start)->flags = T_MODULE;

    jcur = chain_start;
    for(rclass = RCLASS_SUPER(klass); rclass != rb_cObject;
        rclass = RCLASS_SUPER(rclass)) {
                
        RCLASS_SUPER(jcur) = j_class_new(rclass, rb_cObject);
        jcur = RCLASS_SUPER(jcur);
    }

    RCLASS_SUPER(jcur) = (VALUE)NULL;

    return chain_start;
}