在哪里可以找到像 instance_exec 这样的 Native Ruby 源代码?

Posted

技术标签:

【中文标题】在哪里可以找到像 instance_exec 这样的 Native Ruby 源代码?【英文标题】:where to find Native Ruby source code such as instance_exec? 【发布时间】:2021-01-13 14:26:04 【问题描述】:

我知道有函数“method(:instance_exec).source_location”来查找源代码,但仅适用于 gems 中的代码。但在这种特殊情况下它返回 null,因为该方法来自本机 ruby​​。我在谷歌搜索,但我无法找到这是写在哪里。 在我的特殊情况下,我想更好地了解 instance_exec 如何更改 proc 范围的值

正在切线,我想为大学做这件事

precondition  divisor != 0  
postcondition  |result| result * divisor == dividend
  def divide(dividend, divisor)
    dividend / divisor
  end

我知道 instance_exec 在 proc 范围内更改了“self”值。我想在运行时将“除数”添加到 divisor != 0 proc 的范围内,我认为阅读 instance_exec 的实现会非常有帮助。 因为它是为了大学,我不能使用任何宝石来做到这一点,只有标准的红宝石

PS right_click + Go To + Implementation 只显示我

  def instance_exec(*args)
    # This is a stub implementation, used for type inference (actual method behavior may differ)
    yield
  end

【问题讨论】:

ruby-doc.org/core-2.7.0/BasicObject.html#method-i-instance_exec 谢谢,但提供的链接解释了如何使用该方法。我正在寻找它在引擎盖下的作用,它的源代码。这就是我对“它的实施”的意思,而不是如何使用它。我的目标是以某种方式扩展它,这样我不仅可以传递块的参数,还可以设置其范围的变量 github.com/ruby/ruby/blob/v2_7_1/vm_eval.c#L2003-L2033 – 不确定 C 代码将如何提供帮助。 要在块中拥有方法divisor,您必须将其添加到self所指的对象,即instance_exec的接收者 【参考方案1】:

我知道有函数“method(:instance_exec).source_location”来查找源代码,但只适用于gems中的代码。

那不是真的。 Method#source_location 适用于不在 gems 中的方法:

module Foo
  def bar; end
end

p Foo.instance_method(:bar).source_location
#=> ['test.rb', 2]

这里没有宝石。事实上,如果我根本不使用任何文件,它甚至可以工作,只需在命令行上使用ruby -e;在这种情况下,结果将是 ['-e', 2]

另一方面,如果没有 Ruby 源代码,那么它会返回 nil 即使对于 gems

Method#source_location 的返回值与方法是否来自 gem 无关,唯一重要的是是否有 Ruby 源可以定位。 p>

但在这种特殊情况下它返回 null,因为该方法来自原生 ruby​​。

它不应该返回null,它应该返回一个二元素数组或nil,但绝不应该返回null。如果真的是这样的话,您的 Ruby 安装似乎出现了严重问题。

我在谷歌上搜索,但找不到写在哪里。

它将位于您正在使用的 Ruby 实现的源代码中。你还没有指定你使用的是哪个实现,所以我不能确切地告诉你,但这里有一些例子:

在Rubinius中,在core/basic_object.rb中实现:

def instance_exec(*args, &prc)
  raise ::LocalJumpError, "Missing block" unless block_given?
  env = prc.block

  return prc.ruby_method.call(*args) if prc.ruby_method

  lexical_scope = env.lexical_scope
  if ::ImmediateValue === self
    lexical_scope = lexical_scope.using_disabled_scope
  else
    sc = ::Rubinius::Type.object_singleton_class(self)
    lexical_scope = lexical_scope.using_current_as(sc)
  end


  return env.call_under(self, lexical_scope, true, *args)
end

在TruffleRuby中,在src/main/java/org/truffleruby/core/basicobject/BasicObjectNodes.java中实现:

@CoreMethod(names = "instance_exec", needsBlock = true, rest = true)
public abstract static class InstanceExecNode extends CoreMethodArrayArgumentsNode 

    public static InstanceExecNode create() 
        return InstanceExecNodeFactory.create(null);
    

    @Child private CallBlockNode callBlockNode = CallBlockNode.create();

    abstract Object executeInstanceExec(Object self, Object[] args, RubyProc block);

    @Specialization
    protected Object instanceExec(Object receiver, Object[] arguments, RubyProc block) 
        final DeclarationContext declarationContext = new DeclarationContext(
                Visibility.PUBLIC,
                new SingletonClassOfSelfDefaultDefinee(receiver),
                block.declarationContext.getRefinements());
        return callBlockNode
                .executeCallBlock(declarationContext, block, receiver, block.block, arguments);
    

    @Specialization
    protected Object instanceExec(Object receiver, Object[] arguments, NotProvided block) 
        throw new RaiseException(getContext(), coreExceptions().localJumpError("no block given", this));
    


【讨论】:

以上是关于在哪里可以找到像 instance_exec 这样的 Native Ruby 源代码?的主要内容,如果未能解决你的问题,请参考以下文章

我可以将一个本身期望一个块的块传递给 ruby​​ 中的 instance_exec 吗?

我在哪里可以找到这个 LinkedIn 插件?

我在哪里可以找到免费的 WPF 控件

在Outlook 2019中,我在哪里可以找到Outlook日历权限?

如何告诉 lcov 在哪里可以找到我的 .cpp 和 .h 文件?

在哪里可以找到尚学堂的资料?