how to format a throw statement in erlang - erlang

I am new to Erlang syntax and struggling with this
I can do this and compile
throw(Reason)
which is of type throw/1
I want to be able to do this:
%% I have seen this code in sample examples.
?THROW("Couldn't start process: ~p. ~n", [Reason])
I do not think there there is throw/2.
Then how can I define a macro like above?

?THROW is a macro. It should be define somewhere as:
-define(THROW(Format,Params),throw(io_lib:format(Format,Params))).
In this definition, the call to io_lib:format(Format,Params) returns a single string that is used as Reason by the function throw.

Related

Check if parameter was sent to a function

I have the following case, a request is sent to my server, and I am parsing some GET parameters, in order to process it properly. After request is parsed, I am getting something like:
some_function(parameter1, parameter2, ...) ->
some_steps_here.
The idea is that I want to be able to return nice error codes if some of these parameters are missing. E.g. if user did not enter parameter1 into his url, I want to return the error instead of doing some_steps_here.
Was trying to solve it using pattern matching, but don't have idea how to do it at all.
First, if you write param1 and param2 as lower letters, it means an atom and not a Parameter. You want your function to be:
some_function(Param1, Param2, ...)
Regarding your question, I'd suggest to use function clauses to catch a case where Param1 == undefined for example
some_function(undefined, _Param2, ...) ->
io:format("Param1 is undefined~n");
some_function(_Param1, undefined, ...) ->
io:format("Param2 is undefined~n");
some_function(Param1, Param2, ...) ->
io:format("Params are OK!~n").
Every clause is separated by a ; and the last clause is terminated by a dot ..
Update:
Answering the comment below: Is there a way to make it more generic?
It really depends on your implementation. You need to think what is your desired input and if you don't get the desired input, what will you get? A specific atom? Just a random atom instead of a list? Below I've added some other options you might also use. And please, take a look at Learn You Some Erlang you will probably find all your answers there.
You can use guards to check for a specific type:
some_function(Param1, ...) when is_atom(Param1) ->
...
some_function(Param1, ...) -> ...
Or, case .. of to check for something specific:
some_function(Param1, Param2, ...) ->
case Param1=:=7 andalso is_list(Param2) of
true -> something;
false -> something_else
end.
Please see this and this for more information and examples.

How to get the size of a user defined struct? (sizeof)

I've got a structure with C representation:
struct Scard_IO_Request {
proto: u32,
pciLength: u32
}
when I want to ask the sizeof (like in C sizeof()) using:
mem::sizeof<Scard_IO_Request>();
I get compilation error:
"error: `sizeof` is a reserved keyword"
Why can't I use this sizeof function like in C? Is there an alternative?
For two reasons:
There is no such function as "sizeof", so the compiler is going to have a rather difficult time calling it.
That's not how you invoke generic functions.
If you check the documentation for mem::size_of (which you can find even if you search for "sizeof"), you will see that it includes a runnable example which shows you how to call it. For posterity, the example in question is:
fn main() {
use std::mem;
assert_eq!(4, mem::size_of::<i32>());
}
In your specific case, you'd get the size of that structure using
mem::size_of::<Scard_IO_Request>()

Variable in Erlang

I have a very simple Erlang program:
-module(test).
-export([start/0]).
Code = "Z00887".
start() -> io:fwrite(Code).
And I have follows two errors:
c:/erl6.1/dev/test.erl:4: syntax error before: Code
c:/erl6.1/dev/test.erl:5: variable 'Code' is unbound
Could you please help me correctly using variables in my code.
You are defining a variable that is global to the module, which is not allowed. Remember, "variables" in Erlang are really "symbols", so there is no concept of a "global" constant across all functions or processes. The closest thing to this in Erlang would be a macro defined in the module, but if a value is only needed in one place and you want to name it then this must be done within the function definition.
Also, do not use io:fwrite/1 or io:format/1. The problem is the possible inclusion of escape characters in the string you are passing. For example, this causes an error: Code = "Wee~!", io:format(Code). and it will not be caught by the compiler.
The most common thing to do is define a variable within the function:
-module(foo).
-export([start/0]).
start() ->
Code = "Z00887",
io:fwrite("~p~n", [Code]).
You could also just use the value directly:
-module(foo).
-export([start/0]).
start() ->
io:fwrite("Z00887~n").
Or you could define a macro across the whole module:
-module(foo).
-export([start/0]).
-define(CODE, "Z00887").
start() ->
io:fwrite("~p~n", [?CODE]).
Or you could even define a stub function that returns what you want:
-module(foo).
-export([start/0]).
start() ->
io:fwrite("~p~n", [code()]).
code() -> "Z00887".
This last version is actually not as weird as it may seem at first. Very often when developing some code early on you will know you need a value somewhere that you will need to derive in some way, but don't want to worry about the details of it just yet. A stub function is an excellent way to hide the details of how you will do that in the future without writing macro code, variable definitions, etc. that you will have to remember to go back and change later. For example, the last example above will almost certainly change to something like this in the future:
-module(foo).
-export([start/0]).
start() ->
io:fwrite("~p~n", [code()]).
code() ->
{ok, Code} = some_init_module:get_code(),
Code.
Keep this in mind. It makes Erlang almost as prototype-friendly as Guile or Scheme.

How to show correct function names in error messages?

Let's say that I call some functions indirectly, via a variable. For example:
obj = {
on_init = function()
print "hello."
end,
on_destroy = function()
print "bye."
end,
on_do_something = function()
print "doing something."
error("Hi de hi, hi de ho!")
end,
}
local event = "do_something"
local func = obj["on_" .. event]
func()
All works fine.
However, the problem is that when the called function raises an exception (as in the code above) the error message isn't quite clear. It is thus:
lua: test.lua:13: Hi de hi, hi de ho!
stack traceback:
[C]: in function 'error'
test.lua:13: in function 'func'
test.lua:20: in main chunk
It says "in function 'func'". I'd prefer it to say "in function 'on_do_something'" instead.
I'd imagine this scenario to be very common. Is there a solution for this?
I tried calling the function thus:
obj["on_" .. event]()
But then the error message says "in function '?'", which isn't helpful either.
(I tried this code on Lua 5.1, 5.2 and LuaJIT without notable differences.)
This is a limitation of the heuristics used by Lua to provide names for functions.
In Lua, all functions are anonymous. A given function can be the value of several variables: global, local, and table fields. The Lua debug system, which is used in error handling, tries to find a reasonable name for a value based on where it came from by looking into the bytecode being executed.
See
Why is 'name' nil for debug.getinfo(1).
You have a few options. The debug module will try to produce something useful. For instance, you might be able to get the file name and line number where it was defined, if this is your own code. See
http://www.lua.org/pil/23.1.html for the list of what is available via debug module. Or, you might be able to define the functions in the module, then add them to the table:
-- module something
function a()
...
end
tt = {
fn1 = a,
...
}
Depending on where you trap the error (error handler installed via debug hook?), you could check if filename is the module where your table of functions is defined, and if it is, then use the debug module to print appropriate info based on your table structure etc; if it is not, just print the default traceback etc.

erlang: function called with real 'fun' should be transformed with parse_transform?

I'm looking at the O'Reilly Erlang Programming book and there's an example that is run in the erlang shell that looks like this:
17> MS = ets:fun2ms(fun({Name,Country,Job}) when Job /= cook ->
[Country,Name] end).
[ ....an erlang match expression is returned.... ]
18> ets:select(countries, MS).
[[ireland,sean],[ireland,chris]]
However, when I do something similar in my code (not in the shell):
Fun = fun({Type,_,_,ObjectId,PlayerId}) when Type==player_atom, PlayerId==2 -> ObjectId end,
MatchFun = ets:fun2ms(Fun),
PlayerObjectId = ets:select(?roster_table, MatchFun),
I get FUBAR:
exit:{badarg,{ets,fun2ms,[function,called,with,real,'fun',should,be,transformed,with,parse_transform,'or',called,with,a,'fun',generated,in,the,shell]}}
(As an aside, I wonder why the error isn't 'function called with....' Probably so io:format("~p", TheErrorMessage) will line wrap?)
Anyway, I have abandoned select in favor of ets:foldl, since the latter works and - through exceptions in the fun - allows me to terminate the traversal when the first item is found. But, I'm still curious...
...wha? (I did some reading on parse_transform, and I'm new enough to erlang that I'm missing the connection.)
The badarg exception is symptom of a built-in function (or a pseudo function, as in this case) called with a wrong parameter. In this case, the ets:fun2ms/1 function.
Reading from the official documentation:
fun2ms(LiteralFun) -> MatchSpec
Pseudo function that by means of a parse_transform translates
LiteralFun typed as parameter in the function call to a match_spec.
With "literal" is meant that the fun needs to textually be written as
the parameter of the function, it cannot be held in a variable which
in turn is passed to the function).

Resources