FYI: I just started to learn Erlang with the help of https://learnyousomeerlang.com.
While going through the chapters I encountered about module_info. The following is the output that I got for one of the module.
[{module,useless},
{exports,[{add,2},
{hello,0},
{greet_and_add_two,1},
{module_info,0},
{module_info,1}]},
{attributes,[{vsn,[296174539721071843666185210011547328263]},
{author,"An Erlang Champ"}]},
{compile,[{version,"7.4"},
{options,[debug_info,export_all]},
{source,"/Users/vivekdhayalan/useless.erl"}]},
{native,false},
{md5,<<222,209,36,56,31,223,59,231,71,237,66,109,149,39,
223,7>>}]
I have noticed md5 attribute in my output on curious I updated my module and checked the module info after compiling by module once again. But, I still found the same md5 thinking what could be the reason.
If you have any clues please help to understand. Might, be I'm to curious about md5 as I'm yet complete the chapter.
note: vsn is also not getting updated
Updating with more info.
My initial code:
-module(useless).
-export([add/2, hello/0, greet_and_add_two/1]).
add(C,B) ->
C + B.
%% Shows greetings.
%% io:format/1 is the standard function used to output text.
hello() ->
io:format("Hello, world!~n").
greet_and_add_two(X) ->
hello(),
add(X,2).
Module info & compile steps
28> compile:file(useless, [debug_info, export_all]).
{ok,useless}
29> useless:module_info().
[{module,useless},
{exports,[{add,2},
{hello,0},
{greet_and_add_two,1},
{module_info,0},
{module_info,1}]},
{attributes,[{vsn,[296174539721071843666185210011547328263]},
{author,"An Erlang Champ"}]},
{compile,[{version,"7.4"},
{options,[debug_info,export_all]},
{source,"/Users/vivekdhayalan/useless.erl"}]},
{native,false},
{md5,<<222,209,36,56,31,223,59,231,71,237,66,109,149,39,
223,7>>}]
I'm updating my module just with adding author as below
-module(useless).
-export([add/2, hello/0, greet_and_add_two/1]).
-author("An Erlang Champ").
add(C,B) ->
C + B.
%% Shows greetings.
%% io:format/1 is the standard function used to output text.
hello() ->
io:format("Hello, world!~n").
greet_and_add_two(X) ->
hello(),
add(X,2).
my module info after compile.
compile:file(useless, [debug_info, export_all]).
{ok,useless}
31> useless:module_info().
[{module,useless},
{exports,[{add,2},
{hello,0},
{greet_and_add_two,1},
{module_info,0},
{module_info,1}]},
{attributes,[{vsn,[296174539721071843666185210011547328263]},
{author,"An Erlang Champ"}]},
{compile,[{version,"7.4"},
{options,[debug_info,export_all]},
{source,"/Users/vivekdhayalan/useless.erl"}]},
{native,false},
{md5,<<222,209,36,56,31,223,59,231,71,237,66,109,149,39,
223,7>>}]
As we could see the md5 has not updated even after adding info.
compile:file() compiles to a new .beam file on disk, but does not load it. The module_info() function reports the status of the loaded version. The shell c() shortcut will both compile and load - use that instead for interactive work.
-module(my).
-compile([export_all]).
go() -> "hello".
In the shell:
~/erlang_programs$ erl
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V9.3 (abort with ^G)
1> c(my).
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}
2> my:module_info().
[{module,my},
{exports,[{go,0},{module_info,0},{module_info,1}]},
{attributes,[{vsn,[317460282063015155415500557234702055363]}]},
{compile,[{options,[]},
{version,"7.1.5"},
{source,"/Users/7stud/erlang_programs/my.erl"}]},
{native,false},
{md5,<<"îÔ WÝÒ\n©¥ëíQ&÷Ã">>}]
Adding another function:
-module(my).
-compile([export_all]).
stop() -> "goodbye".
go() -> "hello".
In the shell:
5> c(my).
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}
6> my:module_info().
[{module,my},
{exports,[{stop,0},
{go,0},
{module_info,0},
{module_info,1}]},
{attributes,[{vsn,[210928589040636765166954307796272702313]}]},
{compile,[{options,[]},
{version,"7.1.5"},
{source,"/Users/7stud/erlang_programs/my.erl"}]},
{native,false},
{md5,<<158,175,94,91,0,91,194,106,194,244,45,224,190,48,
99,105>>}]
I updated my module and checked the module info after compiling by
module once again. But, I still found the same md5 thinking what could
be the reason.
Prove it.
Related
trying to use function string:find/2but every time getting the error
CRASH REPORT Process <0.779.0> with 0 neighbours exited with reason: {{undef,[{string,find,[[<<208,162,51,32,208,190,208,177,209,137,46,44,32,84,51,32,116,111,116,97,108,44>>],[<<208,186,209,128,208,190,208,178>>]],[]},{proxy_layer_cli_handle_req,do_execute_keysearch,4,[{file,\"/opt/proxy_layer/_build/test/lib/proxy_layer/src/proxy_layer_cli_handle_req.erl\"},{line,222}]},{proxy_layer_cli_handle_req,keysearch,3,[{file,\"/opt/proxy_layer/_build/test/lib/proxy_layer/src/proxy_layer_cli_handle_req.erl\"},{line,...}]},...]},...}
when i use it in terminal - everything is okay
1> string:find(<<208,162,51,32,208,190,208,177,209,137,46,44,32,84,51,32,116,111,116,97,108,44>>,<<208,186,209,128,208,190,208,178>>).
1> nomatch
I'm using Erlang 20.1
here is the code which I use:
do_execute_keysearch([First|Rest], PriceList, Keyword, Acc) ->
Id = utils:get_value(<<"Id">>, First),
case utils:get_value(<<"Keywords">>, First) of
<<>> -> do_execute_keysearch(Rest, PriceList, Keyword, Acc);
undefined -> do_execute_keysearch(Rest, PriceList, Keyword, Acc);
Keys ->
case string:find(Keys, Keyword) of
nomatch ->
do_execute_keysearch(Rest, PriceList, Keyword, Acc);
_ ->
Price = find_price_by_service_id(PriceList, Id),
NewAcc = [lists:append(Price, First) | Acc],
do_execute_keysearch(Rest, PriceList, Keyword, NewAcc)
end
end;
UPDATE:
Issue fixed after changing Erlang version in docker container. (Changed to Erlang 20.1)
Don’t know why there are some modules undefined in Erlang 19
So the problem solved now
string:find/2 was added to Erlang in version 20 which is why you were getting an undef error in Erlang 19. The solution is to upgrade to Erlang 20 (which you've already done).
Look at the error more carefully. Or rather, try to reproduce it. Which of these looks more like your error?
1> catch lists:nonexist(<<1>>, <<2>>).
{'EXIT',{undef,[{lists,nonexist,[<<1>>,<<2>>],[]},
{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]},
{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,431}]},
{shell,exprs,7,[{file,"shell.erl"},{line,687}]},
{shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},
{shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}}
2> catch lists:nonexist([<<1>>], [<<2>>]).
{'EXIT',{undef,[{lists,nonexist,[[<<1>>],[<<2>>]],[]},
{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]},
{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,431}]},
{shell,exprs,7,[{file,"shell.erl"},{line,687}]},
{shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},
{shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}}
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).
consider the code bleow:
-module(add_two).
-compile(export_all).
start()->
process_flag(trap_exit, true),
Pid = spawn_link(add_two, loop, []),
register(add_two, Pid),
ok.
request()->
add_two ! bad,
receive
{'EXIT', _Pid, Reason} -> io:format("self:~w~n", [{error, Reason}]);
{Result} -> io:format("result:~w~n", [Result])
after
1000->timeout
end.
loop()->
receive
bad -> exit(nogoodreason_bad);
{request, Pid, Msg} -> Pid ! {result, Msg + 2}
end,
loop().
when I test the code above in shell,I get two different results with different input order,but why?
first input order :
Eshell V5.9.1 (abort with ^G)
1> add_two:request(ddd).
** exception error: undefined function add_two:request/1
2> add_two:start().
ok
3> add_two:request().
self:{error,nogoodreason_bad}
ok
second input order:
Eshell V5.9.1 (abort with ^G)
1> add_two:start().
ok
2> add_two:request(ddd).
** exception error: undefined function add_two:request/1
3> add_two:request().
** exception error: bad argument
in function add_two:request/0 (add_two.erl, line 11)
The call add_two:request(ddd) makes the shell process die, taking add_two down with it, due to the spawn_link() call. You can confirm this by checking the shell's pid before and after an exception. It doesn't even have to involve the add_two module:
12> self().
<0.61.0>
13> 2+2.
4
14> self().
<0.61.0>
15> 1/0.
** exception error: bad argument in an arithmetic expression
in operator '/'/2
called as 1 / 0
16> self().
<0.69.0>
17>
You can avoid this effect either by calling spawn instead of spawn_link, or trapping and handling exits in the spawned process.
Follow-up to this one.
I got the reading/decoding working
1> {ok, F} = file:read_file("inaimathi.rsapub").
{ok,<<"-----BEGIN RSA PUBLIC KEY-----\nmQINBE9NBIQBEADMSzN6b0FaPP0rGiLDWKfH4ehN66Z0SAIynXm6lBHjmO69pNsm\niIe4p1X9aXhr"...>>}
2> [Entry] = public_key:pem_decode(F).
[{'RSAPublicKey',<<153,2,13,4,79,77,4,132,1,16,0,204,75,
51,122,111,65,90,60,253,43,26,34,195,
88,167,...>>,
not_encrypted}]
According to the docs, the last thing I have to do in order to get a working public key out of this is run public_key:pem_entry_decode/1 on that Entry. However, when I try to do that, I get an eror.
3> public_key:pem_entry_decode(Entry).
** exception error: no match of right hand side value
{error,
{asn1,
{{badmatch,{error,{asn1,{wrong_tag,{131097,16}}}}},
[{'OTP-PUB-KEY',dec_RSAPublicKey,2,
[{file,"OTP-PUB-KEY.erl"},{line,5956}]},
{'OTP-PUB-KEY',decode,2,
[{file,"OTP-PUB-KEY.erl"},{line,493}]},
{public_key,der_decode,2,
[{file,"public_key.erl"},{line,166}]},
{erl_eval,do_apply,6,
[{file,"erl_eval.erl"},{line,576}]},
{shell,exprs,7,[{file,"shell.erl"},{line,668}]},
{shell,eval_exprs,7,
[{file,"shell.erl"},{line,623}]},
{shell,eval_loop,3,
[{file,"shell.erl"},{line,608}]}]}}}
in function public_key:der_decode/2 (public_key.erl, line 170)
What am I doing wrong here?
EDIT: Didn't think it would matter, but someone asked, so.
I'm running Debian Wheezy on a Core i3 with Erlang installed from a ~2 day old checkout of this.
erl --version says
Erlang R15B02 (erts-5.9.2) [source] [64-bit] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false]
Your code works fine here:
decode() ->
[application:start(X) || X <- [crypto, public_key, ssl]],
RawData = ["-----BEGIN PUBLIC KEY-----\n",
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBm8yuHmd0P6scl48DEi+xp47w\n",
"XVZaKWRygGKtA2XkdRuCU99f0Tq07Llcgf8XuR+Wnk+z2CdMMFMzOGhCePblVIAn\n",
"33dcBVlDokpBF7AnTClsaLcixxZw1LIUiaPaBdN7oG8vt3G2caLHRrrkoEnccY+6\n",
"GadfH7iuHdcVsz1mowIDAQAB\n",
"-----END PUBLIC KEY-----"],
D = iolist_to_binary(RawData),
[Entry] = public_key:pem_decode(D),
public_key:pem_entry_decode(Entry).
Generates output (shortened):
{'RSAPublicKey',135956...,65537}
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.