热门标签 | 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游戏开发



推荐阅读
  • 本指南详细介绍了在Linux环境中高效连接MySQL数据库的方法。用户可以通过安装并使用`mysql`客户端工具来实现本地连接,具体命令为:`mysql -u 用户名 -p 密码 -h 主机`。例如,使用管理员账户连接本地MySQL服务器的命令为:`mysql -u root -p pass`。此外,还提供了多种配置优化建议,以确保连接过程更加稳定和高效。 ... [详细]
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • 深入解析 Lifecycle 的实现原理
    本文将详细介绍 Android Jetpack 中 Lifecycle 组件的实现原理,帮助开发者更好地理解和使用 Lifecycle,避免常见的内存泄漏问题。 ... [详细]
  • 大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式
    大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式 ... [详细]
  • 在PHP中如何正确调用JavaScript变量及定义PHP变量的方法详解 ... [详细]
  • DVWA学习笔记系列:深入理解CSRF攻击机制
    DVWA学习笔记系列:深入理解CSRF攻击机制 ... [详细]
  • Netty框架中运用Protobuf实现高效通信协议
    在Netty框架中,通过引入Protobuf来实现高效的通信协议。为了使用Protobuf,需要先准备好环境,包括下载并安装Protobuf的代码生成器`protoc`以及相应的源码包。具体资源可从官方下载页面获取,确保版本兼容性以充分发挥其性能优势。此外,配置好开发环境后,可以通过定义`.proto`文件来自动生成Java类,从而简化数据序列化和反序列化的操作,提高通信效率。 ... [详细]
  • 兆芯X86 CPU架构的演进与现状(国产CPU系列)
    本文详细介绍了兆芯X86 CPU架构的发展历程,从公司成立背景到关键技术授权,再到具体芯片架构的演进,全面解析了兆芯在国产CPU领域的贡献与挑战。 ... [详细]
  • 在List和Set集合中存储Object类型的数据元素 ... [详细]
  • 在 CentOS 7 系统中安装 Scrapy 时遇到了一些挑战。尽管 Scrapy 在 Ubuntu 上安装简便,但在 CentOS 7 上需要额外的配置和步骤。本文总结了常见问题及其解决方案,帮助用户顺利安装并使用 Scrapy 进行网络爬虫开发。 ... [详细]
  • Python 程序转换为 EXE 文件:详细解析 .py 脚本打包成独立可执行文件的方法与技巧
    在开发了几个简单的爬虫 Python 程序后,我决定将其封装成独立的可执行文件以便于分发和使用。为了实现这一目标,首先需要解决的是如何将 Python 脚本转换为 EXE 文件。在这个过程中,我选择了 Qt 作为 GUI 框架,因为之前对此并不熟悉,希望通过这个项目进一步学习和掌握 Qt 的基本用法。本文将详细介绍从 .py 脚本到 EXE 文件的整个过程,包括所需工具、具体步骤以及常见问题的解决方案。 ... [详细]
  • CSS3 @font-face 字体应用技术解析与实践
    在Web前端开发中,HTML教程和CSS3的结合使得网页设计更加多样化。长期以来,Web设计师受限于“web-safe”字体的选择。然而,CSS3中的`@font-face`规则允许从服务器端加载自定义字体,极大地丰富了网页的视觉效果。通过这一技术,设计师可以自由选择和使用各种字体,提升用户体验和页面美观度。本文将深入解析`@font-face`的实现原理,并提供实际应用案例,帮助开发者更好地掌握这一强大工具。 ... [详细]
  • 在重新安装Ubuntu并配置Django和PyCharm后,忘记测试MySQL连接,导致在后续配置过程中遇到错误:ERROR 2003 (HY000) - 无法连接到本地服务器 ‘127.0.0.1’ (111)。本文将详细介绍该错误的原因及解决步骤,帮助用户快速恢复MySQL服务的正常运行。我们将从检查网络配置、验证MySQL服务状态、配置防火墙规则等方面入手,提供全面的故障排除指南。 ... [详细]
  • 本文详细介绍了使用 Python 进行 MySQL 和 Redis 数据库操作的实战技巧。首先,针对 MySQL 数据库,通过 `pymysql` 模块展示了如何连接和操作数据库,包括建立连接、执行查询和更新等常见操作。接着,文章深入探讨了 Redis 的基本命令和高级功能,如键值存储、列表操作和事务处理。此外,还提供了多个实际案例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 在使用 `requests` 库进行 HTTP 请求时,如果遇到 `requests.exceptions.SSLError: HTTPSConnectionPool` 错误,通常是因为 SSL 证书验证失败。解决这一问题的方法包括:检查目标网站的 SSL 证书是否有效、更新本地的 CA 证书库、禁用 SSL 验证(不推荐用于生产环境)或使用自定义的 SSL 上下文。此外,确保 `requests` 库和相关依赖项已更新到最新版本,以避免潜在的安全漏洞。 ... [详细]
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社区 版权所有