cztop 0.14.1 → 1.1.0.pre1

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/coverage.yml +20 -0
  3. data/.github/workflows/draft_api.yml +27 -0
  4. data/.github/workflows/stable_api.yml +26 -0
  5. data/.rubocop.yml +175 -0
  6. data/CHANGES.md +9 -4
  7. data/Gemfile +3 -7
  8. data/README.md +19 -58
  9. data/ci/install-libczmq +22 -0
  10. data/ci/install-libzmq +22 -0
  11. data/cztop.gemspec +12 -13
  12. data/lib/cztop/actor.rb +55 -26
  13. data/lib/cztop/authenticator.rb +18 -9
  14. data/lib/cztop/beacon.rb +22 -10
  15. data/lib/cztop/cert_store.rb +8 -2
  16. data/lib/cztop/certificate.rb +47 -18
  17. data/lib/cztop/config/comments.rb +14 -3
  18. data/lib/cztop/config/serialization.rb +25 -5
  19. data/lib/cztop/config/traversing.rb +44 -13
  20. data/lib/cztop/config.rb +23 -9
  21. data/lib/cztop/frame.rb +23 -10
  22. data/lib/cztop/has_ffi_delegate.rb +11 -1
  23. data/lib/cztop/message/frames.rb +16 -2
  24. data/lib/cztop/message.rb +36 -22
  25. data/lib/cztop/metadata.rb +35 -24
  26. data/lib/cztop/monitor.rb +14 -5
  27. data/lib/cztop/poller/aggregated.rb +31 -15
  28. data/lib/cztop/poller/zmq.rb +25 -22
  29. data/lib/cztop/poller/zpoller.rb +18 -6
  30. data/lib/cztop/poller.rb +43 -18
  31. data/lib/cztop/polymorphic_zsock_methods.rb +6 -1
  32. data/lib/cztop/proxy.rb +34 -19
  33. data/lib/cztop/send_receive_methods.rb +5 -1
  34. data/lib/cztop/socket/types.rb +128 -22
  35. data/lib/cztop/socket.rb +23 -18
  36. data/lib/cztop/version.rb +5 -1
  37. data/lib/cztop/z85/padded.rb +12 -3
  38. data/lib/cztop/z85/pipe.rb +40 -17
  39. data/lib/cztop/z85.rb +17 -6
  40. data/lib/cztop/zap.rb +57 -32
  41. data/lib/cztop/zsock_options.rb +155 -122
  42. data/lib/cztop.rb +2 -1
  43. metadata +25 -90
  44. data/.gitlab-ci.yml +0 -32
  45. data/Guardfile +0 -61
  46. data/Procfile +0 -3
  47. data/ci-scripts/install-deps +0 -8
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CZTop
2
4
  # Represents a CZMQ::FFI::Zcert.
3
5
  class Certificate
6
+
4
7
  include HasFFIDelegate
5
8
  extend CZTop::HasFFIDelegate::ClassMethods
6
9
  include ::CZMQ::FFI
@@ -9,9 +12,11 @@ module CZTop
9
12
  # @return [void]
10
13
  def self.check_curve_availability
11
14
  return if Zsys.has_curve
15
+
12
16
  warn "CZTop: CURVE isn't available. Consider installing libsodium."
13
17
  end
14
18
 
19
+
15
20
  # Loads a certificate from a file.
16
21
  # @param filename [String, Pathname, #to_s] path to certificate file
17
22
  # @return [Certificate] the loaded certificate
@@ -20,6 +25,7 @@ module CZTop
20
25
  from_ffi_delegate(ptr)
21
26
  end
22
27
 
28
+
23
29
  # Creates a new certificate from the given keys (either binary or in Z85
24
30
  # format).
25
31
  # @param public_key [String] binary public key (32 or 40 bytes)
@@ -29,25 +35,28 @@ module CZTop
29
35
  # @raise [ArgumentError] if keys passed are invalid
30
36
  # @raise [SystemCallError] if this fails
31
37
  def self.new_from(public_key, secret_key = nil)
32
- raise ArgumentError, "no public key given" unless public_key
38
+ raise ArgumentError, 'no public key given' unless public_key
39
+
33
40
  secret_key ||= "\x00" * 32 # no secret key given, provide 32 null bytes
34
41
 
35
42
  # convert Z85 => binary
36
43
  public_key = Z85.decode(public_key) if public_key.bytesize == 40
37
44
  secret_key = Z85.decode(secret_key) if secret_key.bytesize == 40
38
45
 
39
- raise ArgumentError, "invalid public key size" if public_key.bytesize != 32
40
- raise ArgumentError, "invalid secret key size" if secret_key.bytesize != 32
46
+ raise ArgumentError, 'invalid public key size' if public_key.bytesize != 32
47
+ raise ArgumentError, 'invalid secret key size' if secret_key.bytesize != 32
41
48
 
42
49
  ptr = Zcert.new_from(public_key, secret_key)
43
50
  from_ffi_delegate(ptr)
44
51
  end
45
52
 
53
+
46
54
  # Initialize a new in-memory certificate with random keys.
47
55
  def initialize
48
56
  attach_ffi_delegate(Zcert.new)
49
57
  end
50
58
 
59
+
51
60
  # Returns the public key either as Z85-encoded ASCII string (default) or
52
61
  # binary string.
53
62
  # @param format [Symbol] +:z85+ for Z85, +:binary+ for binary
@@ -59,10 +68,11 @@ module CZTop
59
68
  when :binary
60
69
  ffi_delegate.public_key.read_string(32)
61
70
  else
62
- raise ArgumentError, "invalid format: %p" % format
71
+ raise ArgumentError, format('invalid format: %p', format)
63
72
  end
64
73
  end
65
74
 
75
+
66
76
  # Returns the secret key either as Z85-encoded ASCII string (default) or
67
77
  # binary string.
68
78
  # @param format [Symbol] +:z85+ for Z85, +:binary+ for binary
@@ -73,16 +83,17 @@ module CZTop
73
83
  case format
74
84
  when :z85
75
85
  key = ffi_delegate.secret_txt.force_encoding(Encoding::ASCII)
76
- return nil if key.count("0") == 40
86
+ return nil if key.count('0') == 40
77
87
  when :binary
78
88
  key = ffi_delegate.secret_key.read_string(32)
79
89
  return nil if key.count("\0") == 32
80
90
  else
81
- raise ArgumentError, "invalid format: %p" % format
91
+ raise ArgumentError, format('invalid format: %p', format)
82
92
  end
83
93
  key
84
94
  end
85
95
 
96
+
86
97
  # Get metadata.
87
98
  # @param key [String] metadata key
88
99
  # @return [String] value for meta key
@@ -90,32 +101,38 @@ module CZTop
90
101
  def [](key)
91
102
  ffi_delegate.meta(key)
92
103
  end
104
+
105
+
93
106
  # Set metadata.
94
107
  # @param key [String] metadata key
95
108
  # @param value [String] metadata value
96
109
  # @return [value]
97
110
  def []=(key, value)
98
111
  if value
99
- ffi_delegate.set_meta(key, "%s", :string, value)
112
+ ffi_delegate.set_meta(key, '%s', :string, value)
100
113
  else
101
114
  ffi_delegate.unset_meta(key)
102
115
  end
103
116
  end
104
117
 
118
+
105
119
  # Returns meta keys set.
106
120
  # @return [Array<String>]
107
121
  def meta_keys
108
- zlist = ffi_delegate.meta_keys
122
+ zlist = ffi_delegate.meta_keys
109
123
  first_key = zlist.first
110
124
  return [] if first_key.null?
125
+
111
126
  keys = [first_key.read_string]
112
- while key = zlist.next
127
+ while (key = zlist.next)
113
128
  break if key.null?
129
+
114
130
  keys << key.read_string
115
131
  end
116
132
  keys
117
133
  end
118
134
 
135
+
119
136
  # Save full certificate (public + secret) to files.
120
137
  # @param filename [String, #to_s] path/filename to public file
121
138
  # @return [void]
@@ -126,55 +143,67 @@ module CZTop
126
143
  def save(filename)
127
144
  # see https://github.com/zeromq/czmq/issues/1244
128
145
  raise ArgumentError, "filename can't be empty" if filename.to_s.empty?
146
+
129
147
  rc = ffi_delegate.save(filename.to_s)
130
- return if rc == 0
131
- raise_zmq_err("error while saving to file %p" % filename)
148
+ return if rc.zero?
149
+
150
+ raise_zmq_err(format('error while saving to file %p', filename))
132
151
  end
133
152
 
153
+
134
154
  # Saves the public key to file in ZPL ({Config}) format.
135
155
  # @param filename [String, #to_s] path/filename to public file
136
156
  # @return [void]
137
157
  # @raise [SystemCallError] if this fails
138
158
  def save_public(filename)
139
159
  rc = ffi_delegate.save_public(filename.to_s)
140
- return if rc == 0
141
- raise_zmq_err("error while saving to the file %p" % filename)
160
+ return if rc.zero?
161
+
162
+ raise_zmq_err(format('error while saving to the file %p', filename))
142
163
  end
143
164
 
165
+
144
166
  # Saves the secret key to file in ZPL ({Config}) format.
145
167
  # @param filename [String, #to_s] path/filename to secret file
146
168
  # @return [void]
147
169
  # @raise [SystemCallError] if this fails
148
170
  def save_secret(filename)
149
171
  rc = ffi_delegate.save_secret(filename.to_s)
150
- return if rc == 0
151
- raise_zmq_err("error while saving to the file %p" % filename)
172
+ return if rc.zero?
173
+
174
+ raise_zmq_err(format('error while saving to the file %p', filename))
152
175
  end
153
176
 
177
+
154
178
  # Applies this certificate on a {Socket} or {Actor}.
155
179
  # @param zocket [Socket, Actor] path/filename to secret file
156
180
  # @return [void]
157
181
  # @raise [SystemCallError] if secret key is undefined
158
182
  def apply(zocket)
159
- raise ArgumentError, "invalid zocket argument %p" % zocket unless zocket
183
+ raise ArgumentError, format('invalid zocket argument %p', zocket) unless zocket
160
184
  return ffi_delegate.apply(zocket) unless secret_key.nil?
161
- raise_zmq_err("secret key is undefined")
185
+
186
+ raise_zmq_err('secret key is undefined')
162
187
  end
163
188
 
189
+
164
190
  # Duplicates the certificate.
165
191
  # @return [Certificate]
166
192
  # @raise [SystemCallError] if this fails
167
193
  def dup
168
194
  ptr = ffi_delegate.dup
169
195
  return from_ffi_delegate(ptr) unless ptr.null?
170
- raise_zmq_err("unable to duplicate certificate")
196
+
197
+ raise_zmq_err('unable to duplicate certificate')
171
198
  end
172
199
 
200
+
173
201
  # Compares this certificate to another.
174
202
  # @param other [Cert] other certificate
175
203
  # @return [Boolean] whether they have the same keys
176
204
  def ==(other)
177
205
  ffi_delegate.eq(other.ffi_delegate)
178
206
  end
207
+
179
208
  end
180
209
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CZTop
2
4
  class Config
3
5
 
@@ -7,11 +9,13 @@ module CZTop
7
9
  # are accessible.
8
10
  # @return [CommentsAccessor]
9
11
  def comments
10
- return CommentsAccessor.new(self)
12
+ CommentsAccessor.new(self)
11
13
  end
12
14
 
15
+
13
16
  # Used to access a {Config}'s comments.
14
17
  class CommentsAccessor
18
+
15
19
  include Enumerable
16
20
 
17
21
  # @param config [Config]
@@ -19,26 +23,30 @@ module CZTop
19
23
  @config = config
20
24
  end
21
25
 
26
+
22
27
  # Adds a new comment.
23
28
  # @param new_comment [String]
24
29
  # @return [self]
25
30
  def <<(new_comment)
26
- @config.ffi_delegate.set_comment("%s", :string, new_comment)
27
- return self
31
+ @config.ffi_delegate.set_comment('%s', :string, new_comment)
32
+ self
28
33
  end
29
34
 
35
+
30
36
  # Deletes all comments for this {Config} item.
31
37
  # @return [void]
32
38
  def delete_all
33
39
  @config.ffi_delegate.set_comment(nil)
34
40
  end
35
41
 
42
+
36
43
  # Yields all comments for this {Config} item.
37
44
  # @yieldparam comment [String]
38
45
  # @return [void]
39
46
  def each
40
47
  while comment = _zlist.next
41
48
  break if comment.null?
49
+
42
50
  yield comment.read_string
43
51
  end
44
52
  rescue CZMQ::FFI::Zlist::DestroyedError
@@ -46,6 +54,7 @@ module CZTop
46
54
  nil
47
55
  end
48
56
 
57
+
49
58
  # Returns the number of comments for this {Config} item.
50
59
  # @return [Integer] number of comments
51
60
  def size
@@ -61,6 +70,8 @@ module CZTop
61
70
  def _zlist
62
71
  @config.ffi_delegate.comments
63
72
  end
73
+
64
74
  end
75
+
65
76
  end
66
77
  end
@@ -1,19 +1,25 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Methods used around serialization of {CZTop::Config} items.
2
4
  module CZTop::Config::Serialization
5
+
3
6
  # Serialize to a string in the ZPL format.
4
7
  # @return [String]
5
8
  def to_s
6
9
  ffi_delegate.str_save.read_string
7
10
  end
8
11
 
12
+
9
13
  # Returns the path/filename of the file this {Config} tree was loaded from.
10
14
  # @return [String]
11
15
  def filename
12
16
  ffi_delegate.filename
13
17
  end
14
18
 
19
+
15
20
  # Some class methods for {Config} related to serialization.
16
21
  module ClassMethods
22
+
17
23
  # Loads a {Config} tree from a string.
18
24
  # @param string [String] the tree
19
25
  # @return [Config]
@@ -21,6 +27,7 @@ module CZTop::Config::Serialization
21
27
  from_ffi_delegate CZMQ::FFI::Zconfig.str_load(string)
22
28
  end
23
29
 
30
+
24
31
  # Loads a {Config} tree from a file.
25
32
  # @param path [String, Pathname, #to_s] the path to the ZPL config file
26
33
  # @raise [SystemCallError] if this fails
@@ -28,10 +35,13 @@ module CZTop::Config::Serialization
28
35
  def load(path)
29
36
  ptr = CZMQ::FFI::Zconfig.load(path.to_s)
30
37
  return from_ffi_delegate(ptr) unless ptr.null?
38
+
31
39
  CZTop::HasFFIDelegate.raise_zmq_err(
32
- "error while reading the file %p" % path.to_s)
40
+ format('error while reading the file %p', path.to_s)
41
+ )
33
42
  end
34
43
 
44
+
35
45
  # Loads a {Config} tree from a marshalled string.
36
46
  # @note This method is automatically used by Marshal.load.
37
47
  # @param string [String] marshalled {Config}
@@ -39,18 +49,22 @@ module CZTop::Config::Serialization
39
49
  def _load(string)
40
50
  from_string(string)
41
51
  end
52
+
42
53
  end
43
54
 
55
+
44
56
  # Saves the Config tree to a file.
45
57
  # @param path [String, Pathname, #to_s] the path to the ZPL config file
46
58
  # @return [void]
47
59
  # @raise [SystemCallError] if this fails
48
60
  def save(path)
49
61
  rc = ffi_delegate.save(path.to_s)
50
- return if rc == 0
51
- raise_zmq_err("error while saving to the file %s" % path)
62
+ return if rc.zero?
63
+
64
+ raise_zmq_err(format('error while saving to the file %s', path))
52
65
  end
53
66
 
67
+
54
68
  # Reload config tree from same file that it was previously loaded from.
55
69
  # @raise [TypeError] if this is an in-memory config
56
70
  # @raise [SystemCallError] if this fails (no existing data will be
@@ -62,11 +76,13 @@ module CZTop::Config::Serialization
62
76
  # swap out the FFI delegate.
63
77
  filename = filename() or
64
78
  raise TypeError, "can't reload in-memory config"
65
- ptr = CZMQ::FFI::Zconfig.load(filename)
79
+ ptr = CZMQ::FFI::Zconfig.load(filename)
66
80
  return attach_ffi_delegate(ptr) unless ptr.null?
67
- raise_zmq_err("error while reloading from the file %p" % filename)
81
+
82
+ raise_zmq_err(format('error while reloading from the file %p', filename))
68
83
  end
69
84
 
85
+
70
86
  # Serialize (marshal) this Config and all its children.
71
87
  #
72
88
  # @note This method is automatically used by Marshal.dump.
@@ -74,9 +90,13 @@ module CZTop::Config::Serialization
74
90
  def _dump(_level)
75
91
  to_s
76
92
  end
93
+
77
94
  end
78
95
 
96
+
79
97
  class CZTop::Config
98
+
80
99
  include Serialization
81
100
  extend Serialization::ClassMethods
101
+
82
102
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Methods used to traverse a {CZTop::Config} tree.
2
4
  module CZTop::Config::Traversing
3
5
 
@@ -12,24 +14,25 @@ module CZTop::Config::Traversing
12
14
  # @raise [Exception] the block's exception, in case it raises (it won't
13
15
  # call the block any more after that)
14
16
  def execute
15
- raise ArgumentError, "no block given" unless block_given?
16
- exception = nil
17
- block_value = nil
18
- ret = nil
19
- callback = CZMQ::FFI::Zconfig.fct do |zconfig, _arg, level|
17
+ raise ArgumentError, 'no block given' unless block_given?
18
+
19
+ exception = nil
20
+ block_value = nil
21
+ ret = nil
22
+ callback = CZMQ::FFI::Zconfig.fct do |zconfig, _arg, level|
20
23
  begin
21
24
  # NOTE: work around JRuby and Rubinius bug, where it'd keep calling
22
25
  # this FFI::Function, even when the block `break`ed
23
26
  if ret != -1
24
- config = from_ffi_delegate(zconfig)
27
+ config = from_ffi_delegate(zconfig)
25
28
  block_value = yield config, level
26
- ret = 0 # report success to keep zconfig_execute() going
29
+ ret = 0 # report success to keep zconfig_execute() going
27
30
  end
28
- rescue
31
+ rescue StandardError
29
32
  # remember exception, so we can raise it later to the ruby code
30
33
  # (it can't be raised now, as we have to report failure to
31
34
  # zconfig_execute())
32
- exception = $!
35
+ exception = $ERROR_INFO
33
36
 
34
37
  ret = -1 # report failure to stop zconfig_execute() immediately
35
38
  ensure
@@ -39,15 +42,18 @@ module CZTop::Config::Traversing
39
42
  end
40
43
  ffi_delegate.execute(callback, _arg = nil)
41
44
  raise exception if exception
42
- return block_value
45
+
46
+ block_value
43
47
  end
44
48
 
49
+
45
50
  # Access to this config item's direct children.
46
51
  # @return [ChildrenAccessor]
47
52
  def children
48
53
  ChildrenAccessor.new(self)
49
54
  end
50
55
 
56
+
51
57
  # Access to this config item's siblings.
52
58
  # @note Only the "younger" (later in the ZPL file) config items are
53
59
  # considered.
@@ -56,9 +62,11 @@ module CZTop::Config::Traversing
56
62
  SiblingsAccessor.new(self)
57
63
  end
58
64
 
65
+
59
66
  # Used to give access to a {Config} item's children or siblings.
60
67
  # @abstract
61
68
  class FamilyAccessor
69
+
62
70
  include Enumerable
63
71
 
64
72
  # @param config [Config] the relative starting point (either parent or
@@ -67,25 +75,30 @@ module CZTop::Config::Traversing
67
75
  @config = config
68
76
  end
69
77
 
78
+
70
79
  # This is supposed to return the first relevant config item.
71
80
  # @abstract
72
81
  # @return [Config, nil]
73
82
  def first; end
74
83
 
84
+
75
85
  # Yields all direct children/younger siblings. Starts with {#first}, if
76
86
  # set.
77
87
  # @yieldparam config [Config]
78
88
  def each
79
- current = first()
89
+ current = first
80
90
  return if current.nil?
91
+
81
92
  yield current
82
- current_delegate = current.ffi_delegate
93
+ current_delegate = current.ffi_delegate
83
94
  while current_delegate = current_delegate.next
84
95
  break if current_delegate.null?
96
+
85
97
  yield CZTop::Config.from_ffi_delegate(current_delegate)
86
98
  end
87
99
  end
88
100
 
101
+
89
102
  # Recursively compares these config items with the ones of the other.
90
103
  # @param other [FamilyAccessor]
91
104
  def ==(other)
@@ -94,30 +107,39 @@ module CZTop::Config::Traversing
94
107
  these.size == those.size && these.zip(those) do |this, that|
95
108
  this.tree_equal?(that) or return false
96
109
  end
97
- return true
110
+ true
98
111
  end
112
+
99
113
  end
100
114
 
115
+
101
116
  # Accesses the younger siblings of a given {Config} item.
102
117
  class SiblingsAccessor < FamilyAccessor
118
+
103
119
  # Returns the first sibling.
104
120
  # @return [Config]
105
121
  # @return [nil] if no younger siblings
106
122
  def first
107
123
  ptr = @config.ffi_delegate.next
108
124
  return nil if ptr.null?
125
+
109
126
  CZTop::Config.from_ffi_delegate(ptr)
110
127
  end
128
+
111
129
  end
112
130
 
131
+
113
132
  # Accesses the direct children of a given {Config} item.
114
133
  class ChildrenAccessor < FamilyAccessor
134
+
115
135
  def first
116
136
  ptr = @config.ffi_delegate.child
117
137
  return nil if ptr.null?
138
+
118
139
  CZTop::Config.from_ffi_delegate(ptr)
119
140
  end
120
141
 
142
+
121
143
  # Adds a new Config item and yields it, so it can be configured in
122
144
  # a block.
123
145
  # @param name [String] name for new config item
@@ -129,8 +151,10 @@ module CZTop::Config::Traversing
129
151
  yield config if block_given?
130
152
  config
131
153
  end
154
+
132
155
  end
133
156
 
157
+
134
158
  # Finds a config item along a path, relative to the current item.
135
159
  # @param path [String] path (leading slash is optional and will be
136
160
  # ignored)
@@ -139,19 +163,26 @@ module CZTop::Config::Traversing
139
163
  def locate(path)
140
164
  ptr = ffi_delegate.locate(path)
141
165
  return nil if ptr.null?
166
+
142
167
  from_ffi_delegate(ptr)
143
168
  end
144
169
 
170
+
145
171
  # Finds last item at given level (0 = root).
146
172
  # @return [Config] the last config item at given level
147
173
  # @return [nil] if there's no config item at given level
148
174
  def last_at_depth(level)
149
175
  ptr = ffi_delegate.at_depth(level)
150
176
  return nil if ptr.null?
177
+
151
178
  from_ffi_delegate(ptr)
152
179
  end
180
+
153
181
  end
154
182
 
183
+
155
184
  class CZTop::Config
185
+
156
186
  include Traversing
187
+
157
188
  end
data/lib/cztop/config.rb CHANGED
@@ -1,11 +1,14 @@
1
- module CZTop
1
+ # frozen_string_literal: true
2
2
 
3
+ module CZTop
3
4
  # Represents a CZMQ::FFI::Zconfig item.
4
5
  # @see http://rfc.zeromq.org/spec:4/ZPL
5
6
  class Config
7
+
6
8
  include HasFFIDelegate
7
9
  extend CZTop::HasFFIDelegate::ClassMethods
8
10
 
11
+
9
12
  # Initializes a new {Config} item. Takes an optional block to initialize
10
13
  # the item further.
11
14
  # @param name [String] config item name
@@ -17,7 +20,7 @@ module CZTop
17
20
  # {Config} object is garbage collected).
18
21
  def initialize(name = nil, value = nil, parent: nil)
19
22
  if parent
20
- parent = parent.ffi_delegate if parent.is_a?(Config)
23
+ parent = parent.ffi_delegate if parent.is_a?(Config)
21
24
  delegate = ::CZMQ::FFI::Zconfig.new(name, parent)
22
25
  attach_ffi_delegate(delegate)
23
26
 
@@ -42,9 +45,11 @@ module CZTop
42
45
  def name
43
46
  ptr = ffi_delegate.name
44
47
  return nil if ptr.null? # NOTE: for unnamed elements
48
+
45
49
  ptr.read_string
46
50
  end
47
51
 
52
+
48
53
  # Sets a new name.
49
54
  # @param new_name [String, #to_s]
50
55
  # @return [new_name]
@@ -52,28 +57,33 @@ module CZTop
52
57
  ffi_delegate.set_name(new_name.to_s)
53
58
  end
54
59
 
60
+
55
61
  # Get the value of the config item.
56
62
  # @return [String]
57
63
  # @note This returns an empty string if the value is unset.
58
64
  def value
59
65
  ptr = ffi_delegate.value
60
- return "" if ptr.null? # NOTE: for root elements
66
+ return '' if ptr.null? # NOTE: for root elements
67
+
61
68
  ptr.read_string
62
69
  end
63
70
 
71
+
64
72
  # Set or update the value of the config item.
65
73
  # @param new_value [String, #to_s]
66
74
  # @return [new_value]
67
75
  def value=(new_value)
68
- ffi_delegate.set_value("%s", :string, new_value.to_s)
76
+ ffi_delegate.set_value('%s', :string, new_value.to_s)
69
77
  end
70
78
 
79
+
71
80
  # Inspects this {Config} item.
72
81
  # @return [String] shows class, name, and value
73
82
  def inspect
74
83
  "#<#{self.class.name}: name=#{name.inspect} value=#{value.inspect}>"
75
84
  end
76
85
 
86
+
77
87
  # Update the value of a config item by path.
78
88
  # @param path [String, #to_s] path to config item
79
89
  # @param value [String, #to_s] path to config item
@@ -81,7 +91,7 @@ module CZTop
81
91
  def []=(path, value)
82
92
  ffi_delegate.put(path.to_s, value.to_s)
83
93
  end
84
- alias_method :put, :[]=
94
+ alias put []=
85
95
 
86
96
  # Get the value of the current config item.
87
97
  # @param path [String, #to_s] path to config item
@@ -92,30 +102,34 @@ module CZTop
92
102
  # @note The default value is not returned when the config item exists but
93
103
  # just doesn't have a value. In that case, it'll return the empty
94
104
  # string.
95
- def [](path, default = "")
105
+ def [](path, default = '')
96
106
  ptr = ffi_delegate.get(path, default)
97
107
  return nil if ptr.null?
108
+
98
109
  ptr.read_string
99
110
  end
100
- alias_method :get, :[]
111
+ alias get []
101
112
 
102
113
  # @!endgroup
103
114
 
115
+
104
116
  # Compares this config item to another. Only the name and value are
105
117
  # considered. If you need to compare a config tree, use {#tree_equal?}.
106
118
  # @param other [Config] the other config item
107
119
  # @return [Boolean] whether they're equal
108
120
  def ==(other)
109
121
  name == other.name &&
110
- value == other.value
122
+ value == other.value
111
123
  end
112
124
 
125
+
113
126
  # Compares this config tree to another tree or subtree. Names, values, and
114
127
  # children are considered.
115
128
  # @param other [Config] the other config tree
116
129
  # @return [Boolean] whether they're equal
117
130
  def tree_equal?(other)
118
- self == other && self.children == other.children
131
+ self == other && children == other.children
119
132
  end
133
+
120
134
  end
121
135
  end