Spec-Zone.ru › Ruby 2.3

класс Method

Родитель:
Объект

Метод

Публичные методы экземпляров

meth == other_meth → true или false Показать исходный код
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;
}

Два объекта метода равны, если они связаны с одним объектом и ссылаются на одно и то же определение метода, а их владельцы — один и тот же класс или модуль.

prc[params,...] → obj Показать исходный код
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);
}

Вызывает блок, устанавливая параметры блока на значения в params, используя что-то близкое к семантике вызова метода. Возвращает значение последнего выражения, вычисленного в блоке.

a_proc = Proc.new {|scalar, *values| values.map {|value| value*scalar } }
a_proc.call(9, 1, 2, 3)    #=> [9, 18, 27]
a_proc[9, 1, 2, 3]         #=> [9, 18, 27]
a_proc.(9, 1, 2, 3)        #=> [9, 18, 27]
a_proc.yield(9, 1, 2, 3)   #=> [9, 18, 27]

Обратите внимание, что prc.() вызывает prc.call() с заданными параметрами. Это синтаксический сахар, скрывающий «вызов».

Для процедур, созданных с помощью lambda или ->(), генерируется ошибка, если передано неправильное количество параметров. Для процедур, созданных с помощью Proc.new или Kernel.proc, дополнительные параметры игнорируются, а недостающие параметры устанавливаются в nil.

a_proc = proc {|a,b| [a,b] }
a_proc.call(1)   #=> [1, nil]

a_proc = lambda {|a,b| [a,b] }
a_proc.call(1)   # ArgumentError: wrong number of arguments (given 1, expected 2)

См. также Proc#lambda?.

arity → целое Показать исходный код
static VALUE
method_arity_m(VALUE method)
{
    int n = method_arity(method);
    return INT2FIX(n);
}

Возвращает указание на количество аргументов, принимаемых методом. Возвращает неотрицательное целое число для методов, принимающих фиксированное число аргументов. Для методов Ruby, принимающих переменное число аргументов, возвращает -n-1, где n — количество обязательных аргументов. Для методов, написанных на C, возвращает -1, если вызов принимает переменное число аргументов.

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
call(params,...) → obj Показать исходный код
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);
}

Вызывает блок, устанавливая параметры блока на значения в params, используя что-то близкое к семантике вызова метода. Возвращает значение последнего выражения, вычисленного в блоке.

a_proc = Proc.new {|scalar, *values| values.map {|value| value*scalar } }
a_proc.call(9, 1, 2, 3)    #=> [9, 18, 27]
a_proc[9, 1, 2, 3]         #=> [9, 18, 27]
a_proc.(9, 1, 2, 3)        #=> [9, 18, 27]
a_proc.yield(9, 1, 2, 3)   #=> [9, 18, 27]

Обратите внимание, что prc.() вызывает prc.call() с заданными параметрами. Это синтаксический сахар, скрывающий «вызов».

Для процедур, созданных с помощью lambda или ->(), генерируется ошибка, если передано неправильное количество параметров. Для процедур, созданных с помощью Proc.new или Kernel.proc, дополнительные параметры игнорируются, а недостающие параметры устанавливаются в nil.

a_proc = proc {|a,b| [a,b] }
a_proc.call(1)   #=> [1, nil]

a_proc = lambda {|a,b| [a,b] }
a_proc.call(1)   # ArgumentError: wrong number of arguments (given 1, expected 2)

См. также Proc#lambda?.

clone → новый_метод Показать исходный код
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;
}

Возвращает копию этого метода.

class A
  def foo
    return "bar"
  end
end

m = A.new.method(:foo)
m.call # => "bar"
n = m.clone.call # => "bar"
curry → процедура Показать исходный код
curry(arity) → процедура
static VALUE
rb_method_curry(int argc, const VALUE *argv, VALUE self)
{
    VALUE proc = method_to_proc(self);
    return proc_curry(argc, argv, proc);
}

Возвращает процедуру, составленную на основе метода. Когда процедура вызывается с количеством аргументов меньше, чем арность метода, возвращается другая составленная процедура. Только когда достаточно аргументов, чтобы удовлетворить сигнатуру метода, метод будет фактически вызван.

Необязательный аргумент arity должен быть предоставлен при составлении методов с переменным количеством аргументов, чтобы определить, сколько аргументов необходимо, прежде чем будет вызван метод.

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]
eql?(other_meth) → true или false Показать исходный код
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;
}

Два объекта метода равны, если они связаны с одним объектом и ссылаются на одно и то же определение метода, а их владельцы — один и тот же класс или модуль.

hash → целое Показать исходный код
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);
}

Возвращает значение хэша, соответствующее объекту метода.

См. также Объект#hash.

inspect → строка Показать исходный код
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;
}

Возвращает имя базового метода.

"cat".method(:count).inspect   #=> "#<Method: String#count>"
name → символ Показать исходный код
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_name → символ Показать исходный код
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);
}

Возвращает исходное имя метода.

owner → класс_или_модуль Показать исходный код
static VALUE
method_owner(VALUE obj)
{
    struct METHOD *data;
    TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
    return data->me->owner;
}

Возвращает класс или модуль, определяющие метод.

parameters → массив Показать исходный код
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);
}

Возвращает информацию о параметрах этого метода.

receiver → объект Показать исходный код
static VALUE
method_receiver(VALUE obj)
{
    struct METHOD *data;

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

Возвращает связанный получатель объекта метода.

source_location → [строка, целое] Показать исходный код
VALUE
rb_method_location(VALUE method)
{
    return method_def_location(method_def(method));
}

Возвращает имя файла Ruby-исходника и номер строки, содержащие этот метод, или nil, если этот метод не был определён в Ruby (т.е. нативный).

super_method → метод Показать исходный код
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(RCLASS_ORIGIN(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);
}

Возвращает Метод суперкласса, который будет вызван при использовании super, или nil, если такого метода нет в суперклассе.

to_proc → процедура Показать исходный код
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;
}

Возвращает объект Proc соответствующий этому методу.

to_s → строка Показать исходный код
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;
}

Возвращает имя базового метода.

"cat".method(:count).inspect   #=> "#<Method: String#count>"
unbind → несвязанный_метод Показать исходный код
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;
}

Отсоединяет meth от его текущего получателя. Результирующий UnboundMethod может быть затем привязан к новому объекту того же класса (см. UnboundMethod).

Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API