Shun_di

Shun_di

Hi,

I’m just starting out with Elixir, however I have used Erlang for about half a year so its not to hard to make the jump across.

However, I am having real trouble with using Erlang records in Elixir.

I have an existing hrl file in a dependency that has two records. I want to be able to extract them and then populate them for use elsewhere.

I am using the following syntax to try and extract them:

Record.defrecord :record_name, Record.extract(:record_name, from: "deps/mydependency/include/header_file.hrl")

However, when I try to compile this I get the following:

== Compilation error in file lib/otherdb.ex ==
** (ArgumentError) cannot invoke defmacro/2 inside function/macro
    (elixir) lib/kernel.ex:5187: Kernel.assert_no_function_scope/3
    (elixir) lib/kernel.ex:3952: Kernel.define/4
    (elixir) expanding macro: Kernel.defmacro/2
    lib/otherdb.ex:28: OHTERDB.defname/0
    (elixir) expanding macro: Record.defrecord/2
    lib/otherdb.ex:28: OHTERDB.defname/0

I’ve seen many other examples of people using this syntax, so I must be doing something wrong.
Any help on this would be appreciated.

Showing Posts 1 to 10

easco

easco

It looks like you are trying to make your defrecord call from inside of a function like:

def  somefunction() do
  Record.defrecord :record_name...
  …
end

The error says the defrecord call must be moved out of the function, presumably to the level of the module.

rvirding

rvirding

Creator of Erlang

IIRC defrecord defines a record, it does not create an instance. Pretty much the same as -record(Name, {...}). in Erlang.

NobbZ

NobbZ

You are right, and Record.extract/2 extracts a keywordlist from a *.hrl, which can be used in Record.defrecord.

But it seems as if he were trying to extract a record from a dependency, so it should be :from_lib instead of :from.

Additionally what @easco said seems to be valid as well:

** (ArgumentError) cannot invoke defmacro/2 inside function/macro

Proof:

iex(1)> defmodule M do              
...(1)>   require Record
...(1)>   def foo() do
...(1)>     Record.defrecord(:foo, [bar: 0])
...(1)>   end
...(1)> end
  iex:1

** (ArgumentError) cannot invoke defmacro/2 inside function/macro
    (elixir) lib/kernel.ex:5150: Kernel.assert_no_function_scope/3
    (elixir) lib/kernel.ex:3906: Kernel.define/4
    (elixir) expanding macro: Kernel.defmacro/2
    iex:5: M.foo/0
    (elixir) expanding macro: Record.defrecord/2
    iex:5: M.foo/0

As you can see, the errormessage has the same shape.

Shun_di

Shun_di OP

Thanks for responses guys.
Yep, I’m a bit of an idiot.

easco is right, I had put this in a function whereas it should have been at module level. I corrected this and it was fine.

The next thing I am trying to do is populate the record that has been defined.

In Erlang I can do this by doing the following (I need them to go into a list hence the square brackets):

things = [#thing{name = “bob”, age = 30, job = “Elixir Dev”}]

I thought I could do it something like this based on research but I’m probably/most likely wrong (this is without it being a list):

thing2 = thing.new(
name = “bob”,
age = 30,
job = “Elixir Dev”)

NobbZ

NobbZ

You need to import the module that contains the defrecord.

Then you can use the generated macro which has the same name as your record. You can find examples in the documentation of Record.defrecord

rvirding

rvirding

Creator of Erlang

IIRC (again) make the argument to new a keyword list. It would become something like:

thing1 = foo(name: "bob", age: 30, job: "Elixir Dev")

Don’t forget that Erlang strings and Elixir strings are not the same.

Shun_di

Shun_di OP

Thanks again for your help guys. I think I’m starting to get the hang of Elixir now.
I put the extract line into it own module, and imported it and used the syntax in rvirding’s post above and all is working well.

I’m now creating a bigger project but I am still using the same erlang records in it.
However, the extract line will be in a separate app (app1) and I will be calling from a separate app (app2). So app1 will be a dependency in app2. However, when I try and compile I get the following error:

== Compilation error in file lib/app1/mymodule.ex ==
** (RuntimeError) error parsing file deps/mydependency/include/erlangheaderfile.hrl, got: {:error, :enonet}
(elixir) lib/record/extractor.ex:84: Record.Extractor.read_file/2

Its probably something simple that I am missing as it works if I have this in the same app/project. Any ideas what I am doing wrong?

NobbZ

NobbZ

Can you please show the line how you are extracting the record?

And how are you specifiying the dependency in your mixfile?

Shun_di

Shun_di OP

Sure no problem.

I’m using the same syntax as before with the exception of from_lib now:

Record.defrecord :record_name, Record.extract(:record_name, from_lib: “mydependency/include/header_file.hrl”)

I’m using the standard dependency git syntax in “app1”. Something like this:

{:mydependency, git "git@someurl.git, tag: “atag”, override: true}

in “app2” i’m using the same syntax but to call “app1” as a dependency:

{:app1, git "git@someurlforapp1.git, tag: “atag”, override: true}

I don’t have the :mydependency dependency in “app2”. Should I have?

I hope that helps.

NobbZ

NobbZ

So you are trying to read into a transient dependency this way? I’m not sure if this is possible. Try to add :mydependency in :app2 as well and check if it works.

If not, please try to provide some minimal project(s) at github or otherwise publicly which reproduce the problem such that we can take a deeper look at it.

— All posts loaded —

Where Next? Top

Trending in Questions Top

Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews