小编Max*_*Max的帖子

EUnit和io:格式

我想使用EUnit测试一些第三方Erlang代码.

代码功能的输出使用显示在标准输出上io:format/2.我想捕获该输出并对?assert将要打印的字符串执行测试.我无法修改第三方代码.

这是用Erlang做到这一点的方法吗?(例如,在Java中,我可以简单地将System.setOut()用于输出流).

更新:

在group_leader/2似乎是在正确的轨道上.

但是,我仍然没有看到它如何允许我捕获打印的字符串,io:format所以我可以测试我的断言.一个非常简单的代码示例是:

result(Value) ->
    io:format("Result: ~w~n", [Value]).

test_result() ->
    ?assertMatch("Result: 5~n", result(5)).
Run Code Online (Sandbox Code Playgroud)

显然,函数的返回result/1是原子ok,但实际上我想测试输出到控制台的字符串(即"Result: 5~n").

这种方法我错了,因为似乎没有其他人这样做(根据我缺乏搜索结果判断)?

背景:第三方代码是一个交互式控制台应用程序,因此所有功能仅用于io:format显示结果.

erlang

7
推荐指数
2
解决办法
2697
查看次数

Haskell约定:可能还是空列表?

请Haskell的任何专家在那里为我澄清一些事情:

给出一个函数的简化示例,match它应该从列表返回一个匹配的值,这是使用Maybe或返回的"更好"的函数定义[](空列表)?

那是:

match :: String -> [String] -> Maybe String
Run Code Online (Sandbox Code Playgroud)

要么

match :: String -> [String] -> [String]     {- possibly empty, if no match -}
Run Code Online (Sandbox Code Playgroud)

出于清晰的原因,我更喜欢第一个版本,但我很想知道这种事情是否有约定.

haskell

6
推荐指数
1
解决办法
1046
查看次数

Apple允许我在自己的应用程序中重用它们的图标吗?

在我的OS X应用程序中,我允许用户打开Finder窗口.我想在我的"打开Finder"按钮上使用Finder的图标.我的应用程序将进入App Store,但我宁愿预先防止任何违反Apple使用其图标的政策.

那么,Apple会允许重复使用吗?并且,任何人都可以提供相应的Apple文档参考吗?(我以为我读过它是不允许的,但我现在找不到它.)

UPDATE:办案人感兴趣的应用程序没有运行,我用前一个问题的superfell的回答12166532,如下所示:

// Return an application's icon using its bundle identifier
- (NSImage *) applicationIconWithBundleIdentifier: (NSString *) bundleIdentifier
{
    NSImage *image = [NSImage imageNamed:NSImageNameComputer]; // fallback icon

    NSString *path = [[NSWorkspace sharedWorkspace] absolutePathForAppBundleWithIdentifier:bundleIdentifier];
    if (path) {
        image = [[NSWorkspace sharedWorkspace] iconForFile:path];
    }

    return image;
}
Run Code Online (Sandbox Code Playgroud)

但是,我非常感谢Rob的回答让我走上正轨.

macos objective-c

6
推荐指数
1
解决办法
528
查看次数

global:whereis_name()从不同的终端返回不同的Pid

有人可以向我解释为什么Pid从全局返回:whereis_name()在不同的终端(在OSX下,至少)完成时是不同的.

下面是一个简单的演示.

demo.erl
-module(demo).

-export([start/0, loop/0, echo/1]).


start() ->
    Pid = spawn(?MODULE, loop, []),
    yes = global:register_name('demo', Pid).

echo(Msg) ->
    global:send('demo', Msg).

loop() ->
    receive
        Msg -> 
            io:format("demo: ~w~n", [Msg]),
            loop()
    end.
Run Code Online (Sandbox Code Playgroud)

航站楼A:

erl -sname A -setcookie demo
(A@local)1> demo:start().
yes
(A@local)2> global:whereis_name(demo).
<0.39.0>
(A@local)3> demo:echo(aaa).
<0.39.0>
demo: aaa  
demo: bbb  
demo: ccc  
(A@local)4>
Run Code Online (Sandbox Code Playgroud)

B航站楼:

erl -sname B -setcookie demo
(B@local)1> net_kernel:connect_node('A@local').
true
(B@local)2> demo:echo(bbb).                     
<6572.39.0>
(B@local)3> global:whereis_name(demo).
<6572.39.0>
Run Code Online (Sandbox Code Playgroud)

终端C:

erl -sname C -setcookie demo
(C@local)1> net_kernel:connect_node('A@local').
true
(C@local)2> demo:echo(ccc). …
Run Code Online (Sandbox Code Playgroud)

erlang

2
推荐指数
1
解决办法
755
查看次数

避免竞争条件

以下代码片段由Francesco Cesarini和Erlang编程的Simon Thompson撰写,作为Erlang中可能的竞争条件的一个例子.

start() -> 
  case whereis(db_server) of
    undefined -> 
      Pid = spawn(db_server, init, []), 
      register(db_server, Pid), 
      {ok, Pid};
    Pid when is_pid(Pid) ->
      {error, already_started}
  end.
Run Code Online (Sandbox Code Playgroud)

在没有逐字复制细节的情况下,作者解释说如果两个进程同时执行start(),那么运行"undefined"部分的进程1可能无法完成,因为进程2会导致它被抢占.然后,进程2将运行"未定义"部分以完成.现在,当进程1恢复时,进程2已经注册了db_server,导致其对register()的调用抛出运行时错误.我希望你能理解我的意思,因为我不想翻阅这本书的文字.

我的问题是,当两个进程同时执行start()时,如何编码上述确切的功能以避免潜在的竞争条件?

erlang

2
推荐指数
1
解决办法
1243
查看次数

Ada83 或 Ada95 是否定义了内存模型来支持多任务处理?

随着“最近”对 C 和 C++ 添加内存模型的更改(类似于 Java 和 C#),我想知道 Ada83 或 Ada95 对并发的内置支持是否也定义了内存模型。

有谁知道有关 Ada 是否定义了内存模型的任何参考资料?

额外问题:Ada83 是第一个为共享状态并发提供 INBUILT 支持的通用编程语言吗?

concurrency multithreading ada memory-model

2
推荐指数
1
解决办法
352
查看次数

重发邮件的好设计?

我需要向全局注册的进程发送一条消息,当它被替换为备份进程(即故障转移)时,可能在短时间内不可用.

以下片段是好的Erlang代码:

% send message to globally registered process, with possibility to retry once
send_message(To, Message, Retry) ->
    try global:send(To, Message)
    catch
        % registered process To is unavailable
        exit: {badarg, {To, Message}} ->
            io:format("catch: exit: {badarg,{~w, ~w}}~n", [To, Message]), % dbg only
            case Retry of 
                true ->
                    % retry sending message, after 1 second
                    sleep(1000),
                    send_message(To, Message, false);
                false ->
                    % re-throw caught exit, including stack trace
                    erlang:raise(exit, {badarg, {To, Message}}, 
                                 erlang:get_stacktrace())
            end            
    end.
Run Code Online (Sandbox Code Playgroud)

Retry参数为true或false,表示如果出现问题,应重试一次消息.如果仍然无法发送消息,我希望引发相同的异常,就像在try-catch块之外调用global:send(To,Message)一样.

我知道上面的工作,但我担心我的case块的错误部分是否是好的erlang(例如使用erlang:raise()和rlang:get_stacktrace()).

有什么想法或建议使代码"更好"?

erlang

1
推荐指数
1
解决办法
868
查看次数