Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(UndefinedFunctionError) function :erl_eval.match1/4 is undefined or private #55

Open
tomazzlender opened this issue Aug 16, 2016 · 7 comments

Comments

@tomazzlender
Copy link

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?

@meh
Copy link
Owner

meh commented Aug 16, 2016

What Erlang version? I've never seen this kind of error before.

@jmerriweather
Copy link

Is it due to defining User and Message twice with defmodule and deftable?

@meh
Copy link
Owner

meh commented Aug 17, 2016

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.

@tomazzlender
Copy link
Author

tomazzlender commented Aug 17, 2016

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

@tomazzlender
Copy link
Author

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.

@jmerriweather
Copy link

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?

@tomazzlender
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants