No attempt has been made to customize the API to the idioms of the respective scripting languages. This allows you to use the C++ API documentation for all environments. However, a few differences are forced upon the API by the languages. See the unit tests in tests/swig/lua, tests/swig/perl, tests/swig/python, and tests/swig/ruby for usage examples.
#include <sava/spread.h> becomes require("sava.spread")sava::spread::BaseMessage::SelfDiscard becomes sava.spread.BaseMessage_SelfDiscard.sava.spread.BaseMessage_SelfDiscard instead of sava.spread.Message_SelfDiscardsava::spread::BaseMessage::Reliable | sava::spread::BaseMessage::SelfDiscard use sava.spread.BaseMessage_ReliableSelfDiscard.pcall. For example, the Lua unit tests do the following:
function test_error()
local succeeded, message = pcall(mbox.join, mbox, "####");
assert(not succeeded)
end
#include <sava/spread.h> becomes use sava::spread;$sava::spread::BaseMessage::SelfDiscard instead of $sava::spread::Message::SelfDiscardeval, which makes the exception available via the $@ special variable. For example, the Perl unit tests do the following:
sub test_error {
eval { $mbox->join("####"); };
is($@->error(), $sava::spread::Error::IllegalGroup);
}
#include <sava/spread.h> becomes import sava.spread#include <sava/spread.h> becomes require 'sava/spread'
private_name, proc_name = sava.spread.split_private_group("#foo#bar")
private_name == "foo" # This expression evaluates to True
proc_name == "bar" # This expression evaluates to True
In Lua split_private_group() returns a C++-style pair with .first and .second members, just like the C++ API.
g1 = sava.spread.GroupList()
g2 = sava.spread.GroupList()
g1.add("foo")
g2.copy(g1)
g2.group(0) == "foo" # This expression evaluates to True.
m = sava.spread.Message()
m.write("foobar")
m.rewind()
s = m.read(m.size())
"foobar" == s # This expression evaluates to True.
readn and writen. Note, that readn is dangerous (e.g., strings are supposed to be immutable in Python) and should be avoided unless you know exactly what you're doing.In order to specify a connection timeout, you may use the Timeout class or you may specify a timeout in seconds with a single integer. For example, to specify a connection timeout of 3 seconds in Python, you could use:
mbox = sava.spread.Mailbox("4803@localhost", "", True, sava.spread.Timeout(3)); or:
mbox = sava.spread.Mailbox("4803@localhost", "", True, 3);
You can't access the contents of a Message directly via &Message[0] as in C++. Instead, you always have to read and write the contents using Message::read and Message::write. Because messages are treated as strings in the script environment, your data shouldn't contain null/0 characters. For example, if you write two strings to a message in a row and read them back into one string, you'll find that the result is treated as only the first string because of the null termination. For example:
m = sava.spread.Message()
m.write("foo")
m.write("bar")
m.rewind()
s = m.read(m.size())
"foo" == s # This expression evaluates to True.
"foobar" == s # This expression evaluates to False.
m.rewind()
s1 = m.read(4)
s2 = m.read(4)
"foo" == s1 # This expression evaluates to True.
"bar" == s2 # This expression evaluates to True.
As long as you use the script environment's object serialization mechanisms, you shouldn't run into any problems in this regard.Don't add raw data parts (things that are not of type Message) to ScatterMessage::add or Mailbox::add_message_part if they will be garbage-collected before a send. For example:
s = "foo" mbox.add_message_part(s) s = None # Don't do this before the send or you may segfault! mbox.send()