Hi folks,
My understanding of proper Ruby and duck-typing idoms is still pretty raw, so I
decided to ask you folks for help.
I’m making a binding to libpcap and libnet for Ruby, which will allow you to do
non-time-critical network traffic analysis in Ruby. Part of my design was that
Packet representations will “mix in” their protocols. For instance, a packet
could be of many different protocols, but still be an IP packet (TCP, UDP,
custom protocol). Likewise, a packet could be a TCP or UDP packet, but not be
transmitted via IP. To me, this seems to be an ideal case for mix-ins.
However, this brings up the problem. Sometimes, people will want to know what
kind of packet a relatively broad filter is spitting back. Is it TCP or UDP? Is
it IP or ICMP? My first instinct was to just let them check the inclusion
history. However, recent reading has revealed to me that relying on the class
and inheritance hierarchy is not the best way to go about doing things in Ruby,
since things are so dynamic.
What then is the right way to let users of the library I am writing check packet
type? A method to include symbols seems to me to be a duplication of
information, which should be avoided. I suppose is_tcp? and is_ip? would be
viable, but seems inelegant to me.
Am I just being picky, or what? Any suggestions are welcome. Thanks for your
time!
···
something like this would allow the various mixins (like TCP) to ‘inherit’ (via
extend) methods from a ‘parent’ module (Protocol) and also allow packets to be
‘wrapped’ in successive protocols in such a way that the type would be
affected correctly. eg:
----CUT----
class Packet < String
attr :protocol_stack
def initialize data
@protocol_stack =
end
def type
@protocol_stack
end
def wrap(*protocols)
protocols.map{|protocol| self.extend protocol}
end
end
module Protocol
def extend_object packet
raise unless Packet === packet
packet.protocol_stack << self
end
end
module IP; extend Protocol; end
module TCP; extend Protocol; end
module UDP; extend Protocol; end
a, b, c = %w(a b c).map{|data| Packet.new data}
a.wrap TCP, IP
b.wrap TCP, IP
c.wrap UDP, IP
p a.type # → [TCP, IP]
p b.type # → [TCP, IP]
p c.type # → [UCP, IP]
p a.type == b.type # → true
p b.type == c.type # → false
p c.type == a.type # → false
----CUT----
-a
···
On Thu, 28 Aug 2003, Dave Fayram wrote:
Hi folks,
My understanding of proper Ruby and duck-typing idoms is still pretty raw, so I
decided to ask you folks for help.
I’m making a binding to libpcap and libnet for Ruby, which will allow you to do
non-time-critical network traffic analysis in Ruby. Part of my design was that
Packet representations will “mix in” their protocols. For instance, a packet
could be of many different protocols, but still be an IP packet (TCP, UDP,
custom protocol). Likewise, a packet could be a TCP or UDP packet, but not be
transmitted via IP. To me, this seems to be an ideal case for mix-ins.
However, this brings up the problem. Sometimes, people will want to know what
kind of packet a relatively broad filter is spitting back. Is it TCP or UDP? Is
it IP or ICMP? My first instinct was to just let them check the inclusion
history. However, recent reading has revealed to me that relying on the class
and inheritance hierarchy is not the best way to go about doing things in Ruby,
since things are so dynamic.
What then is the right way to let users of the library I am writing check packet
type? A method to include symbols seems to me to be a duplication of
information, which should be avoided. I suppose is_tcp? and is_ip? would be
viable, but seems inelegant to me.
Am I just being picky, or what? Any suggestions are welcome. Thanks for your
time!
====================================
Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ara.t.howard@noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
~ > ruby -e ‘p(%.\x2d\x29…intern)’
====================================