From: Robert Klemme Date: 2012-09-05T16:40:54+09:00 Subject: Re: Socket Decorator On Tue, Sep 4, 2012 at 7:53 PM, Bernhard Brodowsky wrote: > Robert Klemme wrote in post #1074648: >> On Tue, Sep 4, 2012 at 2:34 PM, Bernhard Brodowsky >> wrote: >>> Hi, I am implementing a special kind of socket that takes an io object >>> (usually a socket) as its argument and then behaves like a socket, but >>> does some transformations before/after it sends/receives, so in pseudo >>> code, it could look about like this: >> >>> But now I would like to implement the io interface like all those other >>> io classes, >> >> Why? I'd rather have a clean separation, i.e. you have a class [...] > My transformed socket can send arbitrary strings, so a client can send > anything he likes. The advantage of implementing the same interface as > the other IO classes is that my transformed socket can be reused in more > different ways and passed to other methods that take IO streams as > arguments, for example YAML::load(transformed_socket) might read yaml > directly from my transformed socket, which is not possible if I have a > different interface. Ah, I see. Basically you are defining a different message format across the wire but otherwise want to retain all the other functionality. I have two ideas for this: - look at how Ruby's SSL implementation does it - define a "default forwarding" like this: class Wrapper # maybe inherit BasicObject def initialize(socket) @socket = socket or raise "Invalid nil socket" end def write... def read... # other methods that either accept data to send or return data read def method_missing(*a, &b) __wrap__(@socket.send(*a, &b)) end private def __wrap__(obj) obj.equal?(@socket) ? self : obj end # variant def method_missing(*a, &b) __wrap__(@socket.send(*a) do |*x| b[*x.map! {|e| __wrap__(e)}] end) end end > Thanks a lot, I alredy switched to String#<< and String#slice!. The > message size sent through the internal socket is fixed, but from > outside, it appears like a normal IO stream, so a client may call gets, > but several internal messages may have to be read until a newline > character is found. Or read(n) may be called for n != block_size, so a > buffer is definitely necessary. I see. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/