[erlang-questions] Drive by mention of new features without explaination

9 views
Skip to first unread message

Jarrod Roberson

unread,
Dec 7, 2009, 12:59:59 PM12/7/09
to Erlang
On the new page about NIF http://erlang.org/doc/man/erl_nif.html there
is the following:
"A better solution for a real module is to take advantage of the new
attribute on_load to automatically load the NIF library when the
module is loaded."

Where can I find an example of how to use this new attribute?

________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org

Bob Ippolito

unread,
Dec 7, 2009, 1:12:07 PM12/7/09
to Jarrod Roberson, Erlang
On Mon, Dec 7, 2009 at 9:59 AM, Jarrod Roberson <jar...@vertigrated.com> wrote:
> On the new page about NIF http://erlang.org/doc/man/erl_nif.html there
> is the following:
> "A better solution for a real module is to take advantage of the new
> attribute on_load to automatically load the NIF library when the
> module is loaded."
>
> Where can I find an example of how to use this new attribute?

http://www.erlang.org/doc/reference_manual/code_loading.html#id2278452

-bob

Jarrod Roberson

unread,
Dec 7, 2009, 2:43:51 PM12/7/09
to Erlang
> http://www.erlang.org/doc/reference_manual/code_loading.html#id2278452

thanks Bob for the link, following those instructions I got this far:

// niftest.c
#include "erl_nif.h"
static ERL_NIF_TERM hello(ErlNifEnv* env)
{
return enif_make_string(env, "Hello world!");
}
static ErlNifFunc nif_funcs[] =
{
{"hello", 0, hello}
};
ERL_NIF_INIT(niftest,nif_funcs,NULL,NULL,NULL,NULL)

========================

%% niftest.erl
-module(niftest).
-export([hello/0]).
-on_load(run_me/0).

run_me() ->
erlang:load_nif("./niftest", 0).
hello() ->
"NIF library not loaded".

========================

[jrod@null-001ff3d1c06a] [~]
make clean all
rm -f *.o *.beam niftest.so
cc -arch x86_64 -O3 -fPIC -bundle -flat_namespace -undefined suppress
-fno-common -Wall
-I/Users/jrod/Downloads/otp_src_R13B03//erts/emulator/beam/ -c -o
niftest.o niftest.c
gcc -o niftest.so niftest.o -arch x86_64 -O3 -fPIC -bundle
-flat_namespace -undefined suppress -fno-common -Wall
erlc niftest.erl
[jrod@null-001ff3d1c06a] [~]
erl
Erlang R13B03 (erts-5.7.4) [source] [64-bit] [smp:2:2] [rq:2]
[async-threads:0] [kernel-poll:false]

Eshell V5.7.4 (abort with ^G)
1> niftest:hello().
** exception error: undefined function niftest:hello/0
2>

I tried exporting the run_me/0 function as well with the same results?
If I take out the -on_load(run_me/0). and add run_me/0 to the export it works.
Any ideas what I am missing here?

Jarrod Roberson

unread,
Dec 7, 2009, 2:47:04 PM12/7/09
to Erlang
On Mon, Dec 7, 2009 at 2:43 PM, Jarrod Roberson <jar...@vertigrated.com> wrote:
>> http://www.erlang.org/doc/reference_manual/code_loading.html#id2278452
>
> thanks Bob for the link, following those instructions I got this far:
>
> // niftest.c
> #include "erl_nif.h"
> static ERL_NIF_TERM hello(ErlNifEnv* env)
> {
>    return enif_make_string(env, "Hello world!");
> }
> static ErlNifFunc nif_funcs[] =
> {
>    {"hello", 0, hello}
> };
> ERL_NIF_INIT(niftest,nif_funcs,NULL,NULL,NULL,NULL)
>
> ========================
>
> %% niftest.erl
> -module(niftest).
> -export([hello/0]).
> -on_load(run_me/0).
>
> run_me() ->
>      erlang:load_nif("./niftest", 0).
> hello() ->
>      "NIF library not loaded".
>
> ========================


I figured it out! I needed to return true/false from the run_me/0 function!

Rapsey

unread,
Dec 7, 2009, 2:47:09 PM12/7/09
to erlang-q...@erlang.org
The on_load function has to return true. Otherwise module will not be
loaded.


Sergej

Zoltan Lajos Kis

unread,
Dec 7, 2009, 2:48:57 PM12/7/09
to Jarrod Roberson, Erlang
I also overlooked this a few days ago :).

The on_load function expects 'true' to be returned, whereas
erlang:load_nif returns with 'ok' (which is definitely not 'true'). This
will result in your module being unloaded.
Solution:

run_me() ->
erlang:load_nif("./niftest", 0),
true.

Regards,
Zoltan.

Ulf Wiger

unread,
Dec 7, 2009, 3:34:43 PM12/7/09
to Zoltan Lajos Kis, Erlang
Zoltan Lajos Kis wrote:
>
> The on_load function expects 'true' to be returned, whereas
> erlang:load_nif returns with 'ok' (which is definitely not 'true'). This
> will result in your module being unloaded.
> Solution:
>
> run_me() ->
> erlang:load_nif("./niftest", 0),
> true.

Hmm...

Given that the NIF support is flagged as experimental,
could this perhaps be fixed?

BR,
Ulf W
--
Ulf Wiger
CTO, Erlang Training & Consulting Ltd
http://www.erlang-consulting.com

Zoltan Lajos Kis

unread,
Dec 7, 2009, 3:55:00 PM12/7/09
to Ulf Wiger, Erlang
Ulf Wiger wrote:
> Zoltan Lajos Kis wrote:
>>
>> The on_load function expects 'true' to be returned, whereas
>> erlang:load_nif returns with 'ok' (which is definitely not 'true').
>> This will result in your module being unloaded.
>> Solution:
>>
>> run_me() ->
>> erlang:load_nif("./niftest", 0),
>> true.
>
> Hmm...
>
> Given that the NIF support is flagged as experimental,
> could this perhaps be fixed?
>
> BR,
> Ulf W
I'd give a +1 on changing the on_load handler to expect 'ok' instead of
'true'. The documentation states that "there may be
backward-incompatible changes in the feature in future releases.", so
that should not be a problem. But there might be plans unknown to us
with on_load that makes 'true' the preferable choice. Who knows...

btw, we could use this for now:

run_me() ->
ok == erlang:load_nif("./niftest", 0).

Regards,
Zoltan.

Robert Virding

unread,
Dec 7, 2009, 5:08:56 PM12/7/09
to Zoltan Lajos Kis, Ulf Wiger, Erlang
2009/12/7 Zoltan Lajos Kis <ki...@tmit.bme.hu>

>
> I'd give a +1 on changing the on_load handler to expect 'ok' instead of
> 'true'. The documentation states that "there may be backward-incompatible
> changes in the feature in future releases.", so that should not be a
> problem. But there might be plans unknown to us with on_load that makes
> 'true' the preferable choice. Who knows...
>
> btw, we could use this for now:
>
> run_me() ->
> ok == erlang:load_nif("./niftest", 0).
>

If the on_load handler were to return 'ok' when it is successful then what
should it return on failure, 'error'? It still can't return what
erlang:load_nif does as its error returns are quite specific. And there
might actually be people who use the on_load handler for other things than
calling load_nif.

Robert

Jayson Vantuyl

unread,
Dec 7, 2009, 5:23:19 PM12/7/09
to Robert Virding, Zoltan Lajos Kis, Ulf Wiger, Erlang
> If the on_load handler were to return 'ok' when it is successful then what
> should it return on failure, 'error'? It still can't return what
> erlang:load_nif does as its error returns are quite specific. And there
> might actually be people who use the on_load handler for other things than
> calling load_nif.
Actually, why can't it return {error,Reason}? gen_server's return all manner of custom {error,_} tuples that can be handled with fairly generic code because it's really a rather complete idiom.

Why have false unload the module? It appears that there are broken semantics. As if "on_load" really is semantically closer to "should_load_and_convenient_side_effects". I'd much rather have on_load return either ok or some error that could be logged intelligently. Fitting in with load_nif is just a bonus.

Additionally, {ok,_} might have other uses in the future. true / false pretty much makes any extension to the syntax yield a completely broken idiom.

Conversely, what good does true / false do? It's rather arbitrary and certainly uninformative. At least being congruent with load_nif wouldn't be completely arbitrary.


--
Jayson Vantuyl
kag...@souja.net

Björn Gustavsson

unread,
Dec 8, 2009, 2:03:58 AM12/8/09
to Jayson Vantuyl, Robert Virding, Zoltan Lajos Kis, Ulf Wiger, Erlang
On Mon, Dec 7, 2009 at 11:23 PM, Jayson Vantuyl <kag...@souja.net> wrote:
> Why have false unload the module?  It appears that there are broken semantics.  As if "on_load" really is semantically closer to "should_load_and_convenient_side_effects".  I'd much rather have on_load return either ok or some error that could be logged intelligently.  Fitting in with load_nif is just a bonus.

It makes sense. Currently, if the on_load function returns anything
but 'true', the module will be unloaded, so it is not really a true
boolean anyway.

Therefore, I suggest the following change for R13B04:

The on_load function must return 'ok' if the function is to remain loaded.

Returning any other value (or causing an exception) will cause the
module to be unloaded.
In addition, if the return value is {error,Anything}, a message will
be written to the error_logger.


Unless someone finds any problem with this, I'll probably implement
the new semantics
within a few days.

--
Björn Gustavsson, Erlang/OTP, Ericsson AB

Sverker Eriksson

unread,
Dec 8, 2009, 5:37:39 AM12/8/09
to Erlang
Björn Gustavsson wrote:
> Therefore, I suggest the following change for R13B04:
>
> The on_load function must return 'ok' if the function is to remain loaded.
>
> Returning any other value (or causing an exception) will cause the
> module to be unloaded.
> In addition, if the return value is {error,Anything}, a message will
> be written to the error_logger.
>
>

Actually load_nif returns {error, ReasonAtom, ReasonText} where the atom
is "matchable" and the text human readable. Would it be better with
{error, {Atom,Text}} maybe?


And right now I recommend matching against 'ok' which will get you that
error tuple in the face, at least when playing in the shell:

on_load() ->
ok = load_nif("./niftest", 0),
true.

1> niftest:hello().

=ERROR REPORT==== 8-Dec-2009::11:01:37 ===
Error in process <0.35.0> with exit value:
{{badmatch,{error,load_failed,"Failed to load NIF library ./niftest:
'./niftest.so: cannot open shared object file: No such file or
directory'"}},

** exception error: undefined function niftest:hello/0
2>


/Sverker, Erlang/OTP Ericsson

Björn Gustavsson

unread,
Dec 8, 2009, 6:51:53 AM12/8/09
to Sverker Eriksson, Erlang
On Tue, Dec 8, 2009 at 11:37 AM, Sverker Eriksson
<sve...@erix.ericsson.se> wrote:
> Actually load_nif returns {error, ReasonAtom, ReasonText} where the atom is
> "matchable" and the text human readable. Would it be better with {error,
> {Atom,Text}} maybe?

Yes, that would be better.

--
Björn Gustavsson, Erlang/OTP, Ericsson AB

________________________________________________________________

Reply all
Reply to author
Forward
0 new messages