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.



1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
# File 'proc.c', line 1374

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

    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);

    klass1 = method_entry_defined_class(m1->me);
    klass2 = method_entry_defined_class(m2->me);

    if (!rb_method_entry_eq(m1->me, m2->me) ||
  klass1 != klass2 ||
  m1->klass != m2->klass ||
  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


1944
1945
1946
1947
1948
1949
# File 'proc.c', line 1944

VALUE
rb_method_call(int argc, const 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


2234
2235
2236
2237
2238
2239
# File 'proc.c', line 2234

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


1944
1945
1946
1947
1948
1949
# File 'proc.c', line 1944

VALUE
rb_method_call(int argc, const 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"


1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
# File 'proc.c', line 1916

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);
    RB_OBJ_WRITE(clone, &data->recv, orig->recv);
    RB_OBJ_WRITE(clone, &data->klass, orig->klass);
    RB_OBJ_WRITE(clone, &data->me, rb_method_entry_clone(orig->me));
    return clone;
}

#curryProc #curry(arity) ⇒ Proc

Returns a curried proc based on the method. When the proc is called with a number of arguments that is lower than the method's arity, then another curried proc is returned. Only when enough arguments have been supplied to satisfy the method signature, will the method actually be called.

The optional arity argument should be supplied when currying methods with variable arguments to determine how many arguments are needed before the method is called.

def foo(a,b,c)
  [a, b, c]
end

proc  = self.method(:foo).curry
proc2 = proc.call(1, 2)          #=> #<Proc>
proc2.call(3)                    #=> [1,2,3]

def vararg(*args)
  args
end

proc = self.method(:vararg).curry(4)
proc2 = proc.call(:x)      #=> #<Proc>
proc3 = proc2.call(:y, :z) #=> #<Proc>
proc3.call(:a)             #=> [:x, :y, :z, :a]


2816
2817
2818
2819
2820
2821
# File 'proc.c', line 2816

static VALUE
rb_method_curry(int argc, const VALUE *argv, VALUE self)
{
    VALUE proc = method_to_proc(self);
    return proc_curry(argc, argv, proc);
}

#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.



1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
# File 'proc.c', line 1374

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

    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);

    klass1 = method_entry_defined_class(m1->me);
    klass2 = method_entry_defined_class(m2->me);

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

    return Qtrue;
}

#hashInteger

Returns a hash value corresponding to the method object.

See also Object#hash.



1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
# File 'proc.c', line 1411

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->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>"


2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
# File 'proc.c', line 2415

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

    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->klass;

    if (data->me->def->type == VM_METHOD_TYPE_ALIAS) {
  defined_class = data->me->def->body.alias.original_me->owner;
    }
    else {
  defined_class = method_entry_defined_class(data->me);
    }

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

    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(mklass));
  if (defined_class != mklass) {
      rb_str_buf_cat2(str, "(");
      rb_str_buf_append(str, rb_class_name(defined_class));
      rb_str_buf_cat2(str, ")");
  }
    }
    rb_str_buf_cat2(str, sharp);
    rb_str_append(str, rb_id2str(data->me->called_id));
    if (data->me->called_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.



1474
1475
1476
1477
1478
1479
1480
1481
# File 'proc.c', line 1474

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

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

#original_nameObject

Returns the original name of the method.



1490
1491
1492
1493
1494
1495
1496
1497
# File 'proc.c', line 1490

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.



1506
1507
1508
1509
1510
1511
1512
# File 'proc.c', line 1506

static VALUE
method_owner(VALUE obj)
{
    struct METHOD *data;
    TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
    return data->me->owner;
}

#parametersArray

Returns the parameter information of this method.



2395
2396
2397
2398
2399
2400
2401
2402
2403
# File 'proc.c', line 2395

static VALUE
rb_method_parameters(VALUE method)
{
    const rb_iseq_t *iseq = rb_method_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.



1458
1459
1460
1461
1462
1463
1464
1465
# File 'proc.c', line 1458

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)



2382
2383
2384
2385
2386
# File 'proc.c', line 2382

VALUE
rb_method_location(VALUE method)
{
    return method_def_location(method_def(method));
}

#super_methodObject

Returns a Method of superclass which would be called when super is used or nil if there is no method on superclass.



2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
# File 'proc.c', line 2559

static VALUE
method_super_method(VALUE method)
{
    const struct METHOD *data;
    VALUE super_class;
    const rb_method_entry_t *me;

    TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
    super_class = RCLASS_SUPER(method_entry_defined_class(data->me));
    if (!super_class) return Qnil;
    me = (rb_method_entry_t *)rb_callable_method_entry_without_refinements(super_class, data->me->called_id);
    if (!me) return Qnil;
    return mnew_internal(me, super_class, data->recv, data->me->called_id, rb_obj_class(method), FALSE, FALSE);
}

#to_procProc

Returns a Proc object corresponding to this method.



2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
# File 'proc.c', line 2530

static VALUE
method_to_proc(VALUE method)
{
    VALUE procval;
    rb_proc_t *proc;

    /*
     * class Method
     *   def to_proc
     *     lambda{|*args|
     *       self.call(*args)
     *     }
     *   end
     * end
     */
    procval = rb_iterate(mlambda, 0, bmcall, method);
    GetProcPtr(procval, proc);
    proc->is_from_method = 1;
    return procval;
}

#to_sString #inspectString

Returns the name of the underlying method.

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


2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
# File 'proc.c', line 2415

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

    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->klass;

    if (data->me->def->type == VM_METHOD_TYPE_ALIAS) {
  defined_class = data->me->def->body.alias.original_me->owner;
    }
    else {
  defined_class = method_entry_defined_class(data->me);
    }

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

    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(mklass));
  if (defined_class != mklass) {
      rb_str_buf_cat2(str, "(");
      rb_str_buf_append(str, rb_class_name(defined_class));
      rb_str_buf_cat2(str, ")");
  }
    }
    rb_str_buf_cat2(str, sharp);
    rb_str_append(str, rb_id2str(data->me->called_id));
    if (data->me->called_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).



1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
# File 'proc.c', line 1434

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);
    RB_OBJ_WRITE(method, &data->recv, Qundef);
    RB_OBJ_WRITE(method, &data->klass, orig->klass);
    RB_OBJ_WRITE(method, &data->me, rb_method_entry_clone(orig->me));
    OBJ_INFECT(method, obj);

    return method;
}