标签: elixir

如何将Elixir二进制转换为字符串?

所以我试图将二进制文件转换为字符串.这段代码:

t = [{<<71,0,69,0,84,0>>}]
String.from_char_list(t)
Run Code Online (Sandbox Code Playgroud)

但是当我尝试这种转换时,我得到了这个:

** (ArgumentError) argument error
    (stdlib) :unicode.characters_to_binary([{<<70, 0, 73, 0, 78, 0>>}])
    (elixir) lib/string.ex:1161: String.from_char_list/1
Run Code Online (Sandbox Code Playgroud)

我假设<< 70,0等可能是一个字形列表(它是API调用的返回,并且API没有完全记录)但我是否需要以某种方式指定编码?

我知道我可能会遗漏一些明显的东西(也许这不是正确的功能?)但我似乎无法弄清楚该怎么做.


编辑:

对于它的价值,上面的二进制文件是Erlang ODBC调用的返回值.经过一番挖掘后,我发现有问题的二进制文件实际上是"编码为UTF16小端的Unicode二进制文件"(参见此处:http://www.erlang.org/doc/apps/odbc/odbc.pdf第9页) re:SQL_WVARCHAR)并没有真正改变问题,但它确实添加了一些上下文.

unicode erlang odbc elixir

11
推荐指数
4
解决办法
2万
查看次数

Elixir宏:如何用动态arity定义函数

参考这篇文章:如何使用Elixir宏创建动态函数名称?.

上面的帖子询问如何使用宏来生成没有参数的函数,但我想知道如何用一些参数生成函数?

假设有一个宏warp,我可以写代码如下:

warp fun, [args], :ok
Run Code Online (Sandbox Code Playgroud)

然后它生成如下代码:

fun(args), do: :ok
Run Code Online (Sandbox Code Playgroud)

macros elixir

11
推荐指数
1
解决办法
1664
查看次数

Elixir - 在主管下获取进程的所有PID

我有一个主管,想要知道在任何给定时间在该主管下运行的所有进程.似乎应该有一种简单的方法来获取Supervisor或节点下所有进程的所有PID,名称等,但我找不到任何东西.

有关如何做到这一点的任何建议?

elixir erlang-otp

11
推荐指数
1
解决办法
3482
查看次数

使用Ecto(MySQL)进行upsert的最简单方法是什么?

在我的应用程序中执行upsert很常见,我想实现最简洁的方法来实现upsert.

  1. 我应该使用片段来实现本机sql upsert吗?
  2. 任何惯用的ecto方式做upsert?

mysql elixir ecto phoenix-framework

11
推荐指数
2
解决办法
6961
查看次数

如果params不是零,那么执行惯用药吗?

在继续处理参数之前,如何过滤掉无效参数如nil或空列表?

case下面的用法似乎很常见,但代码并不清楚 - 我很确定有一种更简单和惯用的方法可以做到这一点.

 def load(token) do

   case token do
     nil -> nil
     [] -> nil
     token -> process(token)
   end

 end
Run Code Online (Sandbox Code Playgroud)

elixir

11
推荐指数
2
解决办法
2万
查看次数

依赖项目中的重复协议实现

我在Elixir项目中整合协议实现时遇到问题.更具体地说,我使用了Ecto一些简单的项目Gold(无关紧要).问题是,它们(EctoGold)都Poison用于序列化Decimals(并实现适当的协议).

Ecto外观的实现有点像这样:

defimpl Poison.Encoder, for: Decimal do
    def encode(decimal, _opts), do: <<?", Decimal.to_string(decimal)::binary, ?">>
end
Run Code Online (Sandbox Code Playgroud)

在开发期间,有一个警告说该模块是重复的:

warning: redefining module Poison.Encoder.Decimal (current version loaded from /(...)/_build/dev/lib/gold/ebin/Elixir.Poison.Encoder.Decimal.beam)
  lib/ecto/poison.ex:2
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用例如exrm构建版本时,我会收到错误,说我有duplicate_modules

===> Provider (release) failed with: {error,
                     {rlx_prv_assembler,
                      {release_script_generation_error,
                       systools_make,
                       {duplicate_modules,
                        [{{'Elixir.Poison.Encoder.Decimal',
                           gold,
                           "/(...)/rel/bitcoin_api/lib/gold-0.12.0/ebin"},
                          {'Elixir.Poison.Encoder.Decimal',
                           ecto,
                           "/(...)/rel/bitcoin_api/lib/ecto-2.0.2/ebin"}}]}}}}
Run Code Online (Sandbox Code Playgroud)

我应该怎么处理这个?这里的情况是我实际使用我自己的版本Gold,所以我可以篡改它来尽快解决它.我知道我可以再补充EctoGold作为依赖,但似乎有点矫枉过正,只是实现一个协议是这样的.是否有某种宏来检查模块是否已经实现?

decimal elixir ecto exrm elixir-poison

11
推荐指数
1
解决办法
415
查看次数

在GenServer.start_link/3中使用{:via,module,term}注册名称有什么好处?

GenServer.start_link/3我可以使用原子在本地注册一个名称,用于这样的过程:

defmodule Worker do
  use GenServer

  def start_link do
    GenServer.start_link(__MODULE__, nil, name: :worker)
  end
end
Run Code Online (Sandbox Code Playgroud)

然后我可以开始一个主管来监督这个过程:

defmodule Boss do
  use Supervisor

  def init(_) do
    children = [worker(Worker, [])]
    supervise(children, strategy: :one_for_one)
  end
end
Run Code Online (Sandbox Code Playgroud)

现在我想让主管监督3个Worker进程,所以我需要为这3个进程提供唯一的名称,这样当supervisor重新启动进程时,它将始终使用相同的符号名称.

我可以简单地使用字符串插值作为唯一的Worker进程名称,如下所示:

defmodule Worker do
  use GenServer

  def start_link(id) do
    GenServer.start_link(__MODULE__, nil, name: :"worker_#{id}")
  end
end
Run Code Online (Sandbox Code Playgroud)

然后监督3个这样的过程:

defmodule Boss do
  use Supervisor

  def init(_) do
    children = for id <- 1..3 do
      worker(Worker, [id], id: id)
    end
    supervise(children, strategy: :one_for_one)
  end …
Run Code Online (Sandbox Code Playgroud)

elixir erlang-otp gen-server erlang-supervisor

11
推荐指数
2
解决办法
1952
查看次数

在地图上操作时,Elixir中是否保留了键和值的排序?

假设我在Elixir有一张地图:

m = %{"a"=>1, "b"=>2, "c" => 3}
Run Code Online (Sandbox Code Playgroud)

如果我打电话Map.values(m),我保证返回值总是按[1, 2, 3]顺序而不是说,[3, 1, 2]

这是我从文档中不清楚的一件事.经过一些初步测试,我认为是.

elixir

11
推荐指数
2
解决办法
4689
查看次数

在命令行中获取光标位置(Elixir)

我想知道是否有一种方法可以从Elixir中获取命令行中的绝对光标位置.

我知道我必须使用以下ansi转义序列\ 033 [6n,执行后:

echo -en "\033[6n" 
Run Code Online (Sandbox Code Playgroud)

打印正是我正在寻找的,但我不知道如何从Elixir得到命令响应.

谢谢!

elixir

11
推荐指数
2
解决办法
608
查看次数

集群中的全局动态Supervisor

我有一个独特的问题,我没有必要在elxir中解决.

我需要使用动态管理器在群集环境中动态启动(n)数量的子项.我使用libcluster来管理集群并使用全局进程注册表来查找动态管理程序pid ..以下是发生的事情:

global: Name conflict terminating {:packer_supervisor, #PID<31555.1430.0>}
Run Code Online (Sandbox Code Playgroud)

以下是主管的代码:

defmodule EcompackingCore.PackerSupervisor do
  use DynamicSupervisor
  require Logger

  def start_link() do
    DynamicSupervisor.start_link(__MODULE__, :ok, name: {:global, :packer_supervisor})
  end

  def init(:ok) do
    Logger.info("Starting Packer Supervisor")
    DynamicSupervisor.init(strategy: :one_for_one)
  end

  def add_packer(badge_id, packer_name) do
    child_spec = {EcompackingCore.Packer, {badge_id, packer_name}}
    DynamicSupervisor.start_child(:global.whereis_name(:packer_supervisor), child_spec)
  end

  def remove_packer(packer_pid) do
    DynamicSupervisor.terminate_child(:global.whereis_name(:packer_supervisor), packer_pid)
  end

  def children do
    DynamicSupervisor.which_children(:global.whereis_name(:packer_supervisor))
  end

  def count_children do
    DynamicSupervisor.count_children(:global.whereis_name(:packer_supervisor))
  end

end
Run Code Online (Sandbox Code Playgroud)

问题似乎是主管在两个节点上启动.处理这个问题的最佳方法是什么?我真的需要主管是动态的,所以我可以有效地管理工作模块.可能是一个不同的注册表?

谢谢你的帮助.

cluster-analysis elixir

11
推荐指数
1
解决办法
258
查看次数