bunny 0.7.13 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. data/.gitignore +2 -2
  2. data/.travis.yml +7 -16
  3. data/CHANGELOG +3 -21
  4. data/Gemfile +2 -4
  5. data/README.textile +31 -9
  6. data/Rakefile +3 -3
  7. data/bunny.gemspec +6 -3
  8. data/examples/{simple_08.rb → simple.rb} +1 -1
  9. data/examples/{simple_ack_08.rb → simple_ack.rb} +1 -1
  10. data/examples/{simple_consumer_08.rb → simple_consumer.rb} +4 -4
  11. data/examples/{simple_fanout_08.rb → simple_fanout.rb} +1 -1
  12. data/examples/{simple_headers_08.rb → simple_headers.rb} +2 -2
  13. data/examples/{simple_publisher_09.rb → simple_publisher.rb} +1 -1
  14. data/examples/{simple_topic_09.rb → simple_topic.rb} +2 -2
  15. data/ext/amqp-0.9.1.json +1 -0
  16. data/ext/config.yml +3 -3
  17. data/ext/qparser.rb +9 -52
  18. data/lib/bunny/{client09.rb → client.rb} +34 -46
  19. data/lib/bunny/{exchange09.rb → exchange.rb} +16 -15
  20. data/lib/bunny/{queue09.rb → queue.rb} +26 -23
  21. data/lib/bunny/{subscription09.rb → subscription.rb} +11 -6
  22. data/lib/bunny/version.rb +1 -1
  23. data/lib/bunny.rb +15 -33
  24. data/lib/qrack/client.rb +31 -22
  25. data/lib/qrack/protocol/{protocol08.rb → protocol.rb} +2 -1
  26. data/lib/qrack/protocol/{spec09.rb → spec.rb} +8 -7
  27. data/lib/qrack/{qrack08.rb → qrack.rb} +4 -4
  28. data/lib/qrack/subscription.rb +58 -9
  29. data/lib/qrack/transport/{buffer08.rb → buffer.rb} +9 -1
  30. data/lib/qrack/transport/{frame08.rb → frame.rb} +7 -22
  31. data/spec/spec_09/amqp_url_spec.rb +1 -1
  32. data/spec/spec_09/bunny_spec.rb +11 -9
  33. data/spec/spec_09/connection_spec.rb +9 -4
  34. data/spec/spec_09/exchange_spec.rb +23 -25
  35. data/spec/spec_09/queue_spec.rb +33 -19
  36. metadata +71 -81
  37. checksums.yaml +0 -7
  38. data/examples/simple_09.rb +0 -32
  39. data/examples/simple_ack_09.rb +0 -35
  40. data/examples/simple_consumer_09.rb +0 -55
  41. data/examples/simple_fanout_09.rb +0 -41
  42. data/examples/simple_headers_09.rb +0 -42
  43. data/examples/simple_publisher_08.rb +0 -29
  44. data/examples/simple_topic_08.rb +0 -61
  45. data/ext/amqp-0.8.json +0 -616
  46. data/lib/bunny/channel09.rb +0 -39
  47. data/lib/bunny/client08.rb +0 -480
  48. data/lib/bunny/exchange08.rb +0 -177
  49. data/lib/bunny/queue08.rb +0 -403
  50. data/lib/bunny/subscription08.rb +0 -87
  51. data/lib/qrack/protocol/protocol09.rb +0 -135
  52. data/lib/qrack/protocol/spec08.rb +0 -828
  53. data/lib/qrack/qrack09.rb +0 -20
  54. data/lib/qrack/transport/buffer09.rb +0 -305
  55. data/lib/qrack/transport/frame09.rb +0 -97
  56. data/spec/spec_08/bunny_spec.rb +0 -75
  57. data/spec/spec_08/connection_spec.rb +0 -24
  58. data/spec/spec_08/exchange_spec.rb +0 -175
  59. data/spec/spec_08/queue_spec.rb +0 -239
  60. data/spec/spec_helper.rb +0 -8
  61. /data/lib/bunny/{channel08.rb → channel.rb} +0 -0
data/lib/bunny/queue08.rb DELETED
@@ -1,403 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Bunny
4
-
5
- =begin rdoc
6
-
7
- === DESCRIPTION:
8
-
9
- Queues store and forward messages. Queues can be configured in the server or created at runtime.
10
- Queues must be attached to at least one exchange in order to receive messages from publishers.
11
-
12
- =end
13
-
14
- class Queue < Qrack::Queue
15
-
16
- def initialize(client, name, opts = {})
17
- # check connection to server
18
- raise Bunny::ConnectionError, 'Not connected to server' if client.status == :not_connected
19
-
20
- @client = client
21
- @opts = opts
22
- @delivery_tag = nil
23
- @subscription = nil
24
-
25
- # Queues without a given name are named by the server and are generally
26
- # bound to the process that created them.
27
- if !name
28
- opts = {
29
- :passive => false,
30
- :durable => false,
31
- :exclusive => true,
32
- :auto_delete => true
33
- }.merge(opts)
34
- end
35
-
36
- # ignore the :nowait option if passed, otherwise program will hang waiting for a
37
- # response that will not be sent by the server
38
- opts.delete(:nowait)
39
-
40
- opts = { :queue => name || '', :nowait => false }.merge(opts)
41
-
42
- client.send_frame(Qrack::Protocol::Queue::Declare.new(opts))
43
-
44
- method = client.next_method
45
-
46
- client.check_response(method, Qrack::Protocol::Queue::DeclareOk, "Error declaring queue #{name}")
47
-
48
- @name = method.queue
49
- client.queues[@name] = self
50
- end
51
-
52
- # @return [Bunny::Consumer] Default consumer associated with this queue (if any), or nil
53
- # @note Default consumer is the one registered with the convenience {Bunny::Queue#subscribe} method. It has no special properties of any kind.
54
- # @see Queue#subscribe
55
- # @see Bunny::Consumer
56
- # @api public
57
- def default_consumer
58
- @default_consumer
59
- end
60
-
61
-
62
- # @return [Class]
63
- # @private
64
- def self.consumer_class
65
- # Bunny::Consumer
66
- Bunny::Subscription
67
- end # self.consumer_class
68
-
69
- =begin rdoc
70
-
71
- === DESCRIPTION:
72
-
73
- Acknowledges one or more messages delivered via the _Deliver_ or _Get_-_Ok_ methods. The client can
74
- ask to confirm a single message or a set of messages up to and including a specific message.
75
-
76
- ==== OPTIONS:
77
-
78
- * <tt>:delivery_tag</tt>
79
- * <tt>:multiple => true or false (_default_)</tt> - If set to _true_, the delivery tag is treated
80
- as "up to and including", so that the client can acknowledge multiple messages with a single
81
- method. If set to _false_, the delivery tag refers to a single message. If the multiple field
82
- is _true_, and the delivery tag is zero, tells the server to acknowledge all outstanding messages.
83
-
84
- =end
85
-
86
- def ack(opts={})
87
- # Set delivery tag
88
- if delivery_tag.nil? and opts[:delivery_tag].nil?
89
- raise Bunny::AcknowledgementError, "No delivery tag received"
90
- else
91
- self.delivery_tag = opts[:delivery_tag] if delivery_tag.nil?
92
- end
93
-
94
- opts = {:delivery_tag => delivery_tag, :multiple => false}.merge(opts)
95
-
96
- client.send_frame(Qrack::Protocol::Basic::Ack.new(opts))
97
-
98
- # reset delivery tag
99
- self.delivery_tag = nil
100
- end
101
-
102
- =begin rdoc
103
-
104
- === DESCRIPTION:
105
-
106
- Binds a queue to an exchange. Until a queue is bound it will not receive any messages. Queues are
107
- bound to the direct exchange '' by default. If error occurs, a _Bunny_::_ProtocolError_ is raised.
108
-
109
- * <tt>:key => 'routing key'* <tt>:key => 'routing_key'</tt> - Specifies the routing key for
110
- the binding. The routing key is used for routing messages depending on the exchange configuration.
111
- * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
112
-
113
- ==== RETURNS:
114
-
115
- <tt>:bind_ok</tt> if successful.
116
-
117
- =end
118
-
119
- def bind(exchange, opts = {})
120
- exchange = exchange.respond_to?(:name) ? exchange.name : exchange
121
-
122
- # ignore the :nowait option if passed, otherwise program will hang waiting for a
123
- # response that will not be sent by the server
124
- opts.delete(:nowait)
125
-
126
- opts = {
127
- :queue => name,
128
- :exchange => exchange,
129
- :routing_key => opts.delete(:key),
130
- :nowait => false
131
- }.merge(opts)
132
-
133
- client.send_frame(Qrack::Protocol::Queue::Bind.new(opts))
134
-
135
- method = client.next_method
136
-
137
- client.check_response(method, Qrack::Protocol::Queue::BindOk, "Error binding queue: #{name} to exchange: #{exchange}")
138
-
139
- # return message
140
- :bind_ok
141
- end
142
-
143
- =begin rdoc
144
-
145
- === DESCRIPTION:
146
-
147
- Requests that a queue is deleted from broker/server. When a queue is deleted any pending messages
148
- are sent to a dead-letter queue if this is defined in the server configuration. Removes reference
149
- from queues if successful. If an error occurs raises _Bunny_::_ProtocolError_.
150
-
151
- ==== Options:
152
-
153
- * <tt>:if_unused => true or false (_default_)</tt> - If set to _true_, the server will only
154
- delete the queue if it has no consumers. If the queue has consumers the server does not
155
- delete it but raises a channel exception instead.
156
- * <tt>:if_empty => true or false (_default_)</tt> - If set to _true_, the server will only
157
- delete the queue if it has no messages. If the queue is not empty the server raises a channel
158
- exception.
159
- * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
160
-
161
- ==== Returns:
162
-
163
- <tt>:delete_ok</tt> if successful
164
- =end
165
-
166
- def delete(opts = {})
167
- # ignore the :nowait option if passed, otherwise program will hang waiting for a
168
- # response that will not be sent by the server
169
- opts.delete(:nowait)
170
-
171
- opts = { :queue => name, :nowait => false }.merge(opts)
172
-
173
- client.send_frame(Qrack::Protocol::Queue::Delete.new(opts))
174
-
175
- method = client.next_method
176
-
177
- client.check_response(method, Qrack::Protocol::Queue::DeleteOk, "Error deleting queue #{name}")
178
-
179
- client.queues.delete(name)
180
-
181
- # return confirmation
182
- :delete_ok
183
- end
184
-
185
- =begin rdoc
186
-
187
- === DESCRIPTION:
188
-
189
- Gets a message from a queue in a synchronous way. If error occurs, raises _Bunny_::_ProtocolError_.
190
-
191
- ==== OPTIONS:
192
-
193
- * <tt>:ack => false (_default_) or true</tt> - If set to _false_, the server does not expect an
194
- acknowledgement message from the client. If set to _true_, the server expects an acknowledgement
195
- message from the client and will re-queue the message if it does not receive one within a time specified
196
- by the server.
197
-
198
- ==== RETURNS:
199
-
200
- Hash <tt>{:header, :payload, :delivery_details}</tt>. <tt>:delivery_details</tt> is
201
- a hash <tt>{:consumer_tag, :delivery_tag, :redelivered, :exchange, :routing_key}</tt>.
202
-
203
- If the queue is empty the returned hash will contain the values -
204
-
205
- :header => nil
206
- :payload => :queue_empty
207
- :delivery_details => nil
208
-
209
- N.B. If a block is provided then the hash will be passed into the block and the return value
210
- will be nil.
211
-
212
- =end
213
-
214
- def pop(opts = {}, &blk)
215
-
216
- # do we want to have to provide an acknowledgement?
217
- ack = opts.delete(:ack)
218
-
219
- opts = {
220
- :queue => name,
221
- :consumer_tag => name,
222
- :no_ack => !ack,
223
- :nowait => true
224
- }.merge(opts)
225
-
226
- client.send_frame(Qrack::Protocol::Basic::Get.new(opts))
227
-
228
- method = client.next_method
229
-
230
- if method.is_a?(Qrack::Protocol::Basic::GetEmpty) then
231
- queue_empty = true
232
- elsif !method.is_a?(Qrack::Protocol::Basic::GetOk)
233
- raise Bunny::ProtocolError, "Error getting message from queue #{name}"
234
- end
235
-
236
- if !queue_empty
237
- # get delivery tag to use for acknowledge
238
- self.delivery_tag = method.delivery_tag if ack
239
-
240
- header = client.next_payload
241
-
242
- # If maximum frame size is smaller than message payload body then message
243
- # will have a message header and several message bodies
244
- msg = ''
245
- while msg.length < header.size
246
- msg << client.next_payload
247
- end
248
-
249
- msg_hash = {:header => header, :payload => msg, :delivery_details => method.arguments}
250
-
251
- else
252
- msg_hash = {:header => nil, :payload => :queue_empty, :delivery_details => nil}
253
- end
254
-
255
- # Pass message hash to block or return message hash
256
- blk ? blk.call(msg_hash) : msg_hash
257
- end
258
-
259
- =begin rdoc
260
-
261
- === DESCRIPTION:
262
-
263
- Removes all messages from a queue. It does not cancel consumers. Purged messages are deleted
264
- without any formal "undo" mechanism. If an error occurs raises _Bunny_::_ProtocolError_.
265
-
266
- ==== Options:
267
-
268
- * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
269
-
270
- ==== Returns:
271
-
272
- <tt>:purge_ok</tt> if successful
273
- =end
274
-
275
- def purge(opts = {})
276
- # ignore the :nowait option if passed, otherwise program will hang waiting for a
277
- # response that will not be sent by the server
278
- opts.delete(:nowait)
279
-
280
- opts = { :queue => name, :nowait => false }.merge(opts)
281
-
282
- client.send_frame(Qrack::Protocol::Queue::Purge.new(opts))
283
-
284
- method = client.next_method
285
-
286
- client.check_response(method, Qrack::Protocol::Queue::PurgeOk, "Error purging queue #{name}")
287
-
288
- # return confirmation
289
- :purge_ok
290
- end
291
-
292
- =begin rdoc
293
-
294
- === DESCRIPTION:
295
-
296
- Returns hash {:message_count, :consumer_count}.
297
-
298
- =end
299
-
300
- def status
301
- client.send_frame(Qrack::Protocol::Queue::Declare.new(:queue => name, :passive => true))
302
- method = client.next_method
303
- {:message_count => method.message_count, :consumer_count => method.consumer_count}
304
- end
305
-
306
- def subscribe(opts = {}, &blk)
307
- raise RuntimeError.new("This queue already has default consumer. Please instantiate Bunny::Consumer directly and call its #consume method to register additional consumers.") if @default_consumer && ! opts[:consumer_tag]
308
-
309
- # Create a subscription.
310
- @default_consumer = self.class.consumer_class.new(client, self, opts)
311
- @default_consumer.consume(&blk)
312
- end
313
-
314
- =begin rdoc
315
-
316
- === DESCRIPTION:
317
-
318
- Cancels a consumer. This does not affect already delivered messages, but it does mean
319
- the server will not send any more messages for that consumer.
320
-
321
- ==== OPTIONS:
322
-
323
- * <tt>:consumer_tag => '_tag_'</tt> - Specifies the identifier for the consumer.
324
- * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
325
-
326
- ==== Returns:
327
-
328
- <tt>:unsubscribe_ok</tt> if successful
329
-
330
- =end
331
-
332
- def unsubscribe(opts = {})
333
- # Default consumer_tag from subscription if not passed in
334
- consumer_tag = @default_consumer ? @default_consumer.consumer_tag : opts[:consumer_tag]
335
-
336
- # Must have consumer tag to tell server what to unsubscribe
337
- raise Bunny::UnsubscribeError,
338
- "No consumer tag received" if !consumer_tag
339
-
340
- # Cancel consumer
341
- client.send_frame(Qrack::Protocol::Basic::Cancel.new(:consumer_tag => consumer_tag,:nowait => false))
342
-
343
- method = client.next_method
344
-
345
- client.check_response(method, Qrack::Protocol::Basic::CancelOk, "Error unsubscribing from queue #{name}")
346
-
347
- # Reset subscription
348
- @default_consumer = nil
349
-
350
- # Return confirmation
351
- :unsubscribe_ok
352
- end
353
-
354
- =begin rdoc
355
-
356
- === DESCRIPTION:
357
-
358
- Removes a queue binding from an exchange. If error occurs, a _Bunny_::_ProtocolError_ is raised.
359
-
360
- ==== OPTIONS:
361
- * <tt>:key => 'routing key'* <tt>:key => 'routing_key'</tt> - Specifies the routing key for
362
- the binding.
363
- * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
364
-
365
- ==== RETURNS:
366
-
367
- <tt>:unbind_ok</tt> if successful.
368
-
369
- =end
370
-
371
- def unbind(exchange, opts = {})
372
- exchange = exchange.respond_to?(:name) ? exchange.name : exchange
373
-
374
- # ignore the :nowait option if passed, otherwise program will hang waiting for a
375
- # response that will not be sent by the server
376
- opts.delete(:nowait)
377
-
378
- opts = {
379
- :queue => name,
380
- :exchange => exchange,
381
- :routing_key => opts.delete(:key),
382
- :nowait => false
383
- }.merge(opts)
384
-
385
- client.send_frame(Qrack::Protocol::Queue::Unbind.new(opts))
386
-
387
- method = client.next_method
388
-
389
- client.check_response(method, Qrack::Protocol::Queue::UnbindOk, "Error unbinding queue #{name}")
390
-
391
- # return message
392
- :unbind_ok
393
- end
394
-
395
- private
396
-
397
- def exchange
398
- @exchange ||= Bunny::Exchange.new(client, '', {:type => :direct, :key => name})
399
- end
400
-
401
- end
402
-
403
- end
@@ -1,87 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Bunny
4
-
5
- =begin rdoc
6
-
7
- === DESCRIPTION:
8
-
9
- Asks the server to start a "consumer", which is a transient request for messages from a specific
10
- queue. Consumers last as long as the channel they were created on, or until the client cancels them
11
- with an _unsubscribe_. Every time a message reaches the queue it is passed to the _blk_ for
12
- processing. If error occurs, _Bunny_::_ProtocolError_ is raised.
13
-
14
- ==== OPTIONS:
15
- * <tt>:consumer_tag => '_tag_'</tt> - Specifies the identifier for the consumer. The consumer tag is
16
- local to a connection, so two clients can use the same consumer tags. If this option is not
17
- specified a server generated name is used.
18
- * <tt>:ack => false (_default_) or true</tt> - If set to _false_, the server does not expect an
19
- acknowledgement message from the client. If set to _true_, the server expects an acknowledgement
20
- message from the client and will re-queue the message if it does not receive one within a time specified
21
- by the server.
22
- * <tt>:exclusive => true or false (_default_)</tt> - Request exclusive consumer access, meaning
23
- only this consumer can access the queue.
24
- * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
25
- * <tt>:timeout => number of seconds - The subscribe loop will continue to wait for
26
- messages until terminated (Ctrl-C or kill command) or this timeout interval is reached.
27
- * <tt>:message_max => max number messages to process</tt> - When the required number of messages
28
- is processed subscribe loop is exited.
29
-
30
- ==== OPERATION:
31
-
32
- Passes a hash of message information to the block, if one has been supplied. The hash contains
33
- :header, :payload and :delivery_details. The structure of the data is as follows -
34
-
35
- :header has instance variables -
36
- @klass
37
- @size
38
- @weight
39
- @properties is a hash containing -
40
- :content_type
41
- :delivery_mode
42
- :priority
43
-
44
- :payload contains the message contents
45
-
46
- :delivery details is a hash containing -
47
- :consumer_tag
48
- :delivery_tag
49
- :redelivered
50
- :exchange
51
- :routing_key
52
-
53
- If the :timeout option is specified then the subscription will
54
- automatically cease if the given number of seconds passes with no
55
- message arriving.
56
-
57
- ==== EXAMPLES
58
-
59
- my_queue.subscribe(:timeout => 5) {|msg| puts msg[:payload]}
60
-
61
- my_queue.subscribe(:message_max => 10, :ack => true) {|msg| puts msg[:payload]}
62
-
63
- =end
64
-
65
- class Subscription < Bunny::Consumer
66
-
67
- def setup_consumer
68
- subscription_options = {
69
- :queue => queue.name,
70
- :consumer_tag => consumer_tag,
71
- :no_ack => !ack,
72
- :exclusive => exclusive,
73
- :nowait => false
74
- }.merge(@opts)
75
-
76
- client.send_frame(Qrack::Protocol::Basic::Consume.new(subscription_options))
77
-
78
- method = client.next_method
79
-
80
- client.check_response(method, Qrack::Protocol::Basic::ConsumeOk, "Error subscribing to queue #{queue.name}")
81
-
82
- @consumer_tag = method.consumer_tag
83
- end
84
-
85
- end
86
-
87
- end
@@ -1,135 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Qrack
4
- module Protocol09
5
- #:stopdoc:
6
- class Class::Method
7
- def initialize *args
8
- opts = args.pop if args.last.is_a? Hash
9
- opts ||= {}
10
-
11
- if args.size == 1 and args.first.is_a? Transport09::Buffer
12
- buf = args.shift
13
- else
14
- buf = nil
15
- end
16
-
17
- self.class.arguments.each do |type, name|
18
- val = buf ? buf.read(type) :
19
- args.shift || opts[name] || opts[name.to_s]
20
- instance_variable_set("@#{name}", val)
21
- end
22
- end
23
-
24
- def arguments
25
- self.class.arguments.inject({}) do |hash, (type, name)|
26
- hash.update name => instance_variable_get("@#{name}")
27
- end
28
- end
29
-
30
- def to_binary
31
- buf = Transport09::Buffer.new
32
- buf.write :short, self.class.parent.id
33
- buf.write :short, self.class.id
34
-
35
- bits = []
36
-
37
- self.class.arguments.each do |type, name|
38
- val = instance_variable_get("@#{name}")
39
- if type == :bit
40
- bits << (val || false)
41
- else
42
- unless bits.empty?
43
- buf.write :bit, bits
44
- bits = []
45
- end
46
- buf.write type, val
47
- end
48
- end
49
-
50
- buf.write :bit, bits unless bits.empty?
51
- buf.rewind
52
-
53
- buf
54
- end
55
-
56
- def to_s
57
- to_binary.to_s
58
- end
59
-
60
- def to_frame channel = 0
61
- Transport09::Method.new(self, channel)
62
- end
63
- end
64
-
65
- class Header
66
- def initialize *args
67
- opts = args.pop if args.last.is_a? Hash
68
- opts ||= {}
69
-
70
- first = args.shift
71
-
72
- if first.is_a? ::Class and first.ancestors.include? Protocol09::Class
73
- @klass = first
74
- @size = args.shift || 0
75
- @weight = args.shift || 0
76
- @properties = opts
77
-
78
- elsif first.is_a? Transport09::Buffer or first.is_a? String
79
- buf = first
80
- buf = Transport09::Buffer.new(buf) unless buf.is_a? Transport09::Buffer
81
-
82
- @klass = Protocol09.classes[buf.read(:short)]
83
- @weight = buf.read(:short)
84
- @size = buf.read(:longlong)
85
-
86
- props = buf.read(:properties, *klass.properties.map{|type,_| type })
87
- @properties = Hash[*klass.properties.map{|_,name| name }.zip(props).reject{|k,v| v.nil? }.flatten]
88
-
89
- else
90
- raise ArgumentError, 'Invalid argument'
91
- end
92
-
93
- end
94
- attr_accessor :klass, :size, :weight, :properties
95
-
96
- def to_binary
97
- buf = Transport09::Buffer.new
98
- buf.write :short, klass.id
99
- buf.write :short, weight # XXX rabbitmq only supports weight == 0
100
- buf.write :longlong, size
101
- buf.write :properties, (klass.properties.map do |type, name|
102
- [ type, properties[name] || properties[name.to_s] ]
103
- end)
104
- buf.rewind
105
- buf
106
- end
107
-
108
- def to_s
109
- to_binary.to_s
110
- end
111
-
112
- def to_frame channel = 0
113
- Transport09::Header.new(self, channel)
114
- end
115
-
116
- def == header
117
- [ :klass, :size, :weight, :properties ].inject(true) do |eql, field|
118
- eql and __send__(field) == header.__send__(field)
119
- end
120
- end
121
-
122
- def method_missing meth, *args, &blk
123
- @properties.has_key?(meth) || @klass.properties.find{|_,name| name == meth } ? @properties[meth] :
124
- super
125
- end
126
- end
127
-
128
- def self.parse buf
129
- buf = Transport09::Buffer.new(buf) unless buf.is_a? Transport09::Buffer
130
- class_id, method_id = buf.read(:short, :short)
131
- classes[class_id].methods[method_id].new(buf)
132
- end
133
-
134
- end
135
- end