Record not found - erlang

I follow the REST API with yaws tutorial of the 'Building web application with Erlang' book.
I get the following error when starting $ yaws :
file:path_eval([".","/Users/<uername>"],".erlang"): error on line 3: 3: evaluation failed with reason error:{undefined_record,airport} and stacktrace [{erl_eval,exprs,2,[]}]
.erlang file:
application:start(mnesia).
mnesia:create_table(airport,[{attributes, record_info(fields, airport)}, {index, [country]}]).
rest.erl file can be found here.
How can I define a record? I tried to add rd(airport, {code, city, country, name}). without success.

Record 'airport' is defined in the module rest, and all functions in the 'rest' know about record 'airport'. But when you start your application, erlang executes .erlang file, which has nothing to do with the module rest. So, erlang just has no idea what is the record airport and where to find it.
Easiest workaround I believe - is to define some function (for instance 'init') in the module rest, this function must contain all that you have now in .erlang file, export it, and in the .erlang file just invoke rest:init().

Related

Why does Eunit not require test functions to be exported?

I'm going through the EUnit chapter in Learn You Some Erlang and one thing I am noticing from all the code samples is the test functions are never declared in -export() clauses.
Why is EUnit able to pick these test functions up?
From the documentation:
The simplest way to use EUnit in an Erlang module is to add the following line at the beginning of the module (after the -module declaration, but before any function definitions):
-include_lib("eunit/include/eunit.hrl").
This will have the following effect:
Creates an exported function test() (unless testing is turned off, and the module does not already contain a test() function), that can be used to run all the unit tests defined in the module
Causes all functions whose names match ..._test() or ..._test_() to be automatically exported from the module (unless testing is turned off, or the EUNIT_NOAUTO macro is defined)
Glad I found this question because it gives me a meaningful way to procrastinate and I was wondering how functions get created and exported dynamically.
Started by looking at the latest commit affecting EUnit in the Erlang/OTP Github repo, which is 4273cbd. (The only reason for this was to find a relatively stable anchor instead of git branches.)
0. Include EUnit's header file
According EUnit's User's Guide, the first step is to -include_lib("eunit/include/eunit.hrl"). in the tested module, so I assume this is where the magic happens.
1. otp/lib/eunit/include/eunit.hrl (lines 79 - 91)
%% Parse transforms for automatic exporting/stripping of test functions.
%% (Note that although automatic stripping is convenient, it will make
%% the code dependent on this header file and the eunit_striptests
%% module for compilation, even when testing is switched off! Using
%% -ifdef(EUNIT) around all test code makes the program more portable.)
-ifndef(EUNIT_NOAUTO).
-ifndef(NOTEST).
-compile({parse_transform, eunit_autoexport}).
-else.
-compile({parse_transform, eunit_striptests}).
-endif.
-endif.
1.1 What does -compile({parse_transform, eunit_autoexport}). mean?
From the Erlang Reference Manual's Module chapter (Pre-Defined Module Attributes):
-compile(Options).
Compiler options. Options is a single option or a list of options. This attribute is added to the option list when
compiling the module. See the compile(3) manual page in Compiler.
On to compile(3):
{parse_transform,Module}
Causes the parse transformation function
Module:parse_transform/2 to be applied to the parsed code before the
code is checked for errors.
From the erl_id_trans module:
This module performs an identity parse transformation of Erlang code.
It is included as an example for users who wants to write their own
parse transformers. If option {parse_transform,Module} is passed to
the compiler, a user-written function parse_transform/2 is called by
the compiler before the code is checked for errors.
Basically, if module M includes the {parse_transform, Module} compile option, then all of M's functions and attributes can be iterated through using your implementation of Module:parse_transform/2. Its first argument is Forms, which is M's module declaration described in Erlang's abstract format (described in Erlang Run-Time System Application (ERTS) User's Guide.
2. otp/lib/eunit/src/eunit_autoexport.erl
This module only exports parse_transfrom/2 to satisfy {parse_transform, Module} compile option and its first order of business is to figure out what are the configured suffixes for test case functions and generators. If not set manually, using _test and _test_ respectively (via lib/eunit/src/eunit_internal.hrl).
It then scans all the functions and attributes of your module using eunit_autoexport:form/5, and builds a list of to be exported functions where the suffixes above match (plus the original functions. I may be wrong on this one...).
Finally, eunit_autoexport:rewrite/2 builds a module declaration from the original Forms (given to eunit_autoexport:parse_transform/2 as the first argument) and the list of functions to be exported (that was supplied by form/5 above). On line 82 it injects the test/0 function mentioned in the EUnit documentation.

is there a good way to find function define in header file in ace framework

As a ace framework newer, i always encounter some problem when using this framework.
I copy some example code from website and execute it in linux. however some error throw out because of no include correspond header file. for exmaple some error like this: error: ‘sleep’ is not a member of ‘ACE_OS’.
so how can i found this function define in which header file
Most easiest is just to do a "grep sleep $ACE_ROOT/ace/OS*.h", that tells you the file where this method is defined. Other option is to use the most recent doxygen tree at http://doxygen.theaceorb.nl/libace-doc/index.html

Erlang: using include from the console?

The include directive is usually used for a .hrl file at the top of an .erl file.
But, I would like to use include from the Erlang console directly.
I am trying to use some functions in a module. I have compiled the erl file from the console. But, the functions I want to use do not work without access to the hrl file.
Any suggestions?
"But, the functions I want to use do not work without access to the hrl file."
This can't be true, but from this I'll take a shot at guessing that you want access to records in the hrl file that you don't (normally) have in the shell.
If you do rr(MODULE) you will load all records defined in MODULE(including those defined in an include file included by MODULE).
Then you can do everything you need to from the shell.
(Another thing you may possibly want for testing is to add the line -compile(export_all) to your erl file. Ugly, but good sometimes for testing.)
Have you tried the compile:file option? You can pass a list of modules to be included thus:
compile:file("myfile.erl", [{i, "/path/1/"}, {i, "/path/2/"}])
It's worth nothing that jsonerl.hrl doesn't contain any functions. It contains macros. As far as I know, macros are a compile-time-only construct in Erlang.
The easiest way to make them available would be to create a .erl file yourself that actually declares functions that are implemented in terms of the macro. Maybe something like this:
-module(jsonerl_helpers).
-include("jsonerl.hrl").
record_to_struct_f(RecordName, Record) ->
?record_to_struct(RecordName, Record).
... which, after you compile, you could call as:
jsonerl_helpers:record_to_struct_f(RecordName, Record)
I don't know why the author chose to implement those as macros; it seems odd, but I'm sure he had his reasons.

Records in Erl (Erlang question)

Is there a way to use records directly in erl? No matter what I try, it always says it canno find the record. I am trying to do mnesia transactions and I cannot go too far without my records. Any help is greatly appreciated - thank you!
Yes, use help() and find these commands in the shell.
rd(R,D) -- define a record
rf() -- remove all record information
rf(R) -- remove record information about R
rl() -- display all record information
rl(R) -- display record information about R
rp(Term) -- display Term using the shell's record information
rr(File) -- read record information from File (wildcards allowed)
rr(F,R) -- read selected record information from file(s)
rr(F,R,O) -- read selected record information with options
These are a clever hack in the shell, they allow you to load record definitions used in modules when they were compiled. Use the rr command to load it from your module.
Remember that these are only available for the interactive shell to use.
How do you mean? In the shell, then it is as Christian wrote. If you mean in a module then you still have to define records before you can use them. See the erlang docs, online at http://erlang.org/doc/, for a description on how to do this. They are only a compile time construction, so they don't exist as such.

how to include yaws file inside the yaws file

i have one yaws file(let say a.yaws) inside that I have a lot of function which i m using again and again .so i have decided to put those common function inside the other yaws file (let say common.yaws) and include this yaws to a.yaws.
so what is the correct syntax for this.
i m using it but seems not including the file
-include("common.yaws").
thanx in adavance.
If the functions you have in your common file are basically erlang functions you can simply put those functions in an erlang module and simply call the function directly. As an example:
(in one.yaws)
<erl>
out(Arg) ->
mycommonstuff:doIt(Arg).
</erl>
where mycommonstuff.erl contains the exported function doIt.
If your common.yaws file actually contains yaws type features you could use the server side include feature of yaws - that is explained here:
http://yaws.hyber.org/ssi.yaws

Resources