Class: Method

Inherits:
Object show all
Defined in:
proc.c

Instance Method Summary collapse

Instance Method Details

#eql?(other_meth) ⇒ Boolean #==(other_meth) ⇒ Boolean

Two method objects are equal if they are bound to the same object and refer to the same method definition and their owners are the same class or module.

Overloads:

  • #eql?(other_meth) ⇒ Boolean

    Returns:

    • (Boolean)
  • #==(other_meth) ⇒ Boolean

    Returns:

    • (Boolean)


1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
# File 'proc.c', line 1240

static VALUE
method_eq(VALUE method, VALUE other)
{
    struct METHOD *m1, *m2;

    if (!rb_obj_is_method(other))
	return Qfalse;
    if (CLASS_OF(method) != CLASS_OF(other))
	return Qfalse;

    Check_TypedStruct(method, &method_data_type);
    m1 = (struct METHOD *)DATA_PTR(method);
    m2 = (struct METHOD *)DATA_PTR(other);

    if (!rb_method_entry_eq(m1->me, m2->me) ||
	m1->rclass != m2->rclass ||
	m1->recv != m2->recv) {
	return Qfalse;
    }

    return Qtrue;
}

#call(args, ...) ⇒ Object #[](args, ...) ⇒ Object

Invokes the meth with the specified arguments, returning the method’s return value.

m = 12.method("+")
m.call(3)    #=> 15
m.call(20)   #=> 32

Overloads:



1779
1780
1781
1782
1783
1784
# File 'proc.c', line 1779

VALUE
rb_method_call(int argc, VALUE *argv, VALUE method)
{
    VALUE proc = rb_block_given_p() ? rb_block_proc() : Qnil;
    return rb_method_call_with_block(argc, argv, method, proc);
}

#arityFixnum

Returns an indication of the number of arguments accepted by a method. Returns a nonnegative integer for methods that take a fixed number of arguments. For Ruby methods that take a variable number of arguments, returns -n-1, where n is the number of required arguments. For methods written in C, returns -1 if the call takes a variable number of arguments.

class C
  def one;    end
  def two(a); end
  def three(*a);  end
  def four(a, b); end
  def five(a, b, *c);    end
  def six(a, b, *c, &d); end
end
c = C.new
c.method(:one).arity     #=> 0
c.method(:two).arity     #=> 1
c.method(:three).arity   #=> -1
c.method(:four).arity    #=> 2
c.method(:five).arity    #=> -3
c.method(:six).arity     #=> -3

"cat".method(:size).arity      #=> 0
"cat".method(:replace).arity   #=> 1
"cat".method(:squeeze).arity   #=> -1
"cat".method(:count).arity     #=> -1

Returns:



2059
2060
2061
2062
2063
2064
# File 'proc.c', line 2059

static VALUE
method_arity_m(VALUE method)
{
    int n = method_arity(method);
    return INT2FIX(n);
}

#call(args, ...) ⇒ Object #[](args, ...) ⇒ Object

Invokes the meth with the specified arguments, returning the method’s return value.

m = 12.method("+")
m.call(3)    #=> 15
m.call(20)   #=> 32

Overloads:



1779
1780
1781
1782
1783
1784
# File 'proc.c', line 1779

VALUE
rb_method_call(int argc, VALUE *argv, VALUE method)
{
    VALUE proc = rb_block_given_p() ? rb_block_proc() : Qnil;
    return rb_method_call_with_block(argc, argv, method, proc);
}

#cloneObject

Returns a clone of this method.

class A
  def foo
    return "bar"
  end
end

m = A.new.method(:foo)
m.call # => "bar"
n = m.clone.call # => "bar"


1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
# File 'proc.c', line 1748

static VALUE
method_clone(VALUE self)
{
    VALUE clone;
    struct METHOD *orig, *data;

    TypedData_Get_Struct(self, struct METHOD, &method_data_type, orig);
    clone = TypedData_Make_Struct(CLASS_OF(self), struct METHOD, &method_data_type, data);
    CLONESETUP(clone, self);
    *data = *orig;
    data->me = ALLOC(rb_method_entry_t);
    *data->me = *orig->me;
    if (data->me->def) data->me->def->alias_count++;
    data->ume = ALLOC(struct unlinked_method_entry_list_entry);

    return clone;
}

#eql?(other_meth) ⇒ Boolean #==(other_meth) ⇒ Boolean

Two method objects are equal if they are bound to the same object and refer to the same method definition and their owners are the same class or module.

Overloads:

  • #eql?(other_meth) ⇒ Boolean

    Returns:

    • (Boolean)
  • #==(other_meth) ⇒ Boolean

    Returns:

    • (Boolean)

Returns:

  • (Boolean)


1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
# File 'proc.c', line 1240

static VALUE
method_eq(VALUE method, VALUE other)
{
    struct METHOD *m1, *m2;

    if (!rb_obj_is_method(other))
	return Qfalse;
    if (CLASS_OF(method) != CLASS_OF(other))
	return Qfalse;

    Check_TypedStruct(method, &method_data_type);
    m1 = (struct METHOD *)DATA_PTR(method);
    m2 = (struct METHOD *)DATA_PTR(other);

    if (!rb_method_entry_eq(m1->me, m2->me) ||
	m1->rclass != m2->rclass ||
	m1->recv != m2->recv) {
	return Qfalse;
    }

    return Qtrue;
}

#hashInteger

Returns a hash value corresponding to the method object.

Returns:



1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
# File 'proc.c', line 1270

static VALUE
method_hash(VALUE method)
{
    struct METHOD *m;
    st_index_t hash;

    TypedData_Get_Struct(method, struct METHOD, &method_data_type, m);
    hash = rb_hash_start((st_index_t)m->rclass);
    hash = rb_hash_uint(hash, (st_index_t)m->recv);
    hash = rb_hash_method_entry(hash, m->me);
    hash = rb_hash_end(hash);

    return INT2FIX(hash);
}

#to_sString #inspectString

Returns the name of the underlying method.

"cat".method(:count).inspect   #=> "#<Method: String#count>"

Overloads:



2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
# File 'proc.c', line 2214

static VALUE
method_inspect(VALUE method)
{
    struct METHOD *data;
    VALUE str;
    const char *s;
    const char *sharp = "#";
    VALUE mklass;

    TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
    str = rb_str_buf_new2("#<");
    s = rb_obj_classname(method);
    rb_str_buf_cat2(str, s);
    rb_str_buf_cat2(str, ": ");

    mklass = data->me->klass;
    if (FL_TEST(mklass, FL_SINGLETON)) {
	VALUE v = rb_ivar_get(mklass, attached);

	if (data->recv == Qundef) {
	    rb_str_buf_append(str, rb_inspect(mklass));
	}
	else if (data->recv == v) {
	    rb_str_buf_append(str, rb_inspect(v));
	    sharp = ".";
	}
	else {
	    rb_str_buf_append(str, rb_inspect(data->recv));
	    rb_str_buf_cat2(str, "(");
	    rb_str_buf_append(str, rb_inspect(v));
	    rb_str_buf_cat2(str, ")");
	    sharp = ".";
	}
    }
    else {
	rb_str_buf_append(str, rb_class_name(data->rclass));
	if (data->rclass != mklass) {
	    rb_str_buf_cat2(str, "(");
	    rb_str_buf_append(str, rb_class_name(mklass));
	    rb_str_buf_cat2(str, ")");
	}
    }
    rb_str_buf_cat2(str, sharp);
    rb_str_append(str, rb_id2str(data->id));
    if (data->id != data->me->def->original_id) {
	rb_str_catf(str, "(%"PRIsVALUE")",
		    rb_id2str(data->me->def->original_id));
    }
    if (data->me->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) {
        rb_str_buf_cat2(str, " (not-implemented)");
    }
    rb_str_buf_cat2(str, ">");

    return str;
}

#nameObject

Returns the name of the method.



1339
1340
1341
1342
1343
1344
1345
1346
# File 'proc.c', line 1339

static VALUE
method_name(VALUE obj)
{
    struct METHOD *data;

    TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
    return ID2SYM(data->id);
}

#original_nameObject

Returns the original name of the method.



1355
1356
1357
1358
1359
1360
1361
1362
# File 'proc.c', line 1355

static VALUE
method_original_name(VALUE obj)
{
    struct METHOD *data;

    TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
    return ID2SYM(data->me->def->original_id);
}

#ownerObject

Returns the class or module that defines the method.



1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
# File 'proc.c', line 1371

static VALUE
method_owner(VALUE obj)
{
    struct METHOD *data;
    VALUE defined_class;

    TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
    defined_class = data->defined_class;

    if (RB_TYPE_P(defined_class, T_ICLASS)) {
	defined_class = RBASIC_CLASS(defined_class);
    }

    return defined_class;
}

#parametersArray

Returns the parameter information of this method.

Returns:



2194
2195
2196
2197
2198
2199
2200
2201
2202
# File 'proc.c', line 2194

static VALUE
rb_method_parameters(VALUE method)
{
    rb_iseq_t *iseq = rb_method_get_iseq(method);
    if (!iseq) {
	return unnamed_parameters(method_arity(method));
    }
    return rb_iseq_parameters(iseq, 0);
}

#receiverObject

Returns the bound receiver of the method object.

Returns:



1323
1324
1325
1326
1327
1328
1329
1330
# File 'proc.c', line 1323

static VALUE
method_receiver(VALUE obj)
{
    struct METHOD *data;

    TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
    return data->recv;
}

#source_locationArray, Fixnum

Returns the Ruby source filename and line number containing this method or nil if this method was not defined in Ruby (i.e. native)

Returns ].

Returns:



2180
2181
2182
2183
2184
2185
# File 'proc.c', line 2180

VALUE
rb_method_location(VALUE method)
{
    rb_method_definition_t *def = method_get_def(method);
    return method_def_location(def);
}

#to_procProc

Returns a Proc object corresponding to this method.

Returns:



2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
# File 'proc.c', line 2316

static VALUE
method_proc(VALUE method)
{
    VALUE procval;
    struct METHOD *meth;
    rb_proc_t *proc;
    rb_env_t *env;

    /*
     * class Method
     *   def to_proc
     *     proc{|*args|
     *       self.call(*args)
     *     }
     *   end
     * end
     */
    TypedData_Get_Struct(method, struct METHOD, &method_data_type, meth);
    procval = rb_iterate(mlambda, 0, bmcall, method);
    GetProcPtr(procval, proc);
    proc->is_from_method = 1;
    proc->block.self = meth->recv;
    proc->block.klass = meth->defined_class;
    GetEnvPtr(proc->envval, env);
    env->block.self = meth->recv;
    env->block.klass = meth->defined_class;
    env->block.iseq = method_get_iseq(meth->me->def);
    return procval;
}

#to_sString #inspectString

Returns the name of the underlying method.

"cat".method(:count).inspect   #=> "#<Method: String#count>"

Overloads:



2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
# File 'proc.c', line 2214

static VALUE
method_inspect(VALUE method)
{
    struct METHOD *data;
    VALUE str;
    const char *s;
    const char *sharp = "#";
    VALUE mklass;

    TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
    str = rb_str_buf_new2("#<");
    s = rb_obj_classname(method);
    rb_str_buf_cat2(str, s);
    rb_str_buf_cat2(str, ": ");

    mklass = data->me->klass;
    if (FL_TEST(mklass, FL_SINGLETON)) {
	VALUE v = rb_ivar_get(mklass, attached);

	if (data->recv == Qundef) {
	    rb_str_buf_append(str, rb_inspect(mklass));
	}
	else if (data->recv == v) {
	    rb_str_buf_append(str, rb_inspect(v));
	    sharp = ".";
	}
	else {
	    rb_str_buf_append(str, rb_inspect(data->recv));
	    rb_str_buf_cat2(str, "(");
	    rb_str_buf_append(str, rb_inspect(v));
	    rb_str_buf_cat2(str, ")");
	    sharp = ".";
	}
    }
    else {
	rb_str_buf_append(str, rb_class_name(data->rclass));
	if (data->rclass != mklass) {
	    rb_str_buf_cat2(str, "(");
	    rb_str_buf_append(str, rb_class_name(mklass));
	    rb_str_buf_cat2(str, ")");
	}
    }
    rb_str_buf_cat2(str, sharp);
    rb_str_append(str, rb_id2str(data->id));
    if (data->id != data->me->def->original_id) {
	rb_str_catf(str, "(%"PRIsVALUE")",
		    rb_id2str(data->me->def->original_id));
    }
    if (data->me->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) {
        rb_str_buf_cat2(str, " (not-implemented)");
    }
    rb_str_buf_cat2(str, ">");

    return str;
}

#unbindObject

Dissociates meth from its current receiver. The resulting UnboundMethod can subsequently be bound to a new object of the same class (see UnboundMethod).



1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
# File 'proc.c', line 1294

static VALUE
method_unbind(VALUE obj)
{
    VALUE method;
    struct METHOD *orig, *data;

    TypedData_Get_Struct(obj, struct METHOD, &method_data_type, orig);
    method = TypedData_Make_Struct(rb_cUnboundMethod, struct METHOD,
				   &method_data_type, data);
    data->recv = Qundef;
    data->id = orig->id;
    data->me = ALLOC(rb_method_entry_t);
    *data->me = *orig->me;
    if (orig->me->def) orig->me->def->alias_count++;
    data->rclass = orig->rclass;
    data->defined_class = orig->defined_class;
    data->ume = ALLOC(struct unlinked_method_entry_list_entry);
    OBJ_INFECT(method, obj);

    return method;
}