我看书有个习惯,先看图和代码,然后代码中不懂的再去前后文去找说明,有人说这太浪费时间了,我觉得这样才0距离接触代码。Armstrong的代码看得我十分的不爽,可是,学erlang就是像受戒律一样,忍啊忍,悟啊悟,之后,如修炼得道般豁然开朗。
ok,废话少说,读programming erlang 读到 IRC Lite的时候发现在自己面前横着一道槛了。io_widget是什么?lib_chan是什么?mm是什么?太多东西复杂东西了呢。我下载来老头子的源代码,编译运行一下,看了下前面的说明,知道人与这个IRCLite交互的界面大概是什么样子的了,模仿着老头的代码边读练习写IRC Lite,看下我们的需求列表(我喜欢做一点事然后喘口气,把事情分成一小段一小段来做,完成一个小段,奖励下自己,比如喝口茶,需求列表也是我的备忘录,指导我下一步该做什么,它是不断变化,动态增长的一张表):
- 一个500×200的窗口
- 在这个窗口里面放入一个frame的布局2行1列,上面的作为历史记录显示框,下面的输入框
- 历史记录框是一个editor
- 输入框是一个entry
- 输入框有一个提示符
%%在io_widget应该封装好gs,所以应该这么写,
start(Pid)->
io_widget_init().
io_widget_init()->
GS = gs:start(),
Size = [{width,500,{height,200}],
Win = gs:window(Gs,
[{map,true},
{configure,true},
{title,"chat windows"}|Size]),
State=nil,
loop(Win,state).
loop(Win,State)->
receive
after 5000->
true
end.
编译运行一下
恩不错,顺心的开始是成功的一半。
再来看下我们的需求列表:
- 在这个窗口里面放入一个frame的布局2行1列,上面的作为历史记录显示框,下面的输入框
- 历史记录框是一个editor
- 输入框是一个entry
- 输入框有一个提示符
io_widget_init()->
GS = gs:start(),
Size = [{width,500,{height,200}],
Win = gs:window(Gs,
[{map,true},
{configure,true},
{title,"chat windows"}|Size]),
gs:config(IdOrName, Option).
%%Frame options:
%%{packer_x,PackList}
where PackList
is list() of PackOption
, and
%%{packer_y,PackList}
where PackList
is list() of PackOption
.
%%PackOption
is:
%%{stretch, Weight}
where Weight
is integer() > 0, or
%%{stretch, Weight, MinPixelSize, or}
%%{stretch, Weight, MinPixelSize, MaxPixelSize}, or
%%{fixed, PixelSize}
gs:frame(packer,Win,[{packer_x,[{stretch,1,500}]},
{packer_y,[{stretch,10,120,100},
{stretch,1,15,15}]}]),
%%这里我有个不明白的地方, {packer_y,[{stretch,10,120,100},为什么MinPixerlSize会比
%%MaxPixerlSize难道它们会自动交换?
%%gs:create(Obttype, Parent).
%%gs:create(Objtype, Parent, Options).
%%gs:create(Objtype, Parent, Option).
%%gs:create(Objtype, Name, Parent, Options).
%%gs:create(Objtype, Name, Parent, Option).
gs:create(editor,editor,packer,
[{pack_x,1},{pack_y,1},{vscroll,right}]),
gs:create(entry ,entry ,packer,
[{pack_x,1},{pack_y,2},{keypress,true}]),
gs:config(packer,Size),
State=nil,
loop(Win,state).
- 输入框有一个提示符
- 能用标题右边的红叉来关闭整个应用。
io_widget_init()->
GS = gs:start(),
Size = [{width,500,{height,200}],
Win = gs:window(Gs,
[{map,true},
{configure,true},
{title,"chat windows"}|Size]),
gs:frame(packer,Win,[{packer_x,[{stretch,1,500}]},
{packer_y,[{stretch,10,120,100},
{stretch,1,15,15}]}]),
gs:create(editor,editor,packer,
[{pack_x,1},{pack_y,1},{vscroll,right}]),
gs:create(entry ,entry ,packer,
[{pack_x,1},{pack_y,2},{keypress,true}]),
gs:config(packer,Size),
Prompt = ">",
gs:config(entry,{insert,{0,Prompt}}),
State=nil,
loop(Win,state).
ps:这里所有红色边框是因为截屏软件引起的,不要误解~:)
- 能用标题右边的红叉来关闭整个应用。
- 能接受从entry输入的文字信息。
- 把entry输入的文字信息显示在editor上面。
- 把entry输入在editor上显示的提示符去掉。
loop(Win,State)->
receive
{gs,_,destroy,_,_}->
io:format("Destroyed ~n ",[]),
exit(windowDestroyed)
end.
%%当这个循环接收到来自gs的窗口关闭信息的时候,作出退出整个应用的系统的反应。这里发出一个windowDestroy
%%的消亡信号,所以与这个loop进程相联系的进程都会收到这个信号。我们当前代码中与这个loop进程相关联的进程是
%%我们shell的进程。
- 能接受从entry输入的文字信息(在entry中输入文字,当按下enter键就接收一次entry中的数据)。
- 把entry输入的文字信息显示在editor上面。
- 把entry输入在editor上显示的提示符去掉。
- reset下entry
loop(Win,State)->
receive
{gs,entry,keypress,_,['Return'|_]}->
Text = gs:read(entry,text),
io:format("Read:~p ~n",[Text]),
loop(Win,State);
{gs,_,destroy,_,_}->
io:format("Destroyed ~n ",[]),
exit(windowDestroyed)
end.
- 把entry输入的文字信息显示在editor上面。
- 把entry输入在editor上显示的提示符去掉。
- reset下entry
widget(Gs)->
%%这里省略一段代码...
%%原先的gs:config(entry,{insert,{0,Prompt}}).删掉改成如下,算是DRY吧-_-!!!
reset_prompt(Prompt),
loop(Win,State,Prompt).
loop(Win,State,Prompt)->
receive
{gs,entry,keypress,_,['Return'|_]}->
Text = gs:read(entry,text),
Parse_Text = parse(Text),
io:format("Read:~p ~n",[Parse_Text]),
gs:config(entry,{delete,{0,last}}),
reset_prompt(Prompt),
loop(Win,State,Prompt);
{gs,_,destroy,_,_}->
io:format("Destroyed ~n ",[]),
exit(windowDestroyed)
end.
reset_prompt(Prompt)->
gs:config(entry,{insert,{0,Prompt}}).
parse([$>|T])->T;
parse([_|T])->parse(T);
parse([])->exit("no >").
- 把entry输入的文字信息显示在editor上面。
- 当editor中文字信息满掉的时候,能向下滚动。
loop(Win,State,Prompt)->
receive
{gs,entry,keypress,_,['Return'|_]}->
Text = gs:read(entry,text),
Parse_Text = parse(Text),
gs:config(editor,{insert,{'end',Parse_Text++"\n"}}),
%%这里我本想把最后收到信息放在最上面一行的,因为editor的默认vscrollpos一直定位在0的,把
%%最后收到的信息放在最后一行不能进行自动的滚动,想要查看还得使用滚动条,麻烦!
%%尝试过gs:config(editor,{insert,{'0',Parse_Text++"\n"}}),
%%gs:config(editor,{insert,{0,Parse_Text++"\n"}}),
%%gs:config(editor,{insert,{'begin',Parse_Text++"\n"}}),
%%都出错,gs的api上面也没写着!这里知道的朋友请告之下!
scroll_to_show_last_line(),
gs:config(entry,{delete,{0,last}}),
reset_prompt(Prompt),
loop(Win,State,Prompt);
{gs,_,destroy,_,_}->
io:format("Destroyed ~n ",[]),
exit(windowDestroyed)
end.
scroll_to_show_last_line()->
Size = gs:read(editor,size),
Height = gs:read(editor,height),
CharHeight = gs:read(editor,char_height),
TopRow = Size - Height/CharHeight,
if
TopRow >0 -> gs:config(editor,{vscrollpos,TopRow});
true -> gs:config(editor,{vscrollpos,0})
end.
- 大小: 7.4 KB
- 大小: 8.3 KB
- 大小: 2.8 KB
- 大小: 4 KB
- 大小: 2.9 KB
- 大小: 3.8 KB
- 大小: 3.3 KB
- 大小: 10 KB
分享到:
相关推荐
### 1. 函数式编程基础 Erlang基于函数式编程范式,这意味着程序由纯函数构成,没有副作用。函数式编程强调数据不可变性和函数的数学属性,使代码更易于理解、测试和并行处理。 ### 2. 并发与轻量级进程 Erlang的...
5. **模式匹配**:Erlang的函数定义允许模式匹配,使得代码更加简洁和可读。书中可能会详细解释这一特性及其在并发编程中的应用。 6. **并行算法**:书中可能包含实例,演示如何使用Erlang实现高效的并行算法,提升...
1. **下载**:首先,访问Erlang官方网站或者通过第三方源下载`otp_win64_25.0.exe`文件。 2. **安装**:双击下载的文件启动安装向导,按照提示进行操作。默认设置通常足够,但你可以根据需要自定义安装路径和其他...
1. **解压源码**:将otp_src_24.3.4.4文件解压缩到一个合适的目录,通常是在你的开发环境中。 2. **环境配置**:确保你的系统中安装了必要的编译工具,如GCC或Clang,以及Make。对于Windows用户,可能需要安装MSYS2...
Erlang/OTP 26.2.1,Erlang,OTP,26.2.1
1. **下载**:你可以从Erlang Solutions官网或者通过提供的压缩包文件"Erlang 20.3linux░▓╫░░ⁿ"和"Erlang 20.3linux安装包"下载Erlang的Linux二进制包。 2. **解压**:解压缩下载的文件到一个合适的目录,...
1. **语言增强**:Erlang22可能引入了新的语言特性,如更丰富的语法支持或者对现有特性的优化,以便提高开发效率和代码的可读性。 2. **性能提升**:新版本通常会针对CPU使用率、内存管理或垃圾回收进行优化,从而...
erlang安装包
Erlang:RabbitMQ 是用 Erlang 编写的,因此需要 Erlang 运行时。确保安装了兼容的 Erlang 版本;Erlang:RabbitMQ 是用 Erlang 编写的,因此需要 Erlang 运行时。确保安装了兼容的 Erlang 版本;Erlang:RabbitMQ ...
1. **版本号**:22.3-1表示这是Erlang的一个特定版本,22.3是主版本号和次版本号,而-1可能代表修订或更新次数。 2. **操作系统兼容性**:el7表明这个版本的Erlang是针对Red Hat Enterprise Linux 7 (RHEL 7)或其...
1. **函数式编程**:Erlang基于函数式编程范式,强调无副作用的纯函数,以及通过数据不可变性来简化并发处理。在Erlang中,程序是由一系列相互独立的函数构成的,它们可以并行执行,提高了系统的性能。 2. **并发与...
1. 检查网络连接:确保网络稳定且速度足够。 2. 使用代理:如果你在公司或特定区域,可能需要通过代理服务器访问外部资源。 3. 更换下载时间:避开网络高峰期进行下载。 4. 镜像站点:寻找Erlang的镜像站点,这些...
标题中的"erlang-23.2.3-1.el7.x86_64.rpm"和"erlang-23.2.1-1.el7.x86_64.rpm.rar"代表了两个不同的Erlang版本。`.rpm`文件是用于Red Hat Enterprise Linux (RHEL) 和其衍生发行版如CentOS的软件包管理格式,而`....
Erlang是一种高级编程语言,特别适用于并发、分布式和实时计算系统。它的设计目标是创建一个高可用性、容错性强、低延迟的系统。Erlang9指的是Erlang/OTP(Open Telephony Platform)的第9个主要版本。OTP是Erlang...
1. **语法高亮**:Erlang的语法特性被准确地识别和突出显示,使得代码更易读,减少错误的可能性。 2. **代码自动完成**:智能感知功能能根据输入的字符自动提供可能的函数或变量名,节省了大量键入时间。 3. **错误...
erlang otp25 win安装包
1. **Erlang语言基础**:Erlang是瑞典电信设备制造商Ericsson为解决实时通信系统需求而开发的。它采用函数式编程范式,强调纯函数和不可变数据,以及模式匹配和递归等特性。编程+Erlang.pdf可能会详细介绍Erlang的...
Erlang B和Erlang C是电信领域中两种重要的流量模型,用于预测和分析通信系统中的呼叫处理能力和拥塞情况。这两个模型由丹麦工程师Agner Krarup Erlang在20世纪初提出,至今仍广泛应用于现代通信网络的设计与优化。 ...
Erlang是一种面向并发的、函数式编程语言,由瑞典电信设备制造商Ericsson开发,用于构建高可用性、分布式和实时系统。OTP(Open Telecom Platform)是与Erlang一起使用的框架和库,旨在简化并发应用程序的设计和维护...
【Erlang程序设计(第2版)】是由Erlang之父Joe Armstrong撰写的一本经典著作,专注于介绍Erlang编程语言在并发、分布式和容错系统中的应用。本书适用于初学者和有一定经验的Erlang程序员。作者在书中讨论了如何利用...