【发布时间】:2016-05-09 01:11:09
【问题描述】:
elixir 的 pry 可以在模块内运行私有方法吗?例如:
defmodule Test do
require IEx
def foo do
IEx.pry
end
defp bar do
end
end
此时调用bar 不起作用。我对 Elixir 很陌生,是不是我做错了什么或者无法做到这一点的原因?
【问题讨论】:
elixir 的 pry 可以在模块内运行私有方法吗?例如:
defmodule Test do
require IEx
def foo do
IEx.pry
end
defp bar do
end
end
此时调用bar 不起作用。我对 Elixir 很陌生,是不是我做错了什么或者无法做到这一点的原因?
【问题讨论】:
这是预期的行为,因为 IEx.pry 允许您访问调用它的函数的本地变量,但它不会将您置于被撬模块的范围内。
来自IEx.pry 文档:
当一个进程被撬动时,所有代码都在 IEx 内运行,因此,它被评估并且不能访问被撬动模块的私有函数。模块函数仍然需要通过 Mod.fun(args) 访问。
为了进一步说明,您可以检查__MODULE__ 的值。如果您从 IEx 运行它,它的计算结果为 nil(因为您不在 defmodule 块中):
iex(1)> __MODULE__
nil
如果您修改foo 来检查当前模块,您不会有任何意外:
defmodule Test do
require IEx
def foo do
IO.inspect __MODULE__
IEx.pry
end
defp bar do
end
end
现在我们在 iex 中求值并得到适当的结果,但在 pry 中,函数是在 IEx 上下文中求值的(可以这么说),所以如果我们检查当前模块,我们会再次得到 nil。
iex(1)> Test.foo
Test
# ... we skip pry ceremony
pry(1)> __MODULE__
nil
现在我们可以看到发生了什么以及为什么我们不能从 IEx.pry 执行私有函数
我知道如果你有 ruby 背景,这会令人惊讶,因为你可以访问几乎任何你想要的东西,只要你在正确的对象或类的上下文中评估一个块,但在 elixir 中的函数调度基本上是不同。
【讨论】: