The previous tutorial used some features that have changed since then.
You can start asking any questions in the efene mailing list, just send a mail to efene@librelist.com to subscribe.
you will need erlang and git installed in your machine, a C compiler and build tools like make.
in a debian based operating system this can be achieved by running:
sudo apt-get install erlang git-core build-essential
git clone http://github.com/marianoguerra/efene.git
to make our life easier set the FNPATH environment variable to the path where efene is installed.
to make your life easier I recommed to add the export FNPATH line in your .bashrc file like this:
export FNPATH=~/dev/efene
in my case efene is in ~/dev/efene, change that path to the directory where you downloaded efene.
you should also add the path to the efene/bin directory in your PATH environment variable to be able to run fnc from any place, add this at the bottom of your .basrc after the FNPATH declaration:
export PATH=$PATH:$FNPATH/bin
cd efene
export FNPATH=$(pwd)
sh build.sh
now that you have efene installed and configured test if by running:
fnc -s
you should get an interactive shell, test it with some calculations:
>>> 1 + 2
3
>>> 23 * 43
989
press ctrl + D to quit the interactive shell.
we will start with the classic hello world but with a little twist, it will be a full fledged we application
create a file called helloweb.fn in your text editor and type
@public
@get("/") -> html
index = fn (_Req) {
ok => "hello world!"
}
@public
@get("/<string>/?") -> html
index_name = fn (_Req, Name) {
ok => ["hello ", Name, "!"]
}
@public
run = fn () {
rest.start($module)
}
let’s dissect the code, the first line:
@public
defines that the function declaration that follows will be public, that means that the function will be accessible outside of this module.
the next line:
@get("/") -> html
is used by the rest module to expose that function to the web, it says that whenever a HTTP GET request comes asking for the “/” resource it will call this function, the -> html part indicates that this function will return HTML.
then whe have the function definition by itself, in this case the definition:
index = fn (_Req) {
ok => "hello world!"
}
creates a function called index that receives one parameter called _Req, the underscore at the beginning of the name is to indicate to the compiler that we know we don’t use the Req parameter so the compiler doesn’t complain about it.
the Req parameter is passed as first argument to all the functions exposed by the rest module, so we have to receive it anyway.
then we have the body of the function:
ok => "hello world!"
in this case we return the expression that indicates that everything went ok and the body of the response should be “hello world!”.
later we will learn how to use other responses other than ok to indicate some error conditions.
the next function definition is almost the same but with a little modification:
@public
@get("/<string>/?") -> html
index_name = fn (_Req, Name) {
ok => ["hello ", Name, "!"]
}
the @public part was already described, the next line:
@get("/<string>/?") -> html
has one change, instead of a simple “/” we have now “/<string>/?”, this expression says “whenever a HTTP GET request comes asking for a resource that starts with “/” and follows with a string and optionally ends with “/” call this function.
the “<string>” part is a place holder for any string that may come there, we will use that string to do a proper response.
the “/?” part is a regular expression, the ? after the / indicates that the / is optional.
then we have the function definition:
index_name = fn (_Req, Name) {
where we declare a function called index_name that receives the Req argument and another one called Name, this argument is the value that will be in the “<string>” place holder.
with this we can capture parts of the request URL and use it in the function, in this case we will use it to return a different message depending on the value of Name:
ok => ["hello ", Name, "!"]
in this case instead of returning a string, we return a list of strings, this is ok if we are building the string with different parts and we want to avoid the cost of joining all the parts by ourselves, the libraries will take care of that for us.
the final function:
@public
run = fn () {
rest.start($module)
}
declares a public function called run that receives no parameters and calls the start function of the rest module passing a funny parameter, called $module.
the $module variable is a meta variable that is replaced at compile time with the name of the module where it exists.
this is useful to avoid errors if we rename a module and we have in the module the name of it hard coded, we could’ve replaced $module with helloweb but if we copy this code to other module or rename the module then the example would break.
what rest.start does is to start a web server and expose our functions, let’s try that, first compiling our file:
fnc helloweb.fn
and then starting the server:
fnc -s
>>> helloweb.run()
{ok, <0.30.0>}
now open a web browser and go to http://localhost:8000/
you should see a “hello world!” message, you can also visit http://localhost:8000/efene
now “hello efene!” should appear, change efene for any word and see it change.