Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit a4e794d
Showing
70 changed files
with
15,859 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,10 @@ | |||
*~ | |||
*.tmp | |||
\#* | |||
erl_parse.erl | |||
.eunit/* | |||
deps/* | |||
ebin | |||
priv/* | |||
*.o | |||
*.beam |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,76 @@ | |||
.SUFFIXES: .erl .beam .yrl | |||
|
|||
MODS := $(wildcard *.erl) | |||
YRL := $(wildcard *.yrl) | |||
CHAPS := $(wildcard *.chap) | |||
BOOKS := $(wildcard *.book) | |||
LOGS := $(wildcard *.log) | |||
|
|||
CWD := $(shell pwd) | |||
|
|||
../ebin/%.beam: %.erl | |||
## erlc +warn_missing_spec -o ../ebin -W $< | |||
## grep --silent --invert-match "_test" | |||
erlc -o ../ebin -W $< | |||
|
|||
../ebin/%.beam: ../tmp/%.erl | |||
erlc -o ../ebin -W $< | |||
|
|||
../doc/%.html: %.chap | |||
@erl -noshell -pa ../ebin -s elib1_docmaker batch $< -s init stop | |||
|
|||
../doc/%.html: %.log | |||
@erl -noshell -pa ../ebin -s elib1_chunks batch $< -s init stop | |||
|
|||
../doc/%.html: %.erl | |||
./mkdoc $< | |||
|
|||
../tmp/%.erl: %.yrl | |||
erlc -o ../tmp -W $< | |||
|
|||
../../pdf/%.pdf: %.chap | |||
erl -s elib1_doc batch $< | |||
fop -xml ../tmp/$*.xml -xsl chap2pdf.xsl -pdf ../../pdf/$*.pdf | |||
|
|||
# ../../html/%.html: %.chap | |||
# erl -s elib1_doc batch $< | |||
# fop -xml ../tmp/$*.xml -xsl chap2html.xsl -txt ../../html/$*.html | |||
|
|||
all: yecc beam html #chapHTML | |||
|
|||
test: | |||
dialyzer -Wno_return --src -c "." | |||
|
|||
utest: beam | |||
erl -noshell -eval "eunit:test(elib1_misc, [verbose])" -s init stop | |||
|
|||
edoc: | |||
erl -noshell -eval "edoc:application(lib, \".\", [{dir,\"../doc\"}])" \ | |||
-s init stop | |||
|
|||
html: ${MODS:%.erl=../doc/%.html} | |||
|
|||
beam: ${MODS:%.erl=../ebin/%.beam} | |||
|
|||
yecc: ${YRL:%.yrl=../tmp/%.erl} ${YRL:%.yrl=../ebin/%.beam} | |||
|
|||
chapPDF: ${CHAPS:%.chap=../../pdf/%.pdf} | |||
|
|||
# chapHTML: ${CHAPS:%.chap=../../html/%.html} | |||
|
|||
books: ${BOOKS:%.book=../doc/%.html} | |||
|
|||
logs: ${LOGS:%.log=../doc/%.html} | |||
|
|||
clean: | |||
rm ../ebin/*.beam | |||
rm -rf *.aux *.beam | |||
rm -rf *.log *.tmp erl_crash.dump | |||
|
|||
veryclean: | |||
rm ../bin/* ../doc/* ../tmp/* | |||
|
|||
|
|||
|
|||
|
|||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,177 @@ | |||
Best practice for writing documenting and testing code | |||
|
|||
I'd like to try and define "best practice" for writing documenting and | |||
testing Erlang code. I want to use: | |||
|
|||
- only the tools supplied in the OTP release | |||
|
|||
So I use: | |||
|
|||
- eunit for unit testing | |||
- the dialyzer for checking my code | |||
- edoc for documenting things | |||
- type specifications for specifying types | |||
|
|||
These tools do not completely "play together" in a satisfactory manner, | |||
so I'd like to define what I thing is "best practice" and hope that by doing | |||
so the tools will converge. | |||
|
|||
Let's suppose I want to define the good 'ol factorial. Here's a module | |||
called elib1_best.erl. I've written it in such a way that it can be | |||
processed by erlc,eunit,edoc and the dialyzer - read the footnotes | |||
in brackets for an explanation. | |||
|
|||
-module(elib1_best). %% [1] | |||
|
|||
%% elib1_best: Best practice template for library modules [2] | |||
%% Time-stamp: <2009-12-02 09:43:12 ejoearm> [3] | |||
|
|||
%%---------------------------------------------------------------------- | |||
%% Copyright (c) 2009 Joe Armstrong <erlang@gmail.com> [4] | |||
%% Copyright (c) 2009 Whoomph Software AB | |||
%% | |||
%% Permission is hereby granted, free of charge, to any person | |||
%% obtaining a copy of this software and associated documentation | |||
%% files (the "Software"), to deal in the Software without | |||
%% restriction, including without limitation the rights to use, copy, | |||
%% modify, merge, publish, distribute, sublicense, and/or sell copies | |||
%% of the Software, and to permit persons to whom the Software is | |||
%% furnished to do so, subject to the following conditions: | |||
%% | |||
%% The above copyright notice and this permission notice shall be | |||
%% included in all copies or substantial portions of the Software. | |||
%% | |||
%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
%% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |||
%% BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |||
%% ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
%% CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
%% SOFTWARE. | |||
%%----------------------------------------------------------------------- | |||
|
|||
-include_lib("eunit/include/eunit.hrl"). %% [5] | |||
|
|||
-export([fac/1]). %% [6] | |||
|
|||
|
|||
%% @doc fac(N) computes factorial(N) using a fast | |||
%% iterative algorithm. [7] | |||
|
|||
-spec fac(integer()) -> integer(). [8] | |||
|
|||
fac(N) when is_integer(N), N >= 0 -> fac1(N, 1). | |||
|
|||
fac1(0, K) -> K; | |||
fac1(N, K) -> fac1(N-1, K*N). | |||
|
|||
fac_test() -> %% [9] | |||
6 = fac(3), | |||
24 = fac(4). | |||
|
|||
%% Notes: | |||
%% [1] - module on line 1 | |||
%% [2] - module comment | |||
%% [3] - Time stamp auto generated by emacs. | |||
%% Must be near start of file | |||
%% [4] - Copyright (I always forget this, but adding a | |||
%% copyright reduces the pain later | |||
%% [5] - Needed for eunit | |||
%% [6] - use export and NOT compile(export_all) | |||
%% [7] - @doc comes first | |||
%% [8] - -spec comes immediately *before* the function | |||
%% [9] - test cases come immediately after the function | |||
|
|||
%% end of module | |||
... | |||
|
|||
Now let's see what happens: | |||
|
|||
1) Compiling | |||
|
|||
erlc +warn_missing_spec -o ../ebin -W elib1_best.erl | |||
|
|||
./elib1_best.erl:0: Warning: missing specification for function test/0 | |||
./elib1_best.erl:44: Warning: missing specification for function fac_test/0 | |||
|
|||
Best practice is to support type specifications for all exported | |||
functions. But eunit magically adds a function test/0 and I really | |||
don't want to have to add manual exports and type specs for | |||
fac_test/0. | |||
|
|||
[A fix is needed to erlc here, OR eunit can add type specs, | |||
I think the latter is better - erlc should not need to know about eunit] | |||
|
|||
2) Dialyzing | |||
|
|||
dialyzer --src elib1_best.erl | |||
Checking whether the PLT /home/ejoearm/.dialyzer_plt is up-to-date... yes | |||
Proceeding with analysis... | |||
Unknown functions: | |||
eunit:test/1 | |||
done in 0m0.32s | |||
done (passed successfully) | |||
|
|||
This is ok - I could add eunit to my plt if I wanted ... | |||
the dialyzer warns for missing functions so I don't need to run | |||
xref | |||
|
|||
3) Documentation | |||
|
|||
I'll run edoc on everything in the current directory putting the | |||
results in ../doc | |||
|
|||
> erl -noshell -eval "edoc:application(lib, \".\", [{dir,\"../doc\"}])" \ | |||
-s init stop | |||
|
|||
This works fine and ../doc/elib1_best.html has the documentation | |||
but now edoc has not found my nice -spec declaration and thinks that | |||
fac has type: fac(N) -> any() | |||
|
|||
Why: because edoc and erlc don't use the same type parser. | |||
|
|||
Current best practice is to use -spec (in code) and | |||
not @spec (in edoc comments) | |||
|
|||
[A fix is needed here to edoc, to understand -spec's] | |||
|
|||
4) Testing | |||
|
|||
1> eunit:test(elib1_best, [verbose]). | |||
======================== EUnit ======================== | |||
elib1_best: fac_test (module 'elib1_best')...ok | |||
======================================================= | |||
Test passed. | |||
ok | |||
|
|||
Great ... | |||
|
|||
Now for questions. | |||
|
|||
1) Does this represent best practice? Is this the best way to | |||
write code? - can anybody improve on this? | |||
|
|||
[And yes I know about quickcheck, but I'm only concerned | |||
with SW in the OTP release] | |||
|
|||
2) If I write like this can I assume that one day edoc | |||
and eunit and erlc will converge so that I get correctly displayed | |||
types in edoc and no warnings in erlc etc? | |||
|
|||
3) Does anything else have to be fixed? | |||
|
|||
4) Improvements.. | |||
|
|||
I can think of one. I have some code to convert .erl to | |||
.html with correctly colored code and hyperlinks etc. | |||
So I can "surf" the code. It would be nice to have hooks | |||
into edoc so I can call this code | |||
|
|||
That's all for now ... | |||
|
|||
/Joe | |||
|
|||
|
|||
|
|||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,35 @@ | |||
= An Erlang Library | |||
|
|||
This book describes an Erlang library called ''elib1''. | |||
|
|||
== Todo (formatting program) | |||
|
|||
<ul> | |||
+ Add a diagram language (inline svg) | |||
+ ~~Make the Book version~~ | |||
+ ~~Make compact lists, so I can leave out the blank line in paragraphs like | |||
this~~ | |||
+ ~~add processing of ''footnotes''~~ | |||
+ Make commands for /bin | |||
+ check that all list entries do not end with a dot. | |||
+ Check that all list entries start with a big letter. | |||
+ punctuation check. | |||
+ ~~add "typographic quotes."~~ | |||
+ Nice to make paragraphs "clickable-editable" in the browser. | |||
+ Add some nive paragraph hover effect that colors paras as we move over them. Makes text easier to read. | |||
</ul> | |||
|
|||
== To do (programs) | |||
|
|||
<ul> | |||
+ mysql full text searching and metadata | |||
+ go through all old library adding good stuff (example topological sort) | |||
+ javascript slide show from wiki markup | |||
+ move over to GIT | |||
+ xref | |||
</ul> | |||
|
|||
<include chapter="design" /> | |||
<include chapter="ezxml" /> | |||
<include chapter="lorum" /> | |||
|
Empty file.
Oops, something went wrong.