cli-proton-ruby 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/cli-proton-ruby-connector +23 -0
- data/bin/cli-proton-ruby-receiver +23 -0
- data/bin/cli-proton-ruby-sender +23 -0
- data/lib/connector_client.rb +50 -0
- data/lib/constants.rb +27 -0
- data/lib/defaults.rb +91 -0
- data/lib/formatters.rb +28 -0
- data/lib/formatters/basic_formatter.rb +112 -0
- data/lib/formatters/dict_formatter.rb +66 -0
- data/lib/formatters/interop_formatter.rb +88 -0
- data/lib/handlers.rb +34 -0
- data/lib/handlers/basic_handler.rb +79 -0
- data/lib/handlers/connector_handler.rb +90 -0
- data/lib/handlers/receiver_handler.rb +230 -0
- data/lib/handlers/sender_handler.rb +269 -0
- data/lib/handlers/sr_common_handler.rb +100 -0
- data/lib/options.rb +38 -0
- data/lib/options/basic_option_parser.rb +169 -0
- data/lib/options/connector_option_parser.rb +61 -0
- data/lib/options/receiver_option_parser.rb +154 -0
- data/lib/options/sender_option_parser.rb +365 -0
- data/lib/options/sr_common_option_parser.rb +96 -0
- data/lib/receiver_client.rb +61 -0
- data/lib/sender_client.rb +69 -0
- data/lib/utils/duration.rb +44 -0
- data/lib/utils/env_utils.rb +39 -0
- data/lib/utils/exit_timer.rb +44 -0
- data/lib/utils/string_utils.rb +81 -0
- metadata +98 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a4a093138bedcfc8d3887ae6642853dc082d655769d3f4e154730a3e9bcac238
|
4
|
+
data.tar.gz: 788a3da1be2cf22de966091cf1699b7623f43bbf8db82a50d535b101ebab0446
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e8834697ba69e4fd6bf5a92563228b82120f099b9f62f77bd1626715246dcd71127f94d29101b30b94d6d0833d21237c5710c3489ef3edec230414160cc912e1
|
7
|
+
data.tar.gz: f710bd2152728f4dc20946257c4b496b926786d583ab85b47d67d8804e6e46b6a855b8bdd187b218ea60eea337943d31250cdb7fa564e163a7b98527f0f69bde
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#--
|
3
|
+
# Copyright 2017 Red Hat Inc.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#++
|
17
|
+
|
18
|
+
require_relative '../lib/connector_client'
|
19
|
+
|
20
|
+
# Run connector client with command line arguments
|
21
|
+
ConnectorClient.new(ARGV)
|
22
|
+
|
23
|
+
# eof
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#--
|
3
|
+
# Copyright 2017 Red Hat Inc.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#++
|
17
|
+
|
18
|
+
require_relative '../lib/receiver_client'
|
19
|
+
|
20
|
+
# Run receiver client with command line arguments
|
21
|
+
ReceiverClient.new(ARGV)
|
22
|
+
|
23
|
+
# eof
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#--
|
3
|
+
# Copyright 2017 Red Hat Inc.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#++
|
17
|
+
|
18
|
+
require_relative '../lib/sender_client'
|
19
|
+
|
20
|
+
# Run sender client with command line arguments
|
21
|
+
SenderClient.new(ARGV)
|
22
|
+
|
23
|
+
# eof
|
@@ -0,0 +1,50 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2017 Red Hat Inc.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#++
|
16
|
+
|
17
|
+
require 'qpid_proton'
|
18
|
+
require_relative 'options/connector_option_parser'
|
19
|
+
require_relative 'handlers/connector_handler'
|
20
|
+
|
21
|
+
# ConnectorClient parses arguments
|
22
|
+
# and runs connector
|
23
|
+
class ConnectorClient
|
24
|
+
|
25
|
+
# Initialization of connector client,
|
26
|
+
# parsing connector client arguments
|
27
|
+
# and connector client run
|
28
|
+
# ==== Parameters
|
29
|
+
# args:: connector client arguments
|
30
|
+
def initialize(args)
|
31
|
+
# Parse arguments
|
32
|
+
connector_options_parser = Options::ConnectorOptionParser.new(args)
|
33
|
+
# Create connector handler
|
34
|
+
connector_handler = Handlers::ConnectorHandler.new(
|
35
|
+
connector_options_parser.options.broker,
|
36
|
+
connector_options_parser.options.count,
|
37
|
+
connector_options_parser.options.sasl_mechs,
|
38
|
+
connector_options_parser.options.idle_timeout,
|
39
|
+
connector_options_parser.options.max_frame_size,
|
40
|
+
connector_options_parser.options.sasl_enabled,
|
41
|
+
connector_options_parser.options.log_lib,
|
42
|
+
connector_options_parser.options.exit_timer,
|
43
|
+
)
|
44
|
+
# Run connector client
|
45
|
+
Qpid::Proton::Container.new(connector_handler).run
|
46
|
+
end
|
47
|
+
|
48
|
+
end # class ConnectorClient
|
49
|
+
|
50
|
+
# eof
|
data/lib/constants.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2017 Red Hat Inc.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#++
|
16
|
+
|
17
|
+
# Module containing constant values
|
18
|
+
module Constants
|
19
|
+
|
20
|
+
# Minimal port range value
|
21
|
+
CONST_MIN_PORT_RANGE_VALUE = 0
|
22
|
+
# Maximal port range value
|
23
|
+
CONST_MAX_PORT_RANGE_VALUE = 65535
|
24
|
+
|
25
|
+
end # module Constants
|
26
|
+
|
27
|
+
# eof
|
data/lib/defaults.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2017 Red Hat Inc.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#++
|
16
|
+
|
17
|
+
# Module containing default values
|
18
|
+
module Defaults
|
19
|
+
|
20
|
+
# Default value for broker URI in format IP:PORT/queue
|
21
|
+
DEFAULT_BROKER = "127.0.0.1:5672/examples"
|
22
|
+
# Default value for message(s)/connection(s) count to send/receive/create
|
23
|
+
DEFAULT_COUNT = 1
|
24
|
+
# Default value for format of message(s) log
|
25
|
+
DEFAULT_LOG_MSGS = "none"
|
26
|
+
# Default value of message properties
|
27
|
+
DEFAULT_MSG_PROPERTIES = nil
|
28
|
+
# Default value for message content
|
29
|
+
DEFAULT_MSG_CONTENT = nil
|
30
|
+
# Default value for content type
|
31
|
+
DEFAULT_CONTENT_TYPE = "string"
|
32
|
+
# Default value for message content type
|
33
|
+
DEFAULT_MSG_CONTENT_TYPE = nil
|
34
|
+
# Default message durability
|
35
|
+
DEFAULT_MSG_DURABLE = false
|
36
|
+
# Default value for message correlation ID
|
37
|
+
DEFAULT_CORR_ID = nil
|
38
|
+
# Default value for reply-to
|
39
|
+
DEFAULT_MSG_REPLY_TO = nil
|
40
|
+
# Default value for process reply to
|
41
|
+
DEFAULT_PROC_REPLY_TO = false
|
42
|
+
# Default value for message group ID
|
43
|
+
DEFAULT_GROUP_ID = nil
|
44
|
+
# Default value for browse messages
|
45
|
+
DEFAULT_BROWSE = false
|
46
|
+
# Default value for message selector
|
47
|
+
DEFAULT_SELECTOR = nil
|
48
|
+
# Default value for SASL allowed mechanisms
|
49
|
+
DEFAULT_SASL_MECHS = "ANONYMOUS PLAIN EXTERNAL"
|
50
|
+
# Default value for idle timeout
|
51
|
+
DEFAULT_IDLE_TIMEOUT = 0
|
52
|
+
# Default value for message TTL (ms)
|
53
|
+
DEFAULT_MSG_TTL = 0
|
54
|
+
# Default value for message priority
|
55
|
+
DEFAULT_MSG_PRIORITY = nil
|
56
|
+
# Default value for message ID
|
57
|
+
DEFAULT_MSG_ID = nil
|
58
|
+
# Default value for message user ID
|
59
|
+
DEFAULT_MSG_USER_ID = nil
|
60
|
+
# Default value for message subject
|
61
|
+
DEFAULT_MSG_SUBJECT = nil
|
62
|
+
# Default value for anonymous
|
63
|
+
DEFAULT_ANONYMOUS = false
|
64
|
+
# Default value for exit timer
|
65
|
+
DEFAULT_EXIT_TIMER = nil
|
66
|
+
# Default minimal max frame size
|
67
|
+
DEFAULT_MIN_MAX_FRAME_SIZE = 512
|
68
|
+
# Default maximal max frame size
|
69
|
+
DEFAULT_MAX_MAX_FRAME_SIZE = 2**20 # TODO(jdanek): workaround PROTON-1809 Unable to receive messages ...
|
70
|
+
# Default value for max frame size
|
71
|
+
DEFAULT_MAX_FRAME_SIZE = DEFAULT_MAX_MAX_FRAME_SIZE
|
72
|
+
# Default client library logging
|
73
|
+
DEFAULT_LOG_LIB = "NONE"
|
74
|
+
# Default value for recv-listen
|
75
|
+
DEFAULT_RECV_LISTEN = false
|
76
|
+
# Default value for recv-listen port
|
77
|
+
DEFAULT_RECV_LISTEN_PORT = 5672
|
78
|
+
# Default value for auto-settle-off
|
79
|
+
DEFAULT_AUTO_SETTLE_OFF = false
|
80
|
+
# Default value of credit for messages to be pre-fetched
|
81
|
+
DEFAULT_PREFETCH = 10
|
82
|
+
# Default message destination
|
83
|
+
DEFAULT_TO = nil
|
84
|
+
# Default message content hashed
|
85
|
+
DEFAULT_MSG_CONTENT_HASHED = false
|
86
|
+
# Default connection SASL enabled
|
87
|
+
DEFAULT_SASL_ENABLED = true
|
88
|
+
|
89
|
+
end # module Defaults
|
90
|
+
|
91
|
+
# eof
|
data/lib/formatters.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2017 Red Hat Inc.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#++
|
16
|
+
|
17
|
+
require 'formatter/basic_formatter'
|
18
|
+
require 'formatter/dict_formatter'
|
19
|
+
|
20
|
+
# Module containing formatters for cli-proton-ruby clients
|
21
|
+
# ==== Formatters
|
22
|
+
# * Formatters::BasicFormatter for formatting message body
|
23
|
+
# * Formatters::DictFormatter for formatting message into dictionary
|
24
|
+
module Formatters
|
25
|
+
|
26
|
+
end # module Formatters
|
27
|
+
|
28
|
+
# eof
|
@@ -0,0 +1,112 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2017 Red Hat Inc.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#++
|
16
|
+
|
17
|
+
require_relative '../utils/string_utils'
|
18
|
+
|
19
|
+
module Formatters
|
20
|
+
|
21
|
+
# Basic formatter of message body
|
22
|
+
class BasicFormatter
|
23
|
+
|
24
|
+
# Message to format
|
25
|
+
attr_accessor :message
|
26
|
+
# Content hashed
|
27
|
+
attr_accessor :msg_content_hashed
|
28
|
+
|
29
|
+
# Initialization of basic formatter
|
30
|
+
# ==== Basic formatter arguments
|
31
|
+
# message:: message to format
|
32
|
+
def initialize(message, msg_content_hashed=false)
|
33
|
+
# Save message
|
34
|
+
@message = message
|
35
|
+
@msg_content_hashed = msg_content_hashed
|
36
|
+
end # initialize(message)
|
37
|
+
|
38
|
+
# Format value according to type
|
39
|
+
# ==== Parameters
|
40
|
+
# value:: value to format
|
41
|
+
# ==== Returns
|
42
|
+
# value formatted as string
|
43
|
+
def format_value(value)
|
44
|
+
# Switch by class of value
|
45
|
+
case value
|
46
|
+
# Boolean value
|
47
|
+
when TrueClass, FalseClass
|
48
|
+
value ? "True" : "False"
|
49
|
+
# Numeric or Range value
|
50
|
+
when Integer, Float, Numeric, Range #, Bignum, Fixnum are deprecated
|
51
|
+
value
|
52
|
+
# Array value
|
53
|
+
when Array
|
54
|
+
# Array for formatted items of array
|
55
|
+
help_array = []
|
56
|
+
# Each item in array needs to be formatted
|
57
|
+
value.each do |item|
|
58
|
+
# Format array item
|
59
|
+
help_array.push(format_value(item))
|
60
|
+
end
|
61
|
+
"[#{help_array.join(", ")}]"
|
62
|
+
# Dictionary/hash value
|
63
|
+
when Hash
|
64
|
+
# Array for formatted items of hash
|
65
|
+
help_array = []
|
66
|
+
# Each key-value pair needs to be formatted
|
67
|
+
value.each do |key, val|
|
68
|
+
# Format key-value pair of item
|
69
|
+
help_array.push("#{format_value(key)}: #{format_value(val)}")
|
70
|
+
end
|
71
|
+
"{#{help_array.join(", ")}}"
|
72
|
+
# String or symbol value
|
73
|
+
when Symbol
|
74
|
+
value.size > 0 ? "'#{value}'" : "None"
|
75
|
+
when String
|
76
|
+
value.size > 0 ? "'#{value.gsub(/'/, %q(\\\'))}'" : "None"
|
77
|
+
# Nil value
|
78
|
+
when NilClass
|
79
|
+
"None"
|
80
|
+
# Other or unknown type
|
81
|
+
else
|
82
|
+
raise TypeError, "Unknown value type"
|
83
|
+
end # case
|
84
|
+
end # format_value(value)
|
85
|
+
|
86
|
+
# Prints formatted message body to stdout
|
87
|
+
def print()
|
88
|
+
# Print formatted body to stdout
|
89
|
+
puts format_value(@msg_content_hashed ? StringUtils.sha1_hash(@message.body) : @message.body)
|
90
|
+
end # print()
|
91
|
+
|
92
|
+
# Escapes characters which Python's eval() cannot load
|
93
|
+
# that is esp. \0, \r, \n. Use a range, to be safe.
|
94
|
+
def self.escape_chars(msg_string)
|
95
|
+
if msg_string.nil?
|
96
|
+
nil
|
97
|
+
else
|
98
|
+
msg_string.each_codepoint.map do |s|
|
99
|
+
if s < 32 || s > 126
|
100
|
+
format('\\u%04x', s)
|
101
|
+
else
|
102
|
+
s.chr
|
103
|
+
end
|
104
|
+
end.join
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end # class BasicFormatter
|
109
|
+
|
110
|
+
end # module Formatters
|
111
|
+
|
112
|
+
# eof
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2017 Red Hat Inc.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#++
|
16
|
+
|
17
|
+
require_relative 'basic_formatter'
|
18
|
+
|
19
|
+
module Formatters
|
20
|
+
|
21
|
+
# Formatter of message into dictionary format
|
22
|
+
class DictFormatter < Formatters::BasicFormatter
|
23
|
+
|
24
|
+
# Initialization of dictionary formatter
|
25
|
+
# ==== Dictionary formatter arguments
|
26
|
+
# message:: message to format
|
27
|
+
def initialize(message, msg_content_hashed=false)
|
28
|
+
super(message, msg_content_hashed)
|
29
|
+
end # initialize(message)
|
30
|
+
|
31
|
+
# Format message as dictionary
|
32
|
+
# ==== Returns
|
33
|
+
# message formatted as dictionary
|
34
|
+
def get_as_dictionary()
|
35
|
+
dict_to_return = "" \
|
36
|
+
+ "'redelivered': #{format_value(
|
37
|
+
@message.delivery_count == 0 ? false : true
|
38
|
+
)}, "\
|
39
|
+
+ "'reply-to': #{format_value(@message.reply_to)}, "\
|
40
|
+
+ "'subject': #{format_value(@message.subject)}, "\
|
41
|
+
+ "'content-type': #{format_value(@message.content_type)}, "\
|
42
|
+
+ "'id': #{format_value(@message.id)}, "\
|
43
|
+
+ "'group-id': #{format_value(@message.group_id)}, "\
|
44
|
+
+ "'user-id': #{format_value(@message.user_id)}, "\
|
45
|
+
+ "'correlation-id': #{format_value(@message.correlation_id)}, "\
|
46
|
+
+ "'priority': #{format_value(@message.priority)}, "\
|
47
|
+
+ "'durable': #{format_value(@message.durable)}, "\
|
48
|
+
+ "'ttl': #{format_value(@message.ttl)}, "\
|
49
|
+
+ "'properties': #{format_value(@message.properties)}, "\
|
50
|
+
+ "'content': #{
|
51
|
+
format_value(@msg_content_hashed ? StringUtils.sha1_hash(@message.body) : @message.body)
|
52
|
+
}"
|
53
|
+
return self.class.escape_chars("{#{dict_to_return}}")
|
54
|
+
end # get_as_dictionary()
|
55
|
+
|
56
|
+
# Prints message formatted as dictionary to stdout
|
57
|
+
def print()
|
58
|
+
# Print formatted message to stdout
|
59
|
+
puts get_as_dictionary()
|
60
|
+
end # print()
|
61
|
+
|
62
|
+
end # class DictFormatter
|
63
|
+
|
64
|
+
end # module Formatters
|
65
|
+
|
66
|
+
# eof
|