Erlang:强制公开方法,为什么?
Erlang: Forced to make method public, why?
我正在关注 Joe Armstrong 的书 Programming Erlang, 2nd Edition
,其中我们制作了一个文件服务器。
我的代码:
-module(afile_server).
-author("harith").
%% API
-export([start/1]).
start(Dir) -> spawn(afile_server, loop, [Dir]).
loop(Dir) ->
receive
{Client, list_dir} ->
Client ! {self(), file:list_dir(Dir)};
{Client, {get_file, File}} ->
File_Path = filename:join(Dir, File),
Client ! {self(), file:read_file(File_Path)}
end,
loop(Dir).
我们可以看到,loop
是一个私有方法,不应该暴露给外界。现在当我运行它时,我得到:
1> FileServer = afile_server:start(".").
<0.33.0>
=ERROR REPORT==== 3-Jan-2015::06:58:56 ===
Error in process <0.33.0> with exit value: {undef,[{afile_server,loop,["."],[]}]}
2>
但是当我将 loop
public 设为:
-module(afile_server).
-author("harith").
%% API
-export([start/1, loop/1]).
start(Dir) -> spawn(afile_server, loop, [Dir]).
loop(Dir) ->
receive
{Client, list_dir} ->
Client ! {self(), file:list_dir(Dir)};
{Client, {get_file, File}} ->
File_Path = filename:join(Dir, File),
Client ! {self(), file:read_file(File_Path)}
end,
loop(Dir).
然后运行正常:
1> FileServer = afile_server:start(".").
<0.33.0>
2>
spawn
是否要求方法是 public?我想是的,因为它运行为:
afile_server:loop(Dir)
但我想确定没有其他问题。
如果您将 spawn 与 M:F:A 一起使用,您将被迫设置循环 public。
你可以这样避免:
-module(afile_server).
-export([start/1]).
start(Dir) -> spawn(fun() -> loop(Dir) end).
loop(Dir) ->
receive
{Client, list_dir} ->
Client ! {self(), file:list_dir(Dir)};
{Client, {get_file, File}} ->
File_Path = filename:join(Dir, File),
Client ! {self(), file:read_file(File_Path)}
end,
loop(Dir).
如果您的方法没有参数,您还可以使用:
spawn(fun loop/0),
使用带有 M:F:A 的版本的一个很好的理由在于,每当您加载同一模块的新版本时,都会调用这个新版本。否则你将继续调用旧模块。
导出函数的另一个原因,即使它在同一个模块中,是因为 spawn
您创建了一个全新的上下文和环境,因此必须调用导出的函数是合理的.
我正在关注 Joe Armstrong 的书 Programming Erlang, 2nd Edition
,其中我们制作了一个文件服务器。
我的代码:
-module(afile_server).
-author("harith").
%% API
-export([start/1]).
start(Dir) -> spawn(afile_server, loop, [Dir]).
loop(Dir) ->
receive
{Client, list_dir} ->
Client ! {self(), file:list_dir(Dir)};
{Client, {get_file, File}} ->
File_Path = filename:join(Dir, File),
Client ! {self(), file:read_file(File_Path)}
end,
loop(Dir).
我们可以看到,loop
是一个私有方法,不应该暴露给外界。现在当我运行它时,我得到:
1> FileServer = afile_server:start(".").
<0.33.0>
=ERROR REPORT==== 3-Jan-2015::06:58:56 ===
Error in process <0.33.0> with exit value: {undef,[{afile_server,loop,["."],[]}]}
2>
但是当我将 loop
public 设为:
-module(afile_server).
-author("harith").
%% API
-export([start/1, loop/1]).
start(Dir) -> spawn(afile_server, loop, [Dir]).
loop(Dir) ->
receive
{Client, list_dir} ->
Client ! {self(), file:list_dir(Dir)};
{Client, {get_file, File}} ->
File_Path = filename:join(Dir, File),
Client ! {self(), file:read_file(File_Path)}
end,
loop(Dir).
然后运行正常:
1> FileServer = afile_server:start(".").
<0.33.0>
2>
spawn
是否要求方法是 public?我想是的,因为它运行为:
afile_server:loop(Dir)
但我想确定没有其他问题。
如果您将 spawn 与 M:F:A 一起使用,您将被迫设置循环 public。
你可以这样避免:
-module(afile_server).
-export([start/1]).
start(Dir) -> spawn(fun() -> loop(Dir) end).
loop(Dir) ->
receive
{Client, list_dir} ->
Client ! {self(), file:list_dir(Dir)};
{Client, {get_file, File}} ->
File_Path = filename:join(Dir, File),
Client ! {self(), file:read_file(File_Path)}
end,
loop(Dir).
如果您的方法没有参数,您还可以使用:
spawn(fun loop/0),
使用带有 M:F:A 的版本的一个很好的理由在于,每当您加载同一模块的新版本时,都会调用这个新版本。否则你将继续调用旧模块。
导出函数的另一个原因,即使它在同一个模块中,是因为 spawn
您创建了一个全新的上下文和环境,因此必须调用导出的函数是合理的.