How to generate document for Ejabberd custom modules? - erlang

I have created some custom modules I need to create documentation for all my custom module So any help?

You can use edoc - http://erlang.org/doc/apps/edoc/chapter.html. Eg:
test_edoc.erl
-module(test_edoc).
-export([run/1]).
%% -------------------------------------------------------------------
%% #doc
%% Some description
%% #end
%% -------------------------------------------------------------------
-spec run(N :: integer()) -> Result :: integer() | error.
run(N) when is_integer(N) -> N + 1;
run(_) -> error.
Then in Erlang shell:
1> edoc:files(["test_edoc.erl"], [{dir, doc}]).
ok
Then in current folder where you run edoc:files/2 should be generated the doc folder, so, go to the doc folder and open in browser test_edoc.html

Related

Can't compile a new module in ejabberd

I am trying to compile a new module for ejabberd in erlang.I am following this tutorial:http://jasonrowe.com/2011/12/30/ejabberd-offline-messages
I am trying to compile this code:
%% name of module must match file name
-module(mod_http_offline).
-author("Earl The Squirrel").
%% Every ejabberd module implements the gen_mod behavior
%% The gen_mod behavior requires two functions: start/2 and stop/1
-behaviour(gen_mod).
%% public methods for this module
-export([start/2, stop/1, create_message/3]).
%% included for writing to ejabberd log file
-include("ejabberd.hrl").
%% ejabberd functions for JID manipulation called jlib.
-include("jlib.hrl").
start(_Host, _Opt) ->
post_offline_message("testFrom", "testTo", "testBody"),
?INFO_MSG("mod_http_offline loading", []),
ejabberd_hooks:add(offline_message_hook, _Host, ?MODULE, create_message, 50).
stop (_Host) ->
?INFO_MSG("stopping mod_http_offline", []),
ejabberd_hooks:delete(offline_message_hook, _Host, ?MODULE, create_message, 50).
create_message(_From, _To, Packet) ->
Type = xml:get_tag_attr_s("type", Packet),
FromS = xml:get_tag_attr_s("from", Packet),
ToS = xml:get_tag_attr_s("to", Packet),
Body = xml:get_path_s(Packet, [{elem, "body"}, cdata]),
if (Type == "chat") ->
post_offline_message(FromS, ToS, Body)
end.
post_offline_message(From, To, Body) ->
?INFO_MSG("Posting From ~p To ~p Body ~p~n",[From, To, Body]),
?INFO_MSG("post request sent (not really yet)", []).
I have added jlib.hrl,ejabberd.hrl to my folder.But when I try to compile this code I am getting following errors:
jlib.hrl:22: can't find include lib "p1_xml/include/xml.hrl"
mod_http_offline.erl:21: undefined macro 'INFO_MSG/2'
mod_http_offline.erl:27: undefined macro 'INFO_MSG/2'
mod_http_offline.erl:44: undefined macro 'INFO_MSG/2'
jlib.hrl:426: record xmlel undefined
jlib.hrl:466: type xmlel() undefined
mod_http_offline.erl:11: function start/2 undefined
mod_http_offline.erl:11: function stop/1 undefined
mod_http_offline.erl:38: function post_offline_message/3 undefined
mod_http_offline.erl:8: Warning: behaviour gen_mod undefined
How can I resolve this ?
My Ejabberd version:2.1.11
The jlib.hrl file in ejabberd repository contains -include("ns.hrl"). (line 21) and -include_lib("p1_xml/include/xml.hrl"). line 22. The include_lib means that it will search the file in library path. You could modify this and add the necessary files in your directory (maybe a simple solution to test?) but I think that the clean way is to add tour file to the ejabberd application and use rebar to compile it.

External function call Erlang

I'm trying to call a function (from an external module) in erlang. both beam files are located in the same directory.
-module(drop2).
-export([fall_velocity/1]).
fall_velocity(Distance) -> math:sqrt(2 * 9.8 * Distance).
Then I'm calling
-module(ask).
-export([term/0]).
term() ->
Input = io:read("Enter {x,distance} ? >>"),
Term = element(2,Input),
drop2:fall_velocity(Term).
it gives the following error.I tested individual modules for errors. it is compiling with out any errors or warning.
Eshell V5.10.2 (abort with ^G)
1> ask:term().
Enter {x,distance} ? >>{test,10}.
** exception error: an error occurred when evaluating an arithmetic expression
in function drop2:fall_velocity/1 (drop2.erl, line 3)
Not sure why it is throwing arithmetic expression error .
You could read the documentation to figure out that the result is {ok, Term}. You could try the io:read/1 function in the console, then you'd see following:
1> io:read("Enter > ").
Enter > {test, 42}.
{ok,{test,42}}
2>
That means that you need to deconstruct the result of io:read/1 differently, for example like this:
-module(ask).
-export([term/0]).
term() ->
{ok, {_, Distance}} = io:read("Enter {x, distance} > "),
drop2:fall_velocity(Distance).

Having Dialyzer support Custom Behaviours

I am using Dialyzer with a few custom behaviors, the problem is that when I do that, Dialyzer gives me this error:
src/max.erl:3: Callback info about the gen_strategy behaviour is not available
One thing I can't figure out is how to create that callback info. I would like to add this information to my behaviour, so I can get that much more testing out of Dialyzer.
Starting with R15B, The Erlang/OTP compiler was upgraded so that it now handles a new module attribute, named -callback.
Example:
-callback init(Args :: term()) ->
{ok, State :: term()} | {ok, State :: term(), timeout() | hibernate} |
{stop, Reason :: term()} | ignore.
More about that here and here

Erlang Dependency Not Started Error

I am trying to run a start script but I end up with the following error.
{"init terminating in do_boot",{{case_clause,{error,{not_started,ranch}}},[{egs,ensure_started,1,[{file,"src/egs.erl"},{line,84}]},{egs,start,0,[{file,"src/egs.erl"},{line,49}]},{init,start_it,1,[]},{init,start_em,1,[]}]}}
I can compile the entire folder with multiple dependencies and this is the only one with an error. I use 'make' to compile and it is supposed to be 'make run' to run but that isn't working. Is that why I am getting this error? Any ideas on how to fix it would be greatly appreciated.
The file where I get the error from is below.
-module(egs).
-export([start/0, stop/0, global/1, warp/4, warp/5]). %% API.
%% Player and account-related types.
-type gid() :: 0..16#ffffffff.
-type lid() :: 0..1023 | 16#ffff.
-type character_slot() :: 0..3.
-export_type([gid/0, lid/0, character_slot/0]).
%% Location related types.
-type uniid() :: 21 | 26..254 | 16#ffffffff.
-type questid() :: 0..16#ffffffff. %% #todo What's the real max?
-type zoneid() :: 0..16#ffff. %% #todo What's the real max?
-type mapid() :: 0..9999.
-type entryid() :: 0..16#ffff. %% #todo What's the real max?
-type area() :: {questid(), zoneid(), mapid()}. %% #todo Probably remove later.
-type position() :: {X::float(), Y::float(), Z::float(), Dir::float()}.
-export_type([uniid/0, questid/0, zoneid/0, mapid/0, entryid/0,
area/0, position/0]).
%% API.
-spec start() -> ok.
start() ->
ensure_started(crypto),
ensure_started(public_key),
ensure_started(ssl),
ensure_started(cowboy),
ensure_started(ranch),
application:start(egs).
-spec stop() -> ok.
stop() ->
Res = application:stop(egs),
ok = application:stop(cowboy),
ok = application:stop(ranch),
ok = application:stop(ssl),
ok = application:stop(public_key),
ok = application:stop(crypto),
Res.
%% #doc Send a global message.
-spec global(string()) -> ok.
global(Message) when length(Message) > 511 ->
io:format("global: message too long~n");
global(Message) ->
egs_users:broadcast_all({egs, notice, top, Message}).
%% #doc Warp all players to a new map.
-spec warp(questid(), zoneid(), mapid(), entryid()) -> ok.
warp(QuestID, ZoneID, MapID, EntryID) ->
egs_users:broadcast_all({egs, warp, QuestID, ZoneID, MapID, EntryID}).
%% #doc Warp one player to a new map.
-spec warp(gid(), questid(), zoneid(), mapid(), entryid()) -> ok.
warp(GID, QuestID, ZoneID, MapID, EntryID) ->
egs_users:broadcast({egs, warp, QuestID, ZoneID, MapID, EntryID}, [GID]).
%% Internal.
-spec ensure_started(module()) -> ok.
ensure_started(App) ->
case application:start(App) of
ok -> ok;
{error, {already_started, App}} -> ok
end.
The order of application startup is important. In particular, cowboy depends on ranch and crypto. Also, public_key depends on crypto and must be started before ssl. The correct start order is:
ok = application:start(crypto),
ok = application:start(public_key),
ok = application:start(ssl),
ok = application:start(ranch),
ok = application:start(cowboy),
ok = application:start(egs).
For applications built with Rebar, the startup dependencies are listed in [app]/src/[app].app.src. See the LYSE chapter.
The reason it didn't work out of the box is probably that EGS depends on Cowboy's master branch, which quite recently introduced Ranch as a dependency.

Erlang rr() returns missing_chunk

Newbie question on erlang using by wings 3d shell (windows 7 pro, wings 3d 1.4.1). When I write command to read records definitons:
rr(wings).
I always get an error:
{error,beam_lib,
{missing_chunk,'d:/temp/erlang/lib/wings/ebin/wings.beam',"Abst"}}
What I am doing wrong?
rr/1 "reads record definitions from a module's BEAM file. If there are no record definitions in the BEAM file, the source file is located and read instead."
My guess is that the abstract form hasn't been included in the .BEAM file and that in your installation the source files are not available.
UPDATE: Digging into the shell:read_file_records/2 function, I've found the following:
read_file_records(File, Opts) ->
case filename:extension(File) of
".beam" ->
case beam_lib:chunks(File, [abstract_code,"CInf"]) of
{ok,{_Mod,[{abstract_code,{Version,Forms}},{"CInf",CB}]}} ->
case record_attrs(Forms) of
[] when Version =:= raw_abstract_v1 ->
[];
[] ->
%% If the version is raw_X, then this test
%% is unnecessary.
try_source(File, CB);
Records ->
Records
end;
{ok,{_Mod,[{abstract_code,no_abstract_code},{"CInf",CB}]}} ->
try_source(File, CB);
Error ->
%% Could be that the "Abst" chunk is missing (pre R6).
Error
end;
_ ->
parse_file(File, Opts)
end.
It looks like, if the "Abst" chunk is missing, it doesn't even try to read the source code. What does beam_lib:chunks(File, [abstract_code,"CInf"]) return for you? Which Erlang version are you running?
I am using:
Erlang R14B01 (erts-5.8.2) [rq:1] [async-threads:0]
Eshell V5.8.2 (abort with ^G)
Calling this works fine:
rr("d:/temp/erlang/src/wings.hrl").
Calling:
beam_lib:chunks("wings", [abstract_code,"CInf"]).
returns:
{error,beam_lib,{file_error,"wings.beam",enoent}}
rr/1 requires the actual file name or the relative PATH to the file name. Like this:
rr("wings.hrl").
OR
rr("./apps/MYAPP-1.0/include/my_include_file.hrl").
OR
rr("./src/wings.erl").
In other words, pass it the actual relative PATH from your pwd() to the file which contains the definitions.

Resources