文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档> An Erlang Port in Python

An Erlang Port in Python

时间:2009-07-23  来源:pascal4123

Recipe 534162: An Erlang Port in Python

Erlang has two built-in interoperability mechanisms. One is distributed Erlang nodes and the other one is ports. Ports provide the basic Erlang mechanism for communication with the external world. They provide a byte-oriented interface to an external program. When a port has been created, Erlang can communicate with it by sending and receiving lists of bytes. This recipe cooks an Erlang port in python. Making it easy for Erlang to instantiate and use python objects. Like most simple port implementations it uses an external python program and lets Erlang communicate via standard input and write to standard output. Theoretically, the external program could be written in any programming language. This recipe is pretty abstract and you will have to implement your own encode and decoding scheme.


Python
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import sys, os, struct, traceback
from cStringIO import StringIO

class ErlangPort(object):
PACK = '!h'
def __init__(self):
self._in = sys.stdin
self._out = sys.stdout

def recv(self):
buf = self._in.read(2)
if len(buf) ==2:
(sz,) = struct.unpack(self.PACK, buf)
return self._in.read(sz)

def send(self, what):
sz = len(what)
buf = struct.pack(self.PACK, sz)
self._out.write(buf)
return self._out.write(what)

def run(self):
buf = self.recv()
while buf:
try:
result = self.process(buf)
except:
result = traceback.format_exc()
self.send(result)
buf = self.recv()

class ErlangPortTest(ErlangPort):
cmds = (0,lambda x: x+2, lambda x: x*2)
def process(self, message):
fn,arg = struct.unpack('!BB', message)
res = self.cmds[fn](arg)
return struct.pack('!B', res)

class ErlangPyTest(ErlangPortTest):
class SandBox:
def process(self, message):
exec message
sandbox = SandBox()
def process(self, code):
try:
realout = sys.stdout
sys.stdout = StringIO()
self.sandbox.process(code)
result = sys.stdout.getvalue()
finally:
if sys.stdout: sys.stdout.close()
if realout: sys.stdout = realout
return result

if __name__ =='__main__':
import sys
try:
command = sys.argv[1]
if command == 'PortTest':
ErlangPortTest().run()
elif command =='pytest':
ErlangPyTest().run()
except IndexError:
print """
Usage:
First of all see the c Port section in the Erlang guide.
http://www.erlang.org/doc/tutorial/c_port.html#4

1. Start Erlang and compile the Erlang user guide example code:
http://www.erlang.org/doc/tutorial/complex1.erl

unix> erl
Erlang (BEAM) emulator version 4.9.1.2

Eshell V4.9.1.2 (abort with ^G)
1> c(complex1).
{ok,complex1}

3. Run the example.
2> complex1:start("python -u port.py PortTest").
<0.34.0>
3> complex1:foo(3).
4
4> complex1:bar(5).
10
5> complex1:stop().
stop

For more fun try.

6> c("c:\\tg\\python.erl").
:/tg/python.erl:42: Warning: variable 'Reason' is unused
{ok,python}
7> python:start("c:\\python25\\python.exe -u c:\\tg\\port.py pytest").
<0.38.0>
8> python:exec("import os")
9> python:exec("self.x = os.environ['PATH']").
* 2: syntax error before: python **
10> python:exec("import os").
[]
11> python:exec("self.x = os.environ['PATH']").
[]
12> python:exec("print self.x").
"H:\\PROGRA~1\\ERL55~1.5\\ERTS-5~1.5\\bin;H:\\PROGRA~1\\ERL55~1.5\\bin
m Files\\ActivePositionManager\\;C:\\WINNT\\system32;C:\\WINNT;C:\\WI
32\\Wbem;"
"""
相关阅读 更多 +
排行榜 更多 +
找茬脑洞的世界安卓版

找茬脑洞的世界安卓版

休闲益智 下载
滑板英雄跑酷2手游

滑板英雄跑酷2手游

休闲益智 下载
披萨对对看下载

披萨对对看下载

休闲益智 下载