热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

erlang游戏开发_用Erlang进行铁路导向的开发

erlang游戏开发由OlegTarasenko该博客建议了一种替代方法,您可以在受Elixir管道宏|启发的情况下构建程序,而无需使用我最近编写的微

erlang游戏开发

由Oleg Tarasenko

该博客建议了一种替代方法,您可以在受Elixir管道宏'|>启发的情况下构建程序,而无需使用我最近编写的微小Epipe库的可怕的解析转换。 Epipe本身受到Scott Wlaschin发表的这篇文章的启发。

入门

让我们执行一个小的实际任务,该示例将演示这种用于函数式编程的铁路方法。

考虑一下我们使用Erlang构建POP3电子邮件客户端的情况。 我们的目标是实现与POP服务器建立连接的控制流。

下图说明了完成此操作所需的步骤:

首先,让我们构建一个实现连接功能的函数:

connect(Addr, Port, ConnOptions, User, Password) ->
{ok, Socket} = ssl:connect(Addr, Port, ConnOptions),
ok = receive_greetings(Socket),
ok = send_user(Socket, User),
ok = send_password(Socket, Password).

上面的代码非常漂亮,只有四行代码,我们完成了! 但是,等等……上面的实现是最好的情况。 显然,我们需要添加一些错误处理才能处理边缘情况:(。我的意思是,“可能会出什么问题”?

添加错误处理

让我们在下图上总结所有可能的边缘情况:

让我们添加错误处理代码,然后看看它的外观!

剧透:下面的例子很简单,可以通过将操作拆分为单独的函数来美化,但是嵌套的case语句是不可避免的。

connect(Addr, Port, ConnOptions, User, Password) ->
case ssl:connect(Addr, Port, ConnOptions) of
{ok, Socket} ->
case receive_greetings(Socket) of
ok ->
case send_user(Socket, User) of
ok ->
case send_password(Socket, Password) of
ok -> ok;
_Err -> error_logger:error_msg("Auth error")
end;
_Err ->
error_logger:error_msg("Unknown user")
end;
Err -> error_logger:error_msg("Could not receive_greetings")
end;
_Error -> error_logger:error_msg("Could not connect")
end.

哇。 现在,我们添加了所有错误代码。 哇,代码的大小增加了400%……可读性也相应下降。 哎哟!

也许有一种更清洁的方式来实现这一目标?

使用“铁路”方法(理论)进行更好的错误处理设计

铁路方法的思想是使用铁路开关作为模拟来分解“阶梯式”功能块:

*图片来源:Scott Wlaschin

可以将其转换为以下Erlang代码:

switch_component(Input) ->
case some_action() of
{ok, Response} -> {ok, Response}; % Green track
Error -> {error, Error} % Red track
end.

一旦为所有必需的操作创建了两种(正常/错误)开关,您就可以像在铁路上完成的那样将它们组合起来:

*图片来源:Scott Wlaschin

因此,回顾一下,实际发生的是:

在成功方案的情况下,所有功能(“铁路开关”)将按顺序执行,我们沿着“成功轨道”行进。 否则,我们的火车将切换到“错误轨道”,并沿该路线行驶,绕过所有其他步骤:

*图片来源:Scott Wlaschin

使用“铁路”方法进行更好的错误处理设计

我们发布了一个小型的erlang库 ,该库简化了Erlang的铁路分解。 因此,在上述示例的基础上,让我们看一下如何使用Epipe实现我们的用例:

-record(connection, {
socket,
user,
addr,
port,
passwd
}).

connect(Addr, Port, User, Password) ->
Connection = #connection{
user = User,
passwd = Password,
add = Addr,
port = Port
},
% Defining list of railway switches to follow
ConnectionSteps = [
{get_socket, fun get_socket/1},
{recv_greetings, fun recv_greetings/1},
{send_user, fun send_user/1},
{send_passwd, fun send_passwd/1}
],
% Running through switches
case epipe:run(ConnectionSteps, Connection) of
{error, Step, Reason, _State} ->
error_logger:error_msg("Failed to establish connection. Reason: ~p", [Step]),
{error, Reason};
{ok, _Conn} = Success -> Success
end.


% Building blocks. Note that every function can return either {ok, Connection} or {error, Reason}

get_socket(Connection) ->
case ssl:connect(Addr, Port, ExtraOptions) of
{ok, Socket} -> {ok, Connection#connection{socket = Socket}};
Error -> {error, Error}
end.

recv_greetings(Connection) ->
case recv(Connection) of
{ok, <<"&#43;OK", _Rest/binary>>} -> {ok, Connection};
{ok, <<"-ERR ", Error/binary>>} -> {error, Error};
Err -> {error, Err}
end.

send_user(Connection &#61; #connection{user &#61; User}) ->
Msg &#61; list_to_binary(User),
send(Connection, <<"USER ", Msg/binary>>),

case recv(Connection) of
{ok, <<"&#43;OK", _Rest/binary>>} -> {ok, Connection};
{ok, <<"-ERR ", Error/binary>>} -> {error, Error};
Err -> {error, Err}
end.

send_passwd(Connection &#61; #connection{passwd &#61; Passwd}) ->
Msg &#61; list_to_binary(Passwd),
send(Connection, <<"PASS ", Msg/binary>>),

case recv(Connection) of
{ok, <<"&#43;OK", _Rest/binary>>} -> {ok, Connection};
{ok, <<"-ERR ", Error/binary>>} -> {error, Error};
Err -> {error, Err}
end.

与嵌套的case语句实现相比&#xff0c;所生成的代码在代码行方面并不小&#xff0c;但它的可读性肯定更高&#xff0c;从而更易于调试和支持。

如果你想看到一个真实世界中的实现&#xff0c;请看一看这个使用铁路方法进行重构的例子。

最初于 2018 年6月13日 发布在 www.erlang-solutions.com 上。

翻译自: https://hackernoon.com/railway-oriented-development-with-erlang-46ea6db4a795

erlang游戏开发



推荐阅读
  • 近期看见一篇来自Intel的很有意思的分析文章,作者提到在他向45名与会的各公司程序员开发经理战略师提问“什么是实施并行编程的最大障碍”时,下面五个因素 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 去掉空格的方法——Python工程师招聘标准与实践
    本文介绍了去掉空格的方法,并结合2019独角兽企业招聘Python工程师的标准与实践进行讨论。同时提供了一个转载链接,链接内容为更多相关信息。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • 本文详细介绍了如何创建和使用VUE uni-app开发环境,包括通过HBuilderX可视化界面和通过vue-cli命令执行的方法。文章内容简单清晰,易于学习与理解。通过学习本文,读者可以深入了解VUE uni-app开发环境,并通过实践验证掌握具体的使用情况。编程笔记将为读者推送更多相关知识点的文章,欢迎关注! ... [详细]
  • POCOCLibraies属于功能广泛、轻量级别的开源框架库,它拥有媲美Boost库的功能以及较小的体积广泛应用在物联网平台、工业自动化等领域。POCOCLibrai ... [详细]
  • 现在比较流行使用静态网站生成器来搭建网站,博客产品着陆页微信转发页面等。但每次都需要对服务器进行配置,也是一个重复但繁琐的工作。使用DockerWeb,只需5分钟就能搭建一个基于D ... [详细]
  • centos6.8 下nginx1.10 安装 ... [详细]
  • 如何搭建服务器环境php(2023年最新解答)
    导读:本篇文章编程笔记来给大家介绍有关如何搭建服务器环境php的相关内容,希望对大家有所帮助,一起来看看吧。本文目录一览:1、怎么搭建p ... [详细]
  • centos php部署到nginx 404_NodeJS项目部署到阿里云ECS服务器全程详解
    本文转载自:http:www.kovli.com20170919ecs-deploy作者:Kovli本文详细介绍如何部署NodeJS项目到阿里云ECS上, ... [详细]
  • 问题描述:域名已经备案,我全部都有,也在后台配置了,但是手机预览,还是请求失败,PC端是可以请求 ... [详细]
  • 1、概述首先和大家一起回顾一下Java消息服务,在我之前的博客《Java消息队列-JMS概述》中,我为大家分析了:然后在另一篇博客《Java消息队列-ActiveMq实战》中 ... [详细]
  • 原文链接:http:littleq.logdown.composts20131011kerl-to-manage-erlang-versions-on-your-system最近又回到 ... [详细]
author-avatar
往事如烟zhang_214
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有