Class: Method
- Includes:
- MethodAsCode, MethodAsExpression, MethodOrigin, MethodSig
- Defined in:
- lib/internal/method/origin.rb,
lib/internal/method/as_code.rb,
lib/internal/method/signature.rb,
lib/internal/method/as_expression.rb
Class Method Summary collapse
-
.load(String) ⇒ Method
Load a Method from a String.
Instance Method Summary collapse
-
#dump(limit) ⇒ String
Dump a Method and the object to which it is bound to a String.
-
#attached_class ⇒ Class
Given a Method, returns the Class it is attached to.
-
#body ⇒ Node
Given a Method, returns the Node for that Method’s body.
-
#method_id ⇒ Symbol
Given a Method, returns the Symbol of the method it represents.
-
#method_oid ⇒ Symbol
Given a Method, returns the Symbol of the method it represents.
-
#origin_class ⇒ Class
Given a Method, returns the Class in which the method it represents was defined.
-
#receiver ⇒ Object
Given a Method, returns the Object to which it is bound.
-
#signature ⇒ Object
Return a String representing the method’s signature.
Methods included from MethodAsExpression
Methods included from MethodSig
#argument_names, #arguments, #block_arg, #local_vars, #rest_arg
Methods included from MethodAsCode
Methods included from MethodOrigin
Class Method Details
.load(String) ⇒ Method
Load a Method from a String.
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'ext/internal/method/method.c', line 248
static VALUE method_load(VALUE klass, VALUE str)
{
struct METHOD * method;
VALUE rarr = marshal_load(str);
VALUE * arr;
VALUE retval;
if( rb_safe_level() >= 4
|| (rb_safe_level() >= 1 && OBJ_TAINTED(str)))
{
/* no playing with knives in the sandbox */
rb_raise(rb_eSecurityError, "Insecure: can't load method");
}
Check_Type(rarr, T_ARRAY);
if(RARRAY_LEN(rarr) != 6)
{
rb_raise(rb_eArgError, "corrupt data");
}
/* Create a METHOD object -- doesn't matter which method we use */
retval = rb_funcall(
rb_cObject, rb_intern("method"), 1, ID2SYM(rb_intern("__id__")));
UNWRAP_METHOD(retval, method);
arr = RARRAY_PTR(rarr);
#if RUBY_VERSION_CODE >= 192
METHOD_KLASS(method) =
rb_funcall(lookup_module_proc, rb_intern("call"), 1, arr[0]);
METHOD_DEF(method) = xmalloc(sizeof(*METHOD_DEF(method)));
METHOD_DEF(method)->type = VM_METHOD_TYPE_ISEQ;
METHOD_DEF(method)->original_id = SYM2ID(arr[4]);
METHOD_DEF(method)->alias_count = 0;
GetISeqPtr(arr[5], METHOD_DEF(method)->body.iseq);
#else
METHOD_OCLASS(method) =
rb_funcall(lookup_module_proc, rb_intern("call"), 1, arr[0]);
METHOD_RCLASS(method) =
rb_funcall(lookup_module_proc, rb_intern("call"), 1, arr[1]);
method->oid = SYM2ID(arr[4]);
{
NODE * n;
Data_Get_Struct(arr[5], NODE, n);
method->body = n;
}
#endif
method->recv = arr[2];
method->id = SYM2ID(arr[3]);
if(klass == rb_cUnboundMethod)
{
retval = rb_funcall(retval, rb_intern("unbind"), 0);
}
return retval;
}
|
Instance Method Details
#dump(limit) ⇒ String
Dump a Method and the object to which it is bound to a String. The Method’s class will not be dumped, only the name of the class.
Unfortunately, this means that methods for anonymous classes can be dumped but cannot be loaded.
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'ext/internal/method/method.c', line 200
static VALUE method_dump(VALUE self, VALUE limit)
{
struct METHOD * method;
VALUE arr;
if(rb_safe_level() >= 4)
{
/* no access to potentially sensitive data from the sandbox */
rb_raise(rb_eSecurityError, "Insecure: can't dump method");
}
arr = rb_ary_new();
UNWRAP_METHOD(self, method);
#if RUBY_VERSION_CODE >= 193
rb_ary_push(arr, rb_mod_name(method->me->klass)); /* [0] */
rb_ary_push(arr, Qnil); /* TODO */ /* [1] */
#elif RUBY_VERSION_CODE >= 192
rb_ary_push(arr, rb_mod_name(method->me.klass)); /* [0] */
rb_ary_push(arr, Qnil); /* TODO */ /* [1] */
#else
rb_ary_push(arr, rb_mod_name(METHOD_OCLASS(method))); /* [2] */
rb_ary_push(arr, rb_mod_name(METHOD_RCLASS(method))); /* [3] */
#endif
if(rb_class_of(self) == rb_cUnboundMethod)
{
rb_ary_push(arr, Qnil); /* [4] */
}
else
{
rb_ary_push(arr, method->recv); /* [4] */
}
rb_ary_push(arr, ID2SYM(method->id));
#if RUBY_VERSION_CODE >= 192
rb_ary_push(arr, ID2SYM(METHOD_DEF(method)->original_id)); /* [5] */
#else
rb_ary_push(arr, ID2SYM(method->oid)); /* [5] */
#endif
rb_ary_push(arr, method_body(self)); /* [6] */
return marshal_dump(arr, limit);
}
|
#attached_class ⇒ Class
Given a Method, returns the Class it is attached to.
159 160 161 162 163 164 |
# File 'ext/internal/method/method.c', line 159
static VALUE method_attached_class(VALUE method)
{
struct METHOD * m;
UNWRAP_METHOD(method, m);
return CLASS_OF(m->recv);
}
|
#body ⇒ Node
Given a Method, returns the Node for that Method’s body. This can be used to directly copy one class’s method to another (using add_method).
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'ext/internal/method/method.c', line 174
static VALUE method_body(VALUE method)
{
struct METHOD * m;
if(rb_safe_level() >= 4)
{
/* no access to potentially sensitive data from the sandbox */
rb_raise(rb_eSecurityError, "Insecure: can't get method body");
}
UNWRAP_METHOD(method, m);
#if RUBY_VERSION_CODE >= 192
return METHOD_DEF(m)->body.iseq->self; /* TODO: body is a union; is this right? */
#else
return wrap_node(m->body);
#endif
}
|
#method_id ⇒ Symbol
Given a Method, returns the Symbol of the method it represents. If the method is an alias for another method, returns the Symbol of the new method, not the original. If the method changes name, returns the original name, not the new name.
104 105 106 107 108 109 |
# File 'ext/internal/method/method.c', line 104
static VALUE method_id(VALUE method)
{
struct METHOD * m;
UNWRAP_METHOD(method, m);
return ID2SYM(m->id);
}
|
#method_oid ⇒ Symbol
Given a Method, returns the Symbol of the method it represents. If the method is an alias for another method, returns the Symbol of the original method, not the alias. If the original method changes name, returns the original name.
120 121 122 123 124 125 126 127 128 129 |
# File 'ext/internal/method/method.c', line 120
static VALUE method_oid(VALUE method)
{
struct METHOD * m;
UNWRAP_METHOD(method, m);
#if RUBY_VERSION_CODE >= 192
return ID2SYM(METHOD_DEF(m)->original_id);
#else
return ID2SYM(m->oid);
#endif
}
|
#origin_class ⇒ Class
Given a Method, returns the Class in which the method it represents was defined. If the method was defined in a base class and Object#method is called on a derived instance of that base class, this method returns the base class.
140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'ext/internal/method/method.c', line 140
static VALUE method_origin_class(VALUE method)
{
struct METHOD * m;
UNWRAP_METHOD(method, m);
#if RUBY_VERSION_CODE >= 193
return m->me->klass;
#elif RUBY_VERSION_CODE >= 192
return m->me.klass;
#else
return METHOD_OCLASS(m);
#endif
}
|
#receiver ⇒ Object
Given a Method, returns the Object to which it is bound.
88 89 90 91 92 93 |
# File 'ext/internal/method/method.c', line 88
static VALUE method_receiver(VALUE method)
{
struct METHOD * m;
UNWRAP_METHOD(method, m);
return m->recv;
}
|