为什么在ActionController :: Instrumentation :: render中不使用args参数?

问题描述

我是Ruby和Rails的新手,并且试图完全理解我正在阅读的内容

我正在查看一些Rails源代码在这种情况下为action_controller/Metal/instrumentation.rb

def render(*args)
  render_output = nil
  self.view_runtime = cleanup_view_runtime do
    Benchmark.ms { render_output = super }
  end
  render_output
end

我知道*args正在使用splat运算符将参数一起收集到一个数组中。但是在那之后,这对我来说就不再有意义了。

我无法理解为什么将render_output设置为nil,然后再将其重新分配为等于super,然后再不加任何参数地对其进行调用。我收集到一些速度测试已经完成,但是来自其他语言,我希望它更像是Benchmark.ms(render_output)Benchmark.start,然后是render_output,然后是{{1} }。我很难按照这里的工作方式进行操作。

但更重要的是,我并不真正理解为什么不再使用Benchmark.end。为什么要麻烦定义不使用的参数?我的意思是,显然它正在被使用-我只是不知道如何使用。这里有一些我尚未了解的隐藏机制。

解决方法

在这种情况下,重要的是要注意super的工作方式,因为在某些情况下它会隐式传递参数,而您可能不希望这样做。

当您拥有类似方法

def method(argument)
  super
end

然后,super将使用与当前方法完全相同的参数隐式调用method的重写实现。这意味着在此示例中,super实际上将调用super(argument)

当然,您仍然可以定义一个方法调用,以将其他参数显式发送到原始实现,如本例所示:

def method(argument)
  super(argument + 1)
end

另一个重要的极端情况是,当您希望不带任何参数的情况下显式调用super时,尽管当前方法是使用参数进行调用的,那么您需要像这样非常显式

def method(argument)
  super()                      # note the empty parentheses
end
,

让我尝试向您描述我认为这段代码的作用。

*args*

使用splat运算符将参数一起收集到一个数组中

那是完全正确的,但是他们没有使用它,如果您要转到master分支,他们只是将其更改为*。问为什么定义和不使用它,我认为这是关于不良设计的问题。他们应该将其命名为_args,或者至少现在像现在只是单个splat *

render_output由于范围而设置为nil,必须在block,lambda,proc中显式定义以便在其中存储值,否则它的可见性将仅锁定于这些lambda,proc,block执行。请参阅this article

Benchmark.start。块是伟大的红宝石建筑。您完全正确地完成了速度测试,我们可以看到它只是benchmark库的装饰器。 source。 您想知道为什么我们不能仅将其传递为Benchmark.ms(render_output),这是因为基准ms函数将得到什么?将得到结果,如<div> my html </div。以及如何测量此字符串结果-否。这就是为什么我们在此块中调用超级权限,我们想访问父类函数并将其包装在块中,所以我们不调用它,我们只是构造它,而将在benchmark lib内部调用它并进行测量像

class Benchmark
  ...
  def realtime # :yield:
    r0 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
    yield
    Process.clock_gettime(Process::CLOCK_MONOTONIC) - r0
  end
  ...
end

所以这里我们可以计算函数执行的实时性,这是original library

中的代码

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...