Ilyes512

Ilyes512

Can't use (Erlang) Records that start with an uppercased letter

So I am using Erlsom to parse a XML file that also has a matching XSD file. Erlsome includes an option to generate records (.erl file) based on the model of the XSD (erlsom:write_xsd_hrl_file).

This auto-generated .erl file includes records that start with an uppercased letter. For example:

-record('Pip3A4PurchaseOrderRequestType', {anyAttribs :: anyAttribs(),
	fromRole :: roleType(),
	'Authentication' :: 'AuthenticationType'(),
	'GlobalDocumentFunctionCode' :: string(),
	'PurchaseOrder' :: 'PurchaseOrderType'(),
	thisDocumentGenerationDateTime :: 'DateTimeType'(),
	thisDocumentIdentifier :: 'ProprietaryDocumentIdentifierType'(),
	toRole :: roleType()}).

So when I use a record in my elixir module (like the one below) I can’t use it.

Record.defrecord :Pip3A4PurchaseOrderRequestType, Record.extract(:Pip3A4PurchaseOrderRequestType, from: @hrl)
Erlang/OTP 19 [erts-8.3] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Interactive Elixir (1.4.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> require Ot.Poc
Ot.Poc
iex(2)> record = Ot.Poc.Pip3A4PurchaseOrderRequestType()
** (SyntaxError) iex:2: syntax error before: '('

iex(2)> record = Ot.Poc.pip3A4PurchaseOrderRequestType()
** (UndefinedFunctionError) function Ot.Poc.pip3A4PurchaseOrderRequestType/0 is undefined or private. Did you mean one of:

      * Pip3A4PurchaseOrderRequestType/0
      * Pip3A4PurchaseOrderRequestType/1
      * Pip3A4PurchaseOrderRequestType/2

    (ot) Ot.Poc.pip3A4PurchaseOrderRequestType()

I thought I could fix this by defining the record as fallowed:

  #                 v--- lower cased p                              v--- Upper cased p
  Record.defrecord :pip3A4PurchaseOrderRequestType, Record.extract(:Pip3A4PurchaseOrderRequestType, from: @hrl)

Now I can call Ot.Poc.pip3A4PurchaseOrderRequestType(), but when I try to pass the record data it fails because the record links to other records that are starting with upper cased names, but first it fails because it can’t match it self with the data:

** (ArgumentError) expected argument to be a literal atom, literal keyword or a :pip3A4PurchaseOrderRequestType record, got runtime: {:Pip3A4PurchaseOrderRequestType, [], {:roleType, [],

So at this point I tried everything I could think off without success. What can I do without having to adjust the .erl file manually (392 LoC)?

Marked As Solved

Ilyes512

Ilyes512

I got it working by doing the following:

defmodule Ot.Poc do
    for name <- Record.extract_all(from: @hrl) |> Keyword.keys do 
      Record.defrecord :"#{name |> to_string }", Record.extract(name, from: @hrl)
   end
  # ...
end

edit:
BTW thanks @peerreynders! And the rest to of course! (quite surprised how fast I had my first reaction here :smiley:)

Also Liked

peerreynders

peerreynders

What about this approach:

require Record
defmodule Person do
  Record.defrecord :"Person", [:name, age: 25]
end

.

iex> require Person
iex> default = Person."Person"
{:Person, nil, 25}
iex> name_and_age = Person."Person"(name: "Bob Jones", age: 55)
{:Person, "Bob Jones", 55}
iex>

Example from Working with Erlang Records in Elixir

michalmuskala

michalmuskala

Record.defrecord can accept an additional argument to differentiate the macro name from the record tag. And that’s probably what you want - lowercase macro with an uppercase tag.

Where Next?

Popular in Questions Top

WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
yawaramin
In the Dialyzer docs ( dialyzer — OTP 29.0.2 (dialyzer 6.0.1) ), there is a way to turn off a specific warning for a function: -dialyzer...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New

Other popular topics Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31194 112
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

We're in Beta

About us Mission Statement