amnesia
amnesia copied to clipboard
(UndefinedFunctionError) function :erl_eval.match1/4 is undefined or private
When I try to use example code in IEx
Amnesia.transaction do
john = %User{name: "John", email: "[email protected]"} |> User.write
end
error is raised.
** (UndefinedFunctionError) function :erl_eval.match1/4 is undefined or private
(uym) User.write(%User{email: "[email protected]", id: nil, name: "John"})
(stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
(stdlib) erl_eval.erl:438: :erl_eval.expr/5
(mnesia) mnesia_tm.erl:835: :mnesia_tm.apply_fun/3
(mnesia) mnesia_tm.erl:810: :mnesia_tm.execute_transaction/5
in lib/database.ex is example code from README. Database was created using
mix amnesia.create -db Database --disk
Content of database.ex
use Amnesia
defdatabase Database do
deftable User
deftable Message, [:user_id, :content], type: :bag do
@type t :: %Message{user_id: integer, content: String.t}
def user(self) do
User.read(self.user_id)
end
def user!(self) do
User.read!(self.user_id)
end
end
deftable User, [{ :id, autoincrement }, :name, :email], type: :ordered_set, index: [:email] do
@type t :: %User{id: non_neg_integer, name: String.t, email: String.t}
def add_message(self, content) do
%Message{user_id: self.id, content: content} |> Message.write
end
def add_message!(self, content) do
%Message{user_id: self.id, content: content} |> Message.write!
end
def messages(self) do
Message.read(self.id)
end
def messages!(self) do
Message.read!(self.id)
end
end
end
defmodule User do
defstruct id: nil, name: nil, email: nil
end
defmodule Message do
defstruct user_id: nil, content: nil
end
I use Elixir 1.3.2
, {:amnesia, "~> 0.2.4"}
.
What could be wrong?
What Erlang version? I've never seen this kind of error before.
Is it due to defining User and Message twice with defmodule and deftable?
That shouldn't be an issue, the actual module name inside the defdatabase gets prefixed with the database module name, so they don't collide.
But now that you point that out I'm not entirely sure what the User
inside the transaction is referring to.
@meh it is Erlang/OTP version 19, more specifically 19.0.2.
Modules User and Message are defined because otherwise I got this error.
User.__struct__/1 is undefined, cannot expand struct User
I tried now running code prefixed with database name:
Amnesia.transaction do
john = %Database.User{name: "John", email: "[email protected]"} |> Database.User.write
end
And result was :badarg
.
Hm, not sure why I got :badarg before. I ran above code again and it worked OK.
So I guess the question is why prefixing module User inside Amnesia.transaction block does not work.
Why do you define separate structs for User
and Message
?
Can't you just alias Database.User
and alias Database.Message
at the top of your file?
@jmerriweather agree, it doesn't make sense to have them.
Is using Database.User instead of User inside transaction block expected behaviour? If it is, I can update README example.