标签: elixir

如何在Elixir中保存HashDicts文件

任务是使用Elixir在文件中保存和加载结构的HashDict.我正计划迭代HashDict并在文件的每一行写出一个结构.但是,我无法在Google上找到有关如何将Struct或Dict保存到文件的任何内容.特别是,是否有内置的序列化Dicts的方法?

我尝试先转换为字符串.iex片段: -

iex(68)> {:ok,of} = File.open("ztest.txt", [:write, :utf8])
{:ok, #PID<0.232.0>}
iex(69)> IO.write(of, {:atuple, "abc"})                    
** (Protocol.UndefinedError) protocol String.Chars not implemented for {:atuple, "abc"}
Run Code Online (Sandbox Code Playgroud)

有人想知道如何为地图或元组实现String.chars的实现吗?

此外,是否可以将IO.inspect的输出传输到文件中?我尝试这样做是不成功的.

elixir

10
推荐指数
1
解决办法
2965
查看次数

如何覆盖凤凰城的错误?

我在凤凰上建立了宁静的api(json).而且我不需要html的支持.

如何覆盖凤凰城的错误?示例错误: - 500 - 404没有找到路由和其他.

elixir phoenix-framework

10
推荐指数
2
解决办法
2814
查看次数

对elixir的任何readline绑定支持?

我试图创造出接受用户输入的类似的方式,程序iexerl做(例如:按允许键来浏览过去的历史时).

如果标准IO.gets使用如下,

IO.gets "user> "
Run Code Online (Sandbox Code Playgroud)

按下向上允许时,控制台最终会出现以下情况.

user> ^[[A^[[A
Run Code Online (Sandbox Code Playgroud)

是否有任何函数/库具有可在elixir代码中使用的readline功能?


到目前为止我调查的是,

  • 有些语言对readline库有绑定支持,但我无法找到elixir的相应功能.
  • iex实现似乎将此功能委托给erl(/lib/iex/history.ex似乎只是管理历史列表),但我无法在erlang方面找到相应的功能.
  • 我试过了erl_ddll.load,但未能从以下方面走得更远.

在iex上,

iex(4)> :erl_ddll.load('/usr/lib', 'libreadline')
{:error, {:open_error, -10}}
iex(5)> :erl_ddll.format_error({:open_error, -10})
'dlopen(/usr/lib/libreadline.so, 2): image not found'
Run Code Online (Sandbox Code Playgroud)

我在OSX,并通过自制安装libreadline,我可以找到libreadline.dylib/usr/lib.


[关于目的的附加说明]

我正在使用elixir进行以下(mal)实验,这是一个用各种语言实现的lisp repl(但不是用elixir/erlang实现).

https://github.com/kanaka/mal

该步骤的一部分是使用历史记录实现repl,并且如果不是本地语言,则某些语言正在使用readline绑定库.

[更新一点 - 2015/3/22]

我尝试使用NIF方法(与encurses类似)来使用readline库.我可以在erlang(erl)上做一些工作,但是坚持使用elixir方面.当从C库(readline或只是普通scanf)读取输入时,"mix run -e"或"iex"似乎表现得有些奇怪(跳过或忽略某些输入),但无法找出原因.encurses似乎行为相似.

以下是我的试验.

https://github.com/parroty/ereadline

https://github.com/parroty/readline

我可能会采用像rlwrap这样的更通用的方法.

elixir

10
推荐指数
1
解决办法
1365
查看次数

Elixir脚本递归加载文件夹中的所有模块

我想在特定文件夹中递归地编译和加载所有模块.我知道我可以用Mix项目做到这一点

iex -S mix run
Run Code Online (Sandbox Code Playgroud)

这将加载lib/目录中的所有文件.

但是,我想在非混合脚本中使用相同的行为 - 如果可能的话,编程方式.有什么像这样的Code.compile_all("directory/")
API吗?

elixir

10
推荐指数
1
解决办法
3368
查看次数

使用Elixir和Phoenix框架形成对象

我不知道是否有是创建表单对象的方式ElixirPhoenix框架?我想实现类似于reformgem所做的事情,Rails因为我不喜欢在每种情况下都运行相同的验证,这导致了我的经验中的复杂代码.那么我可以创建类似下面的内容并以某种方式使其工作吗?

defmodule RegistrationForm do
  defstruct email: nil, password: nil, age: nil    

  import Ecto.Changeset       

  def changeset(model, params \\ :empty) do
    model
    |> cast(params, ["email", "password", "age"], ~w())
    |> validate_length(:email, min: 5, max: 240)       
    |> validate_length(:password, min: 8, max: 240)
    |> validate_inclusion(:age, 0..130)        
  end   

end
Run Code Online (Sandbox Code Playgroud)

elixir ecto phoenix-framework

10
推荐指数
1
解决办法
1789
查看次数

Phoenix控制器中的current_user通过Plug传递

将此代码示例作为Plug来处理身份验证:

defmodule Financeweb.APIAuth do
...

  def call(conn, _opts) do
  ...

    if authenticated_user do
      conn
      |> assign(:current_user, user)
    else
      conn
      |> send_resp(401, "{\"error\":\"unauthorized\"}")
      |> halt
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

所以,我通过current_user下游传递变量Plug.Conn.assign/3.在Phoenix控制器中获取此变量的最佳方法是什么?我这样做(下面的代码),但我确信有更好的方法来做到这一点.

def index(conn, _) do
  user_id = conn.assigns.current_user.id 
end
Run Code Online (Sandbox Code Playgroud)

elixir phoenix-framework

10
推荐指数
1
解决办法
1795
查看次数

Elixir:如何按键过滤地图

我有一个带有键值对的Map和一个带有原子的元组.我想删除地图中的任何条目,其中键不是元组中的原子

m = %{value1: nil, value2: nil, value4: nil}
t = {:value1, :value3, :value4}
# The result should be %{value1: nil, value4: nil}
Run Code Online (Sandbox Code Playgroud)

这是一种交叉问题.我调查了一下Enum.filter,MapSet但没有找到一个优雅的解决方案.这必须是一个常见问题,您的意见得到高度赞赏.

elixir

10
推荐指数
1
解决办法
3040
查看次数

使用Poison将映射编码到JSON以与Slack一起使用

我正在使用Poison将地图编码为JSON,并将其发送到Slack API.这就是Poison给我的东西:

"{\"text\":\"changed readme fad996e98e04fd4a861840d92bdcbbcb1e1ec296\"}"
Run Code Online (Sandbox Code Playgroud)

当我把它放入JSON lint时,它说它是有效的JSON,但是Slack响应"无效的有效载荷".

如果我将JSON更改为这样

{"text":"changed readme fad996e98e04fd4a861840d92bdcbbcb1e1ec296"}
Run Code Online (Sandbox Code Playgroud)

然后它工作.有谁知道我在哪里出错?我是否需要对编码的JSON进行额外处理,或者是否需要设置一些标头?

这是我的控制器

def create(conn, opts) do
    message = Message.create_struct(opts)
    response = Slack.Messages.send(message)

    case response do
      {:ok, data} ->
        render conn, json: Poison.encode!(data)
      {:error, reason} ->
        render conn, json: reason
    end
end
Run Code Online (Sandbox Code Playgroud)

这是发送消息的库的一部分

defmodule Slack.Messages do

  def format_simple_message(map) do
    text = map.description <> " " <> map.commits
    message = %{text: text}
  end

  def post_to_slack(map) do
    Slack.post(:empty, map)
  end

  def send(map) do
    map
    |> format_simple_message
    |> post_to_slack
  end

end
Run Code Online (Sandbox Code Playgroud)

我的HTTPoison处理

defmodule …
Run Code Online (Sandbox Code Playgroud)

elixir slack-api elixir-poison

10
推荐指数
1
解决办法
5160
查看次数

Elixir + Phoenix Channels内存消耗

我对Elixir和Phoenix Framework很新,所以可能我的问题有点愚蠢.

我有一个应用程序,Elixir + Phoenix Framework作为后端,Angular 2作为前端.我使用Phoenix Channels作为前端/后端交换的渠道.我发现了一个奇怪的情况:如果我从后端向前端发送大量数据,那么特定的通道进程内存消耗就会达到数百MB.即使在传输结束后,每个连接(每个通道进程)也会占用大量内存.

以下是来自后端频道说明的代码段:

defmodule MyApp.PlaylistsUserChannel do
  use MyApp.Web, :channel

  import Ecto.Query

  alias MyApp.Repo
  alias MyApp.Playlist

  # skipped ... #

  # Content list request handler
  def handle_in("playlists:list", _payload, socket) do 
    opid = socket.assigns.opid + 1
    socket = assign(socket, :opid, opid)

    send(self, :list)
    {:reply, :ok, socket}
  end

  # skipped ... #        

  def handle_info(:list, socket) do

    payload = %{opid: socket.assigns.opid}

    result =
    try do
      user = socket.assigns.current_user
      playlists = user
                  |> Playlist.get_by_user
                  |> order_by([desc: :updated_at])
                  |> Repo.all …
Run Code Online (Sandbox Code Playgroud)

elixir phoenix-framework phoenix-channels

10
推荐指数
1
解决办法
2293
查看次数

为什么在连接列表时Enum.concat比++慢得多?

我尝试使用Benchfella进行一些快速基准测试:

defmodule ConcatListBench do
  use Benchfella

  @a1 Enum.to_list(1..10_000)
  @a2 Enum.to_list(10_000..20_0000)

  bench "++" do
    @a1 ++ @a2
  end

  bench "Enum.concat" do
    Enum.concat(@a1, @a2)
  end
end
Run Code Online (Sandbox Code Playgroud)

在运行时:

$ elixir -v
Erlang/OTP 19 [erts-8.0.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Elixir 1.4.0-dev (762e7de)

$ mix bench
Settings:
  duration:      1.0 s

## ConcatListBench
[10:01:09] 1/2: ++
[10:01:20] 2/2: Enum.concat

Finished in 14.03 seconds

## ConcatListBench
benchmark na iterations   average time
++           1000000000   0.01 µs/op
Enum.concat       50000   45.03 µs/op
Run Code Online (Sandbox Code Playgroud)

问题是Enum.concat如果内部 …

benchmarking elixir

10
推荐指数
1
解决办法
589
查看次数