首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用method_missing委托的方法的一致性

使用method_missing委托的方法的一致性
EN

Stack Overflow用户
提问于 2012-12-10 01:34:17
回答 2查看 417关注 0票数 3

当我将类A的实例上的方法委托给$delegation_target时,如下所示:

代码语言:javascript
复制
$delegation_target = ""
class A
  def method_missing *args, ≺ $delegation_target.send(*args, &pr) end
  def respond_to_missing? *args; $delegation_target.respond_to?(*args) end
end

A实例上的方法的arity返回-1,而与$delegation_target上的方法的arity无关

代码语言:javascript
复制
def $delegation_target.foo; end
A.new.method(:foo).arity # => -1

def $delegation_target.foo arg1; end
A.new.method(:foo).arity # => -1

def $delegation_target.foo arg1, arg2; end
A.new.method(:foo).arity # => -1

def $delegation_target.foo arg1, arg2, arg3; end
A.new.method(:foo).arity # => -1

这个-1是从哪里来的?还有,有没有办法使得对于任何可能的方法名mA.new.method(m).arity都会返回$delegation_target.method(m)的any (如果已定义)?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-10 01:59:33

Object#method以一种特殊的方式处理respond_to_missing? & method_missing。让我们深入研究Ruby C源代码,看看会发生什么:

Object#method开始,我们调用mnew,它为被调用的对象和传递的id创建一个新的Method对象。在mnew的源代码中,我们可以很容易地看到未定义方法时的特殊处理,但当给定id时,respond_to_missing?返回true

代码语言:javascript
复制
if (UNDEFINED_METHOD_ENTRY_P(me)) {
    ID rmiss = rb_intern("respond_to_missing?");
    VALUE sym = ID2SYM(id);

    if (obj != Qundef && !rb_method_basic_definition_p(klass, rmiss)) {
        if (RTEST(rb_funcall(obj, rmiss, 2, sym, scope ? Qfalse : Qtrue))) {
            def = ALLOC(rb_method_definition_t);
            def->type = VM_METHOD_TYPE_MISSING;
            def->original_id = id;
            // ...

def->type = VM_METHOD_TYPE_MISSING;很重要。找到definition for VM_METHOD_TYPE_MISSING,我们看到它是一个“method_missing(id)的包装器”。因此,从本质上讲,返回的方法实际上只是method_missing,第一个参数已经被指定为您最初试图获取的方法的id。

我们可以通过验证method_missing的正确率与我们得到的相同来确认我们的怀疑:

代码语言:javascript
复制
A.new.method(:method_missing).arity  #=> -1

顺便说一句,-1的多重性意味着该方法可以接受无限数量的参数。

至于是否可以让它返回被调用的…方法的“真实”性值不,你不能。首先,Ruby不会假设你的method_missing中发生了什么,甚至不知道它只是简单地委托给其他一些方法。

票数 6
EN

Stack Overflow用户

发布于 2012-12-10 01:58:18

负数表示有最后一个带*前缀的参数。如果有一个必选参数后跟一个*-前缀(即一个必选参数和一个可选的额外量),则该参数将表示为-2,所以-n-1,其中n是所需参数的数量。

- n -1被称为n的1的补码,ruby甚至有一个运算符来获取所需参数的数量,即~运算符。

代码语言:javascript
复制
p ~A.new.method(:foo).arity #=> 0
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13789849

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档