Archive

Archive for April, 2009

[荐]talk to erlang in ruby with Erlix

April 29th, 2009 :: jackyz

KDr2(Killy Draw)同学做了一个 Ruby – Erlang 的项目 Erlix 。象这种富有新意(Talk to Erlang as A Node 而不是 as A Port, Like erlectricity)的民族软件(KDr2 Speaks Chinese),而且文档也比较完整,实在是找不出不大力进行推荐的理由。

项目主页:http://code.google.com/p/erlix/ || http://github.com/KDr2/erlix/

代码下载:http://erlix.googlecode.com/files/erlix-0.2.zip

使用教程:http://code.google.com/p/erlix/wiki/ErlixTutorial

另外,还有买一赠一惊喜大特惠!这里再推荐一篇通过 Erlang Node 机制进行通讯的原理性文章(刚巧也是 Ruby 的),如果想要实现一个自己的 Talk to Erlang as A Node in xxx Language (貌似好几个语言都已经有了自己的版本,大家动手之前,先 google 一下,看看别人做了没有),相信这一篇 [ 点这里 ] 也会很有参考价值。

news

[荐]Erlang的Unicode支持

April 10th, 2009 :: jackyz

勤奋的 litaocheng 同学,在每日超负荷的加班工作之余,仍然刻苦学习笔耕不辍,为我们不断带来劲爆文章,这一篇《Erlang的Unicode支持》为我们介绍了 R13 的最新特性,也是最被大家期望的特性——内置的 Unicode 支持。废话少说,直接上正文。

在R13A中, Erlang加入了对Unicode的支持。本文涉及到的数据类型包括:list, binary, 涉及到的模块包括stdlib/unicode, stdlib/io, kernel/file。

Binary

Binary的type属性增加了utf相关的type:utf8, utf16, utf32,其分别对应UTF8, UTF16,UTF32编码。

Binary Constructing

在Binary构建时, 如果指定了utf相关类型,那么对应的integer的Value必须位于:0..16#D7FF, 16#E000..16#FFFD, 或者 16#10000..16#10FFFF这三个区间中。否则将会提示’bad argument’,参数错误。根据指定的的utf类型不同,同一个数据产生的binary不同。

对于utf8,每个integer生成1到4个字符;对于utf16,每个integer生成2或4个字符;对于utf32,每个integer生成4个字符。

比如, 使用unicode为1024的字符A, 构建一个binary:

1> <<1024/utf8>>.   
<<208,128>>
2> <<1024/utf16>>.
<<4,0>>
3> <<1024/utf32>>.
<<0,0,4,0>>

Binary Match

当进行Binary Match时,如果指定utf相关类型,变量成功匹配后,将拥有一个位于:0..16#D7FF, 16#E000..16#FFFD, 或者 16#10000..16#10FFFF这三个区间中的integer。

其更具utf类型的不同,消耗(match)不同数目的bytes。

  • utf8匹配1-4个bytes(参考RFC-2279)
  • utf16匹配2 或 4 个bytes (参考 RFC-2781)
  • utf32匹配4个 bytes

比如:继续我们上面的例子

4> Bin = <<1024/utf8>>.
<<208,128>>
5> <<U/utf8>> = Bin.
<<208,128>>
6> U.
1024

这个例子中,U匹配了2个bytes。对于utf相关类型,不能指定unit spec。

List

在list中,每个unicode字符采用integer来表示,因此与latin1的list相比,unicode list中,element的数值可以大于255。下面就是一个有效的unicode list: [1024, 1025]

我们可以通过unicode 模块实现 list到binary的转换。

unicode module

首先请参看下面的type定义:

unicode_binary() = binary() with characters encoded in UTF-8 coding standard
unicode_char() = integer() representing valid unicode codepoint
chardata() = charlist() | unicode_binary()
charlist() = [unicode_char() | unicode_binary() | charlist()]
a unicode_binary is allowed as the tail of the list

external_unicode_binary() = binary() with characters coded in a user specified Unicode encoding other than UTF-8 (UTF-16 or UTF-32)
external_chardata() = external_charlist() | external_unicode_binary()
external_charlist() = [unicode_char() | external_unicode_binary() | external_charlist()]
an external_unicode_binary is allowed as the tail of the list

latin1_binary() = binary() with characters coded in iso-latin-1
latin1_char() = integer() representing valid latin1 character (0-255)
latin1_chardata() = latin1_charlist() | latin1_binary()
latin1_charlist() = [latin1_char() | latin1_binary() | latin1_charlist()]
a latin1_binary is allowed as the tail of the list

我们可以调用unicode:characters_to_list/1 将chardata或latin1_chardata或external_chardata()转化成一个unicode list。

如果参数为latin1_chardata,那么Data参数就是一个iodata. 返回的结果list中,每个element为一个integer。默认情况 unicode:characters_to_list/1调用unicode:characters_to_list(Data, unicode)

如果我们的CharData为其他类型,我们可以指明InEncoding type。如果此函数执行成功,返回{ok, List},如果失败返回{error, list(), RestData}, 其中list为转化成功的部分,RestData为发生错误的位置。

我们也可以调用unicode:characters_to_binary/1,将chardata或latin1_chardata或 external_chardata()转化成一个binary。这个函数和unicode:characters_to_list类似,只是结果保存为 binary。

如果Data为latin1_chardata, 那么unicode:characters_to_binary/1和 erlang:iolist_to_binary/1功能相同

unicode模块中,还有两个于bom相关的函数,可以根据bom指返回对应的encoding类型,也可以根据encoding类型生成对应的bom值。其在保存文件时,经常使用.

Examples

1, 打开utf8保存的文件

文件内容如下test.file:

[
desc, "这是一个测试文件"},
{
author, "litaocheng"}
].

其格式为erlang term,保存时选择utf8编码。
代码如下:

  1. %% read content from the file
  2. test1() ->
  3.     {ok, [Terms]} = file:consult("test.txt"),
  4.     Desc = proplists:get_value(desc, Terms),
  5.     _Author = proplists:get_value(author, Terms),
  6.    
  7.     % out put the Desc and Author
  8.     DescUniBin = iolist_to_binary(Desc),
  9.     DescUniList = unicode:characters_to_list(DescUniBin),
  10.     io:format("desc bin : ~ts~ndesc bin : ~p~n",[DescUniBin, DescUniBin]),
  11.     io:format("desc list: ~ts~ndesc list: ~p~n", [DescUniList, DescUniList]).

结果:

desc bin : 这是一个测试文件
desc bin : <<232,191,153,230,152,175,228,184,128,228,184,170,230,181,139,232,
             175,149,230,150,135,228,187,182>>
desc list: 这是一个测试文件
desc list: [36825,26159,19968,20010,27979,35797,25991,20214]

首先将内容从list转换为binary, DescUniBin 便是对应的unicode binary。随后通过unicode:characters_to_list/1转化为unicode list最后输出。
我们可以看到 unicode list中所有的element为integer, unicode binary中unicode string采用uft8编码。

2, 将数据保存成uft8格式

  1. %% save the binary in utf8 format
  2. test2() ->
  3.     [DescList] = io_lib:format("~ts", ["这是一个测试文件"]),
  4.     DescBin = erlang:iolist_to_binary(DescList),
  5.     DescList2 = unicode:characters_to_list(DescBin),
  6.     List = lists:concat(["[{desc,\"", DescList2, "\"}, {author, \"litaocheng\"}]."]),
  7.     Bin = unicode:characters_to_binary(List),
  8.     io:format("bin is:~ts~n", [Bin]),
  9.     file:write_file("test_out.txt", Bin).

这个例子的完整代码如下:

  1. -module(unicode_test).
  2. -compile([export_all]).
  3.  
  4. %%
  5. %% the test.txt content:
  6. %% [
  7. %% {desc, "这是一个测试文件"},
  8. %% {author, "litaocheng"}
  9. %% ].
  10. %%
  11.  
  12. test() ->
  13.     test2(),
  14.     test1().
  15.  
  16. %% read content from the file
  17. test1() ->
  18.     {ok, [Term]} = file:consult("test_out.txt"),
  19.     Desc = proplists:get_value(desc, Term),
  20.     _Author = proplists:get_value(author, Term),
  21.    
  22.     % out put the Desc and Author
  23.     DescUniBin = iolist_to_binary(Desc),
  24.     DescUniList = unicode:characters_to_list(DescUniBin),
  25.     io:format("desc bin : ~ts~ndesc bin : ~p~n",[DescUniBin, DescUniBin]),
  26.     io:format("desc list: ~ts~ndesc list: ~p~n", [DescUniList, DescUniList]).
  27.  
  28.  
  29. %% save the binary in utf8 format
  30. test2() ->
  31.     [DescList] = io_lib:format("~ts", ["这是一个测试文件"]),
  32.     DescBin = erlang:iolist_to_binary(DescList),
  33.     DescList2 = unicode:characters_to_list(DescBin),
  34.     List = lists:concat(["[{desc,\"", DescList2, "\"}, {author, \"litaocheng\"}]."]),
  35.     Bin = unicode:characters_to_binary(List),
  36.     io:format("bin is:~ts~n", [Bin]),
  37.     file:write_file("test_out.txt", Bin).

misc

[荐]平行處理概觀

April 7th, 2009 :: jackyz

这篇发表于 ZDNet tw 站上的《Programming for Parallelism》,是 Intel 赞助的内容,虽说有广告嫌疑,而且通篇都是读起来让人亲切之余还有些吃力的 “正体中文” (幸好初中读过一本繁体竖排版的《封神榜》打了点基础),而且满眼尽是晕乎乎的台式技术术语(幸好大学读过一本繁体横排版的《组合语言程式设计》,注: “组合语言” == “汇编” ,又打了点基础)。但是内容确实没得说,相当之有料!清晰简明,三两句就把原来觉得神秘兮兮的东西讲明白了——保持了海峡对岸兄弟们技术文章的一贯高水准。我是一口气读完了,大呼过瘾,如果你也能够耐着性子读完,肯定会很有收获。

“并行编程 (Parallel Programming)” 和 “并发编程 (Concurrent Programming)” 是一码事么?如果不是,那它们之间到底有什么区别呢?

这个问题,在看完这篇文章之前,我还真回答不上来。因为,确实不了解,我也知道 OpenMP、MPI 这些被当作是并行编程的 “必杀密技” 必须要去了解一下,但我一听见这些强烈 C 风格的东西就私底下直犯触,老是没法鼓起勇气(和兴趣)去研究它们。这下好了,这篇文章以极其精炼的语言和高度抽象的视角(主要是这个,老实说,我对细节还真的不是很感兴趣),把这些 “难点” 一下子都讲明白了。

以我不求甚解的标准来看,“并行编程 (Parallel Programming)” 在抽象方法上的:优先考虑并行、大量制造任务、限制锁的使用。以及基础设施中的:基本的可并行算法和数据结构、互斥、计时、任务计划、MPI 的消息传递机制,等等。其实和强调 “并发编程 (Concurrent Programming)” 的 Erlang 在概念上基本 “略同” 。所不同的是,这些设施大多都是为 C 系语言准备的,号召广大 C 程序员向并发 “靠拢” ,而 Erlang 则是彻底决裂,自己搞了一个语言出来(把这些具体的实现细节隐藏在虚拟机里面)。

又长知识了,感谢方块兄的投递,感谢 INET6 的推荐。

misc

关于 Erlang in JVM 的讨论

April 4th, 2009 :: jackyz

貌似最近 Erlang4J 又被很多人炒(吵)起来。似乎隔不了多久,社区中的一部分,就要被这类话题给搅和一番。为此 Hypothetical LabsKevin 同学发了一篇火力十足的猛文,相当精彩,也没有被墙,就不转载了,请到[这里]欣赏。

通常,这种火力十足的帖子都会引发围观,在 Erlang 的邮件列表,这种事情也已经发生过好几起了,实在不足为奇。这里罗嗦的一点观战提示是:跟帖质量相当之高,同样值得一读。

misc