标签: elixir

在Elixir中打开模块?

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)

elixir

8
推荐指数
1
解决办法
1322
查看次数

如何删除Phoenix会话?

我正在阅读凤凰城会议指南.它很好地解释了我如何使用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)

elixir phoenix-framework

8
推荐指数
2
解决办法
5020
查看次数

在Phoenix中使用带有多个控制器的自定义视图

Phoenix,有什么方法可以指定使用哪个View而不是让Controller命名空间中的变形?

我有多个控制器,每个控制器的视图方法都相同.我想创建一个单独的视图,并与(几乎)我的所有控制器一起使用它.

这可能吗?更重要的是,这是一种不好的做法还是在我的情况下是合理的?

elixir phoenix-framework

8
推荐指数
1
解决办法
1148
查看次数

成功 Repo.update 后 Ecto 重新加载所属关联

将params 中给定的关联child从 from更改parent_aparent_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)

更新后检索新关联的父记录的正确方法是什么?

elixir ecto phoenix-framework

8
推荐指数
2
解决办法
2574
查看次数

在Plug.Router中,init函数有什么意义?

试图了解Plug,特别是Plug.Router.从文档(http://hexdocs.pm/plug/Plug.Router.html).从规范插件有一个init函数,在初始化时调用以传入选项,但那些似乎在定义的路由中不可用.

没有可用选项的原因是什么,是否有允许它的模式?

elixir

8
推荐指数
1
解决办法
765
查看次数

如何在Elixir中打印PID?

我试过了:

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>.

elixir

8
推荐指数
3
解决办法
4285
查看次数

如何在Ecto的迁移中运行更新?

我在我的一个项目中使用PhoenixEcto.

我想在一个表中添加一个列,我希望它是一个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)

elixir ecto phoenix-framework

8
推荐指数
1
解决办法
3050
查看次数

使用 Mox 测试函数链中的多个 API 调用

我正在尝试测试我是否正确地转换了从第三方 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 …

elixir mox

8
推荐指数
1
解决办法
716
查看次数

Elixir:Supervisor、GenServer 和 Application 之间的区别

我正在练习这个例子。
https://github.com/kwmiebach/how-to-elixir-supervisor

我按照说明进行操作并了解其工作原理,但我无法理解 Supervisor、GenServer 和 Application 之间究竟有何不同。

有人可以解释这 3 种有何不同以及何时应该使用它们吗?

elixir erlang-supervisor

8
推荐指数
1
解决办法
886
查看次数

检查模块是否实现了行为

我有一个行为和一个函数,它采用应该实现该行为的模块列表。我想检查传入的每个模块是否确实实现了该行为。我可以用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()

elixir

8
推荐指数
1
解决办法
891
查看次数

标签 统计

elixir ×10

phoenix-framework ×4

ecto ×2

erlang-supervisor ×1

mox ×1