如何在另一个`iex`中自动加载新编译的模块



我打开了一个bash终端进行编译。并为iex打开另一个终端,打开命令为iex -S mix

我修改前的代码如下:

defmodule Mirror.Imports.Product do
use Ecto.Schema
import Ecto.Changeset
def test do
IO.inspect("hello world")
end

编译后,代码如下:

def test do
IO.inspect("hello world1")
end

第一个终端中的编译命令如下:

mix compile

我在第二个iex中发现,编译后的模块没有自动加载,我需要关闭iex并再次打开它。

如何将其配置为使新编译的模块自动加载到所有其他iex中?

mix.exs文件如下:

defmodule Mirror.MixProject do
use Mix.Project
def project do
[
app: :mirror,
version: "0.1.0",
elixir: "~> 1.12",
elixirc_paths: elixirc_paths(Mix.env()),
# compilers: [:gettext] ++ Mix.compilers(),
compilers: Mix.compilers(),
start_permanent: Mix.env() == :prod,
aliases: aliases(),
deps: deps()
]
end
# Configuration for the OTP application.
#
# Type `mix help compile.app` for more information.
def application do
[
mod: {Mirror.Application, []},
extra_applications: [:logger, :runtime_tools]
]
end
# Specifies which paths to compile per environment.
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
# Specifies your project dependencies.
#
# Type `mix help deps` for examples and options.
defp deps do
[
{:phoenix, "~> 1.6.10"},
{:phoenix_ecto, "~> 4.4"},
{:ecto_sql, "~> 3.6"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "~> 3.0"},
{:phoenix_live_reload, "~> 1.2", only: :dev},
{:phoenix_live_view, "~> 0.17.5"},
# {:floki, ">= 0.30.0", only: :test},
{:phoenix_live_dashboard, "~> 0.6"},
{:esbuild, "~> 0.4", runtime: Mix.env() == :dev},
{:swoosh, "~> 1.3"},
{:telemetry_metrics, "~> 0.6"},
{:telemetry_poller, "~> 1.0"},
{:gettext, "~> 0.18"},
{:jason, "~> 1.2"},
{:plug_cowboy, "~> 2.5"},
{:nimble_csv, "~> 1.2"},
{:iconv, "~> 1.0"},
{:floki, "~> 0.33.0"},
{:html5ever, "~> 0.13.0"},
{:fast_html, "~> 2.0"}
#{:csv, "~> 2.5"}
]
end
# Aliases are shortcuts or tasks specific to the current project.
# For example, to install project dependencies and perform other setup tasks, run:
#
#     $ mix setup
#
# See the documentation for `Mix` for more info on aliases.
defp aliases do
[
setup: ["deps.get", "ecto.setup"],
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
"ecto.reset": ["ecto.drop", "ecto.setup"],
test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"],
"assets.deploy": ["esbuild default --minify", "phx.digest"]
]
end
end

通常,当您启动iex会话时,它会启动应用程序的一个单独实例(一个节点(,这意味着每个节点都有自己的内存。对一个节点的任何更改都不会影响另一个。除非您特别告诉另一个节点从磁盘重新加载模块,否则它将继续使用加载到内存中的版本。每个实例都保持隔离。

这里的技巧是从2个(或多个(不同的iex会话登录到SINGLE节点。诀窍是指定--remsh选项来连接到远程节点。

在一个终端

启动iex会话并使用--sname选项为其命名

iex --sname conn1 -S mix

该应用程序将从以下内容开始:

Interactive Elixir (1.13.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(conn1@MacBook-Pro)1>

请注意iex提示--它会显示节点名。CCD_ 9。

在第二个终端

现在,您可以连接到在"第一个终端"窗口中运行的节点。您必须为第二个节点指定一个唯一的名称,因此您可以再次使用--sname选项,但权力在于--remsh选项。这里是您从第一个终端连接指定节点名称的位置:

iex --sname conn2 --remsh conn1@MacBook-Pro
# or... omit the hostname if you're on the same host
iex --sname conn2 --remsh conn1

当您在第二次连接中到达iex提示时,您会注意到它显示了您为第一次连接指定的短名称:

iex(conn1@MacBook-Pro)1>

现在,当您在一个窗口中执行recompile操作时,第二个窗口也会受到影响。为什么?因为它是下面的同一个节点。。。他们正在使用相同的内存。

请注意,两个iex会话之间仍然存在一些间隔。例如,您不能在一个窗口中定义一个变量,然后在另一个窗口读取它——这是因为两个iex会话都在不同的进程中运行。在两个窗口中检查self()的输出:它们不同。请记住,Elixir在进程之间保持着强大的隔离,因此发生的任何变量绑定都保留在单个进程的范围内。

最新更新