Class: Method

Inherits:
Object show all
Defined in:
proc.c

Instance Method Summary collapse

Instance Method Details

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

Returns:

  • (Boolean)

1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
# File 'proc.c', line 1061

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:


1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
# File 'proc.c', line 1524

VALUE
rb_method_call(int argc, VALUE *argv, VALUE method)
{
    VALUE result = Qnil;	/* OK */
    struct METHOD *data;
    int state;
    volatile int safe = -1;

    TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
    if (data->recv == Qundef) {
	rb_raise(rb_eTypeError, "can't call unbound method; bind first");
    }
    PUSH_TAG();
    if (OBJ_TAINTED(method)) {
	const int safe_level_to_run = 4 /*SAFE_LEVEL_MAX*/;
	safe = rb_safe_level();
	if (rb_safe_level() < safe_level_to_run) {
	    rb_set_safe_level_force(safe_level_to_run);
	}
    }
    if ((state = EXEC_TAG()) == 0) {
	rb_thread_t *th = GET_THREAD();

	PASS_PASSED_BLOCK_TH(th);
	result = rb_vm_call(th, data->recv, data->id,  argc, argv, data->me, data->defined_class);
    }
    POP_TAG();
    if (safe >= 0)
	rb_set_safe_level_force(safe);
    if (state)
	JUMP_TAG(state);
    return result;
}

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


1773
1774
1775
1776
1777
1778
# File 'proc.c', line 1773

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:


1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
# File 'proc.c', line 1524

VALUE
rb_method_call(int argc, VALUE *argv, VALUE method)
{
    VALUE result = Qnil;	/* OK */
    struct METHOD *data;
    int state;
    volatile int safe = -1;

    TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
    if (data->recv == Qundef) {
	rb_raise(rb_eTypeError, "can't call unbound method; bind first");
    }
    PUSH_TAG();
    if (OBJ_TAINTED(method)) {
	const int safe_level_to_run = 4 /*SAFE_LEVEL_MAX*/;
	safe = rb_safe_level();
	if (rb_safe_level() < safe_level_to_run) {
	    rb_set_safe_level_force(safe_level_to_run);
	}
    }
    if ((state = EXEC_TAG()) == 0) {
	rb_thread_t *th = GET_THREAD();

	PASS_PASSED_BLOCK_TH(th);
	result = rb_vm_call(th, data->recv, data->id,  argc, argv, data->me, data->defined_class);
    }
    POP_TAG();
    if (safe >= 0)
	rb_set_safe_level_force(safe);
    if (state)
	JUMP_TAG(state);
    return result;
}

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

1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
# File 'proc.c', line 1493

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

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

Returns:

  • (Boolean)

Returns:

  • (Boolean)

1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
# File 'proc.c', line 1061

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:


1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
# File 'proc.c', line 1091

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:


1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
# File 'proc.c', line 1928

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

    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, ": ");

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

	if (data->recv == Qundef) {
	    rb_str_buf_append(str, rb_inspect(data->me->klass));
	}
	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_cat2(str, rb_class2name(data->rclass));
	if (data->rclass != data->me->klass) {
	    rb_str_buf_cat2(str, "(");
	    rb_str_buf_cat2(str, rb_class2name(data->me->klass));
	    rb_str_buf_cat2(str, ")");
	}
    }
    rb_str_buf_cat2(str, sharp);
    rb_str_append(str, 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.


1160
1161
1162
1163
1164
1165
1166
1167
# File 'proc.c', line 1160

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

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

#ownerObject

Returns the class or module that defines the method.


1176
1177
1178
1179
1180
1181
1182
1183
# File 'proc.c', line 1176

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

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

#parametersArray

Returns the parameter information of this method.

Returns:


1908
1909
1910
1911
1912
1913
1914
1915
1916
# File 'proc.c', line 1908

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:


1144
1145
1146
1147
1148
1149
1150
1151
# File 'proc.c', line 1144

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:


1894
1895
1896
1897
1898
1899
# File 'proc.c', line 1894

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:


2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
# File 'proc.c', line 2025

static VALUE
method_proc(VALUE method)
{
    VALUE procval;
    rb_proc_t *proc;
    /*
     * class Method
     *   def to_proc
     *     proc{|*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>"

Overloads:


1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
# File 'proc.c', line 1928

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

    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, ": ");

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

	if (data->recv == Qundef) {
	    rb_str_buf_append(str, rb_inspect(data->me->klass));
	}
	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_cat2(str, rb_class2name(data->rclass));
	if (data->rclass != data->me->klass) {
	    rb_str_buf_cat2(str, "(");
	    rb_str_buf_cat2(str, rb_class2name(data->me->klass));
	    rb_str_buf_cat2(str, ")");
	}
    }
    rb_str_buf_cat2(str, sharp);
    rb_str_append(str, 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).


1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
# File 'proc.c', line 1115

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