Ruby有开放的类,非常方便(虽然受到一些人的谴责),Elixir大量借用Ruby,所以我希望Elixir允许我重新打开一个模块并在关闭后添加宏,但这不起作用我试过的方式.有办法做到这一点吗?Elixir中是否提供此功能?
为了具体化,让我们以Chris McCord的Metaprogramming Elixir为例:
defmodule Math do
defmacro say({:+, _, [lhs, rhs]}) do
quote do
lhs = unquote(lhs)
rhs = unquote(rhs)
result = lhs + rhs
IO.puts "#{lhs} plus #{rhs} is #{result}"
result
end
end
defmacro say({:*, _, [lhs, rhs]}) do
quote do
lhs = unquote(lhs)
rhs = unquote(rhs)
result = lhs * rhs
IO.puts "#{lhs} times #{rhs} is #{result}"
result
end
end
end
Run Code Online (Sandbox Code Playgroud)
如果我然后添加一个宏用于减法
defmodule Math do
defmacro say({:-, _, [lhs, rhs]}) do
quote do
lhs = unquote(lhs)
rhs …Run Code Online (Sandbox Code Playgroud) 我正在阅读凤凰城会议指南.它很好地解释了我如何使用put_session以后使用和获取值来将数据绑定到会话,get_session但它没有告诉我如何删除用户的会话.
从指南:
defmodule HelloPhoenix.PageController do
use Phoenix.Controller
def index(conn, _params) do
conn = put_session(conn, :message, "new stuff we just set in the session")
message = get_session(conn, :message)
text conn, message
end
end
Run Code Online (Sandbox Code Playgroud) 在Phoenix,有什么方法可以指定使用哪个View而不是让Controller命名空间中的变形?
我有多个控制器,每个控制器的视图方法都相同.我想创建一个单独的视图,并与(几乎)我的所有控制器一起使用它.
这可能吗?更重要的是,这是一种不好的做法还是在我的情况下是合理的?
将params 中给定的关联child从 from更改parent_a为parent_bvia 会parent_id留下一个陈旧的record.parent对象。
例如(假设参数匹配%{child: %{id: '1', parent_id: '6'}})
# ...
child = Repo.get(Child, child_id)
|> preload([:parent])
changeset = Child.changeset(child, child_params)
case Repo.update(changeset) do
{:ok, child} ->
IO.puts child.parent_id # returns '6', or the new, changed `id`
IO.puts child.parent.id # returns '5', or the old id
# child.parent is stale
# ...
Run Code Online (Sandbox Code Playgroud)
更新后检索新关联的父记录的正确方法是什么?
试图了解Plug,特别是Plug.Router.从文档(http://hexdocs.pm/plug/Plug.Router.html).从规范插件有一个init函数,在初始化时调用以传入选项,但那些似乎在定义的路由中不可用.
没有可用选项的原因是什么,是否有允许它的模式?
我试过了:
pid = spawn fn -> 1 + 2 end
IO.puts(pid)
IO.puts(IO.inspect(pid))
Run Code Online (Sandbox Code Playgroud)
并且都给了一个
** (Protocol.UndefinedError) protocol String.Chars not implemented for #PID<0.59.0>
Run Code Online (Sandbox Code Playgroud)
必须有一种方法来获得"#PID <0.59.0>"的表示pid,因为REPL打印出来#PID<0.59.0>.
我想在一个表中添加一个列,我希望它是一个NOT NULL列.但是我已经有了一些已存在的数据,所以我决定添加列,将所有行更新为某个值并将列修改为NOT NULL.
我尝试了这两个代码:
# solution 1
def up do
alter table(:channels) do
add :type, :integer
Exchat.Repo.update_all("channels", set: [type: 1])
modify :type, :integer, null: false
end
end
# solution 2
def up do
alter table(:channels) do
add :type, :integer
end
Exchat.Repo.update_all("channels", set: [type: 1])
alter table(:channels) do
modify :type, :integer, null: false
end
end
Run Code Online (Sandbox Code Playgroud)
他们两个都没有工作,我得到的错误如下:
23::40::07.514 [info] == Running Exchat.Repo.Migrations.AddTypeToChannels.up/0 forward
23::40::07.541 [debug] UPDATE "channels" AS c0 SET "type" = $1 …Run Code Online (Sandbox Code Playgroud) 我正在尝试测试我是否正确地转换了从第三方 api 返回的数据。我在使用 Mox 时遇到了一些麻烦,因为我需要在数据转换期间点击两个单独的端点。让我通过发布代码更清楚地解释:
test "players/0 return all active players" do
Statcasters.SportRadarNbaApi.ClientMock
|> expect(:league_hierarchy, fn ->
{:ok, league_hierarchy_map()}
end)
Statcasters.SportRadarNbaApi.ClientMock
|> expect(:team_profile, fn _ ->
{:ok, team_profile_map()}
end)
assert Statcasters.Sports.Nba.get_players() == ["Kevon Looney", "Patrick McCaw"]
end
Run Code Online (Sandbox Code Playgroud)
def get_players do
with {:ok, hierarchy} <- @sport_radar_nba_api.league_hierarchy,
team_ids <- get_team_ids(hierarchy),
players <- get_team_players(team_ids)
do
IO.inspect players
end
end
defp get_team_players(team_ids) do
for team_id <- team_ids do
{:ok, team} = @sport_radar_nba_api.team_profile(team_id)
end
end
Run Code Online (Sandbox Code Playgroud)
忽略编写的代码实际上不会通过测试的事实。这是我试图弄清楚的测试失败。
第二个 api 调用team_profile在测试中被调用两次,因为我遍历了两次,team_ids …
我正在练习这个例子。
https://github.com/kwmiebach/how-to-elixir-supervisor
我按照说明进行操作并了解其工作原理,但我无法理解 Supervisor、GenServer 和 Application 之间究竟有何不同。
有人可以解释这 3 种有何不同以及何时应该使用它们吗?
我有一个行为和一个函数,它采用应该实现该行为的模块列表。我想检查传入的每个模块是否确实实现了该行为。我可以用MyBehaviour.implemented_by?/1下面的方法做到这一点,但我想知道是否有更直接的方法。
defmodule MyBehaviour do
@callback do_something(String.t(), String.t()) :: no_return()
def implemented_by?(module) do
:attributes
|> module.module_info()
|> Enum.member?({:behaviour, [__MODULE__]})
end
end
Run Code Online (Sandbox Code Playgroud)
这是检查的最好方法吗?我在文档或 Elixir 论坛或任何地方都找不到任何内容。
我应该检查一下吗?或者我应该让责任完全落在来电者身上?行为是否更多是关于“我想确保我实现所有需要的东西”而不是“我希望其他人知道我实现了所有需要的东西”?
有没有办法在 typespecs 中使用行为作为类型?我的函数规范可以说 args 应该实现我的行为,还是应该只使用module()/atom()?