标签: elixir

创建新的保护条款

在Elixir中,我将如何为函数创建新的保护条款?显然,我已经看到你不能只在一个when语句中调用任何函数,但是能够做到这样的事情会很好:

defmodule Player do
  def play_card(player), do: []
  def play_card(player) when has_cards(player), do: ...
  # Define has_cards as guard clause?
end
Run Code Online (Sandbox Code Playgroud)

function elixir pattern-matching

17
推荐指数
2
解决办法
5036
查看次数

Erlang(或elixir)性能(每秒请求数)对jruby缓慢?

作为一个rubyist,我决定采用erlang来获得高性能,可靠的后端.设置非常简单:获取发布请求,将内容写入redis,返回统计信息.所有的json.这也是为什么我非常关心每秒的请求.

选择的工具:webmachine,瞬间对JSON编码/解码,poolboy用于连接池,并且eredis为redis的通信.

机器使用:macbook pro,i5 2.4Ghz,8GB内存.

我的erlang每秒大约有5000个请求,jruby/torqbox大约有12,0000个.(在这里查看完整的ruby性能测试设置)

我意识到我可以在erlang中使用ets来节省时间,并且在响应之后留下用于"后台处理"的redis,但这将没有什么影响.甚至是对'你好世界'背后的二郎腿的简单测试.

有什么建议?我做错了吗?

erlang performance elixir requests-per-second webmachine

17
推荐指数
3
解决办法
9764
查看次数

什么 在Elixir做

我知道String.strip/2,但我无法弄清楚它用于删除空格的用法.

String.strip "_some_", ?_   #=> "some"
Run Code Online (Sandbox Code Playgroud)

如果字符串有空格而不是_,那么如何删除它们?而且,如果有人可以解释什么,那会很棒吗?在这里意味着

elixir

17
推荐指数
2
解决办法
3965
查看次数

在Elixir中执行基本的shell命令

在学习语言的早期阶段,并通过ElixirSips系列视频进行工作.我一直在打一些被语言变化略微痴迷的东西.试图围绕这一点,谷歌/ Github问题追踪器/ SO拖网让我无处可用.我有这个非常基本的模块,它应该运行一个shell命令:

defmodule QuickieSynth.Sound do
  def command(note) do
    "play -qn synth 2 pluck #{note}"
  end

  def play(note) do
    note |> command |> System.cmd
  end
end
Run Code Online (Sandbox Code Playgroud)

但是,当编译此文件并运行测试时,我得到一个参数错误; 足够公平 - System.cmd/1似乎不再是标准库的一部分.

System.cmd/3 在标准库,并读取文档所指示的选项,以及,可选的.所以我通过空的args note |> command |> System.cmd([]),我得到的是erlang: :enoent:再次仔细阅读文档后,再次公平.

所以我尝试使用Erlang :os.cmd/1,所以note |> command |> :os.cmd,我得到了(FunctionClauseError) no function clause matching in :os.validate/1.我现在卡住了.

erlang elixir

17
推荐指数
1
解决办法
3806
查看次数

在Ecto中插入关联的模型

我正在尝试插入发票结构及其关联的发票项目.我可以插入发票数据,并调用匿名函数来验证,转换和插入每个项目.由于insert/2不会产生返回,如果一个项目未通过验证或插入,如何在仍然能够回滚整个事务的同时获取项目的invoice_id?

我把代码放在我自己的回购中,这里是:

def insertassoc(params) do
 Repo.transaction(fn ->    
  i = Invoice.changeset(params["data"], :create)
    if i.valid? do
      Repo.insert(i)
    else
      Repo.rollback(i.errors)
    end

  insert_include = fn k ->
    c = InvoiceItem.changeset(k, :create)
    if c.valid? do
      Repo.insert(c)
    else
      Repo.rollback(c.errors)
    end
  end

  for include <- params["includes"] do
    insert_include.(Map.merge(include, %{"invoice_id" => ????}))
  end

 end)
end
Run Code Online (Sandbox Code Playgroud)

以下是我在控制器中使用它的方法:

def create(conn, params) do
 case InvoiceRepo.insertassoc(params) do
  {:ok, x} ->
    json conn, Map.merge(params, %{"message" => "OK"})
  {:error, x} ->
    json conn |> put_status(400), Map.merge(params, %{"message" 
    => "Error"})
 end
end
Run Code Online (Sandbox Code Playgroud)

有没有很多最新的例子与Ecto,所以抱歉,如果这些是noob问题;-).有人有想法吗?我尝试将发票插入放在私有函数中,并使用case块来确定主事务是否应回滚,但我无法弄清楚如何从中获取发票ID.

elixir ecto phoenix-framework

17
推荐指数
2
解决办法
8397
查看次数

如何在eex中检查变量是否存在?

我正在研究一个模型的crud部分,我已经添加了图像支持.理想情况下,如果您正在编辑模型,我想显示图像,我会这样做.

<%= Logo.url({@company.logo, @company}, :thumb) %>
Run Code Online (Sandbox Code Playgroud)

问题是公司变量仅在编辑操作中可用,因为新操作上还有公司,所以我需要检查@company是否已设置.

<%= unless @company do %>
  <%= Logo.url({@company.logo, @company}, :thumb) %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

问题是,这会产生以下错误.

"分配@company在eex模板中不可用.可用分配:[:action,:changeset]"

我尝试使用is_nil,但同样的错误.

elixir phoenix-framework

17
推荐指数
1
解决办法
7304
查看次数

在没有模型或变更集的情况下使用form_for

我正在尝试创建一个只有一个文本字段和一个隐藏字段的表单,我将在将数据传递给HTTP API时使用,因此我没有与之关联的模型,并且通过扩展,没有变更.

是否可以这样做并使用form_for或只是编写HTML来创建表单的答案?

elixir phoenix-framework

17
推荐指数
1
解决办法
5052
查看次数

有没有办法在凤凰城定义自定义路线?

假设我想创建一个resources向它添加几个自定义动作,rails中的模拟是:

resources :tasks do
  member do
    get :implement
  end
end
Run Code Online (Sandbox Code Playgroud)

这不仅会给我带来7条标准路线,还会带来1条新路线:

GET /tasks/:id/implement
Run Code Online (Sandbox Code Playgroud)

我怎么能在凤凰城做到这一点?

elixir phoenix-framework

17
推荐指数
3
解决办法
4743
查看次数

Elixir是否提供了更简单的方法来获取GenServer进程的当前状态?

给定一个简单的GenServer过程.

defmodule KVServer do
  use GenServer

  def start do
    GenServer.start(__MODULE__, %{}, name: :kv_server)
  end

  def store(k, v) do
    GenServer.cast(:kv_server, {:store, k, v})
  end

  def handle_cast({:store, k, v}, state) do
    {:noreply, Map.put(state, k, v)}
  end
end
Run Code Online (Sandbox Code Playgroud)

我可以使用当前的进程状态 :sys.get_status/1

iex(1)> {:ok, pid} = KVServer.start
{:ok, #PID<0.119.0>}
iex(2)> KVServer.store(:a, 1)
:ok
iex(3)> KVServer.store(:b, 2)
:ok
iex(4)> {_,_,_,[_,_,_,_,[_,_,{_,[{_,state}]}]]} = :sys.get_status(pid)
...
iex(5)> state
%{a: 1, b: 2}
Run Code Online (Sandbox Code Playgroud)

只是想知道Elixir提供了一种更简单的方法来获得GenServer流程的当前状态吗?

elixir gen-server

17
推荐指数
1
解决办法
3083
查看次数

正常关闭GenServer

我用GenServer编写了一个Elixir应用程序,它在启动时启动外部应用程序并关闭它并在退出时进行其他清理.我在init/1回调中的回调和清理代码中添加了启动功能terminate/2.

init当GenServer开始代码工作正常,并且terminate也被称为方法中,当:stop被手动发送信号,但在意外停机和中断的情况下(如在按下Ctrl + C的情况下)在IEx标志,该终止代码是不叫.


目前,我已经完成了大量的论坛帖子,博客文章和文档,包括:

来自Elixir Docs - GenServers:

如果在没有捕获退出时从任何进程GenServer接收到退出信号(即不是:normal),它将以相同的原因突然退出,因此不会调用terminate/2.请注意,过程确实NOT默认陷阱退出,并且当链接的过程退出或它的节点断开发送一个退出信号.

因此,不保证terminate/2GenServer退出时调用 .出于这些原因,我们通常建议通过使用监控或链接本身在分离的流程中实现重要的清理规则.

但我完全不知道如何获得:init.stop,linked processes或其他任何与此相关的工作(因为这是我第一次使用GenServers).


这是我的代码:

defmodule MyAwesomeApp do
  use GenServer

  def start do
    GenServer.start_link(__MODULE__, nil)
  end

  def init(state) do
    # Do Bootup stuff

    IO.puts "Starting: #{inspect(state)}"
    {:ok, state}
  end

  def terminate(reason, state) do …
Run Code Online (Sandbox Code Playgroud)

elixir gen-server

17
推荐指数
2
解决办法
7489
查看次数