A complete implementation of a transport requires that three classes
(such as the 'Grid' class below) be implemented from their respective
base class.
These transport classes are used by other classes within the
library, and should never be used directly by the user.
I interpreted this to mean that the base grid class would not be part
of the interface presented to the user either. Is this correct?
def initialize(transport)
@t = transport
@grid = @t.grid
@grid = @t.grid.new # alternative
end
Cus the way Robert saw it was that the transport should be the factory
for the grid, and the user will see the grid. The transport, which is
the factory for the grid, is fed to the object.
But the way I saw it was that the transport should be created by the
factory and so the user should see no grid at all. The factory
feeds the transport to the object.
We probably need more context. In an attempt to create a bigger example:
$ ./TrueGrit.rb
sending "basic message" across TheLibrary::JasonTransport
closing TheLibrary::JasonTransport
waiting for two weeks to transmit "basic message" via TheLibrary::CarrierPigeon
TheLibrary::CarrierPigeon is flying home
$ cat -n TrueGrit.rb
1 #!/bin/env ruby19
2
3 module TheLibrary
4
5 class BaseTransport
6 def self.open(*params)
7 grid = new(*params)
8
9 if block_given?
10 begin
11 yield grid
12 ensure
13 grid.close
14 end
15 else
16 grid
17 end
18 end
19 end
20
21 class JasonTransport < BaseTransport
22 def send(msg)
23 printf "sending %p across %p\n", msg, self.class
24 end
25
26 def close
27 printf "closing %p\n", self.class
28 end
29 end
30
31 class ThriftTransport < BaseTransport
32 def send(msg)
33 printf "sending %p across %p\n", msg, self.class
34 end
35
36 def close
37 printf "%p says, man I'm glad I get home\n", self.class
38 end
39 end
40
41 class CarrierPigeon < BaseTransport
42 def send(msg)
43 printf "waiting for two weeks to transmit %p via %p\n",
msg, self.class
44 end
45
46 def close
47 printf "%p is flying home\n", self.class
48 end
49 end
50
51 end
52
53 include TheLibrary;
54
55 JasonTransport.open(:host => "foo.bar.com") do |grid|
56 grid.send("basic message")
57 end
58
59 CarrierPigeon.open(:destination => "Stockholm") do |grid|
60 grid.send("basic message")
61 end
$
It really does not matter what method #new of the factory returns (or
whether it's called "new" at all). Basically one needs a defined
interface (note that I left some flexibility in there in order to be
able to provide different configurations depending on transport used).
Also, the approach with open is just an example how to do this in the
same manner as File and IO and other classes work which use a block
for safe resource deallocation.
Have I missed the point? More importantly, have you made the code win?
I'm not sure what "win" means in this context...
Kind regards
robert
···
On Tue, Apr 5, 2011 at 4:44 PM, Johnny Morrice <spoon@killersmurf.com> wrote:
On Tue, Apr 5, 2011 at 3:22 PM, Alex Rothbard <alex323@gmail.com> wrote:
On Tue, 5 Apr 2011 22:39:33 +0900 > Robert Klemme <shortcutter@googlemail.com> wrote:
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/