rbs 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,9 +4,34 @@ module RBS
4
4
  attr_reader :self_class
5
5
  attr_reader :builder
6
6
 
7
- def initialize(self_class:, builder:)
7
+ def initialize(self_class:, builder:, sampling:)
8
8
  @self_class = self_class
9
9
  @builder = builder
10
+ @sampling = sampling
11
+ end
12
+
13
+ def overloaded_call(method, method_name, call, errors:)
14
+ es = method.method_types.map do |method_type|
15
+ es = method_call(method_name, method_type, call, errors: [])
16
+
17
+ if es.empty?
18
+ return errors
19
+ else
20
+ es
21
+ end
22
+ end
23
+
24
+ if es.size == 1
25
+ errors.push(*es[0])
26
+ else
27
+ errors << Errors::UnresolvedOverloadingError.new(
28
+ klass: self_class,
29
+ method_name: method_name,
30
+ method_types: method.method_types
31
+ )
32
+ end
33
+
34
+ errors
10
35
  end
11
36
 
12
37
  def method_call(method_name, method_type, call, errors:)
@@ -56,7 +81,7 @@ module RBS
56
81
  end
57
82
 
58
83
  def return(method_name, method_type, fun, call, errors, return_error:)
59
- unless call.exception
84
+ if call.return?
60
85
  unless value(call.return_value, fun.return_type)
61
86
  errors << return_error.new(klass: self_class,
62
87
  method_name: method_name,
@@ -151,6 +176,14 @@ module RBS
151
176
  end
152
177
  end
153
178
 
179
+ def sampling?
180
+ !!@sampling
181
+ end
182
+
183
+ def sample(array)
184
+ array.size > 100 && sampling? ? array.sample(100) : array
185
+ end
186
+
154
187
  def value(val, type)
155
188
  case type
156
189
  when Types::Bases::Any
@@ -175,9 +208,14 @@ module RBS
175
208
  klass = Object.const_get(type.name.to_s)
176
209
  case
177
210
  when klass == ::Array
178
- Test.call(val, IS_AP, klass) && val.all? {|v| value(v, type.args[0]) }
211
+ Test.call(val, IS_AP, klass) && sample(val).yield_self do |val|
212
+ val.all? {|v| value(v, type.args[0]) }
213
+ end
179
214
  when klass == ::Hash
180
- Test.call(val, IS_AP, klass) && val.all? {|k, v| value(k, type.args[0]) && value(v, type.args[1]) }
215
+ Test.call(val, IS_AP, klass) && sample(val.keys).yield_self do |keys|
216
+ values = val.values_at(*keys)
217
+ keys.all? {|key| value(key, type.args[0]) } && values.all? {|v| value(v, type.args[1]) }
218
+ end
181
219
  when klass == ::Range
182
220
  Test.call(val, IS_AP, klass) && value(val.begin, type.args[0]) && value(val.end, type.args[0])
183
221
  when klass == ::Enumerator
@@ -198,7 +236,7 @@ module RBS
198
236
  end
199
237
  end
200
238
 
201
- values.all? do |v|
239
+ sample(values).all? do |v|
202
240
  if v.size == 1
203
241
  # Only one block argument.
204
242
  value(v[0], type.args[0]) || value(v, type.args[0])
@@ -1,3 +1,3 @@
1
1
  module RBS
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -85,8 +85,8 @@ module RBS
85
85
  puts "end"
86
86
 
87
87
  when AST::Declarations::Module
88
- self_type = if decl.self_type
89
- " : #{decl.self_type}"
88
+ self_type = unless decl.self_types.empty?
89
+ " : #{decl.self_types.join(", ")}"
90
90
  end
91
91
 
92
92
  write_comment decl.comment
@@ -226,15 +226,11 @@
226
226
  "$ref": "#/definitions/classMember"
227
227
  }
228
228
  },
229
- "self_type": {
230
- "oneOf": [
231
- {
232
- "$ref": "types.json"
233
- },
234
- {
235
- "type": "null"
236
- }
237
- ]
229
+ "self_types": {
230
+ "type": "array",
231
+ "items": {
232
+ "$ref": "#/definitions/moduleSelf"
233
+ }
238
234
  },
239
235
  "annotations": {
240
236
  "type": "array",
@@ -249,7 +245,22 @@
249
245
  "$ref": "location.json"
250
246
  }
251
247
  },
252
- "required": ["declaration", "name", "type_params", "members", "self_type", "annotations", "location", "comment"]
248
+ "required": ["declaration", "name", "type_params", "members", "self_types", "annotations", "location", "comment"]
249
+ },
250
+ "moduleSelf": {
251
+ "type": "object",
252
+ "properties": {
253
+ "name": {
254
+ "type": "string"
255
+ },
256
+ "args": {
257
+ "type": "array",
258
+ "items": {
259
+ "$ref": "types.json"
260
+ }
261
+ }
262
+ },
263
+ "required": ["name", "args"]
253
264
  },
254
265
  "interfaceMember": {
255
266
  "oneOf": [
@@ -269,8 +269,7 @@ class Proc < Object
269
269
  # See also Object\#hash.
270
270
  def hash: () -> Integer
271
271
 
272
- def initialize: () -> void
273
- | () { (*untyped) -> untyped } -> void
272
+ def initialize: () { (*untyped) -> untyped } -> void
274
273
 
275
274
  # Returns `true` for a [Proc](Proc.downloaded.ruby_doc) object for which
276
275
  # argument handling is rigid. Such procs are typically generated by
@@ -0,0 +1,23 @@
1
+ class Logger
2
+ class Formatter
3
+ public
4
+
5
+ attr_accessor datetime_format: String?
6
+
7
+ def call: (String severity, Time time, untyped progname, untyped msg) -> String
8
+
9
+ private
10
+
11
+ def format_datetime: (Time time) -> untyped
12
+
13
+ def initialize: () -> void
14
+
15
+ def msg2str: (String | Exception | untyped msg) -> String
16
+ end
17
+
18
+ interface _Formatter
19
+ def call: (String severity, Time time, untyped progname, untyped msg) -> _ToS
20
+ end
21
+ end
22
+
23
+ Logger::Formatter::Format: String
@@ -0,0 +1,39 @@
1
+ class Logger
2
+ class LogDevice
3
+ # TODO: Write type signature for MonitorMixin
4
+ # include MonitorMixin
5
+
6
+ include Period
7
+
8
+ attr_reader dev: _WriteCloser
9
+ attr_reader filename: String?
10
+
11
+ public
12
+
13
+ def close: () -> nil
14
+
15
+ def reopen: (?logdev log) -> self
16
+
17
+ def write: (untyped message) -> untyped
18
+
19
+ private
20
+
21
+ def add_log_header: (IO file) -> untyped
22
+
23
+ def check_shift_log: () -> untyped
24
+
25
+ def create_logfile: (String filename) -> File
26
+
27
+ def initialize: (?untyped logdev, ?binmode: bool, ?shift_period_suffix: String, ?shift_size: Integer, ?shift_age: Numeric | String) -> void
28
+
29
+ def lock_shift_log: () { () -> untyped } -> untyped
30
+
31
+ def open_logfile: (String filename) -> File
32
+
33
+ def set_dev: (logdev log) -> untyped
34
+
35
+ def shift_log_age: () -> true
36
+
37
+ def shift_log_period: (Time period_end) -> true
38
+ end
39
+ end
@@ -0,0 +1,507 @@
1
+ # ## Description
2
+ #
3
+ # The Logger class provides a simple but sophisticated logging utility that you
4
+ # can use to output messages.
5
+ #
6
+ # The messages have associated levels, such as `INFO` or `ERROR` that indicate
7
+ # their importance. You can then give the Logger a level, and only messages at
8
+ # that level or higher will be printed.
9
+ #
10
+ # The levels are:
11
+ #
12
+ # `UNKNOWN`
13
+ # : An unknown message that should always be logged.
14
+ # `FATAL`
15
+ # : An unhandleable error that results in a program crash.
16
+ # `ERROR`
17
+ # : A handleable error condition.
18
+ # `WARN`
19
+ # : A warning.
20
+ # `INFO`
21
+ # : Generic (useful) information about system operation.
22
+ # `DEBUG`
23
+ # : Low-level information for developers.
24
+ #
25
+ #
26
+ # For instance, in a production system, you may have your Logger set to `INFO`
27
+ # or even `WARN`. When you are developing the system, however, you probably want
28
+ # to know about the program's internal state, and would set the Logger to
29
+ # `DEBUG`.
30
+ #
31
+ # **Note**: Logger does not escape or sanitize any messages passed to it.
32
+ # Developers should be aware of when potentially malicious data (user-input) is
33
+ # passed to Logger, and manually escape the untrusted data:
34
+ #
35
+ # logger.info("User-input: #{input.dump}")
36
+ # logger.info("User-input: %p" % input)
37
+ #
38
+ # You can use #formatter= for escaping all data.
39
+ #
40
+ # original_formatter = Logger::Formatter.new
41
+ # logger.formatter = proc { |severity, datetime, progname, msg|
42
+ # original_formatter.call(severity, datetime, progname, msg.dump)
43
+ # }
44
+ # logger.info(input)
45
+ #
46
+ # ### Example
47
+ #
48
+ # This creates a Logger that outputs to the standard output stream, with a level
49
+ # of `WARN`:
50
+ #
51
+ # require 'logger'
52
+ #
53
+ # logger = Logger.new(STDOUT)
54
+ # logger.level = Logger::WARN
55
+ #
56
+ # logger.debug("Created logger")
57
+ # logger.info("Program started")
58
+ # logger.warn("Nothing to do!")
59
+ #
60
+ # path = "a_non_existent_file"
61
+ #
62
+ # begin
63
+ # File.foreach(path) do |line|
64
+ # unless line =~ /^(\w+) = (.*)$/
65
+ # logger.error("Line in wrong format: #{line.chomp}")
66
+ # end
67
+ # end
68
+ # rescue => err
69
+ # logger.fatal("Caught exception; exiting")
70
+ # logger.fatal(err)
71
+ # end
72
+ #
73
+ # Because the Logger's level is set to `WARN`, only the warning, error, and
74
+ # fatal messages are recorded. The debug and info messages are silently
75
+ # discarded.
76
+ #
77
+ # ### Features
78
+ #
79
+ # There are several interesting features that Logger provides, like auto-rolling
80
+ # of log files, setting the format of log messages, and specifying a program
81
+ # name in conjunction with the message. The next section shows you how to
82
+ # achieve these things.
83
+ #
84
+ # ## HOWTOs
85
+ #
86
+ # ### How to create a logger
87
+ #
88
+ # The options below give you various choices, in more or less increasing
89
+ # complexity.
90
+ #
91
+ # 1. Create a logger which logs messages to STDERR/STDOUT.
92
+ #
93
+ # logger = Logger.new(STDERR)
94
+ # logger = Logger.new(STDOUT)
95
+ #
96
+ # 2. Create a logger for the file which has the specified name.
97
+ #
98
+ # logger = Logger.new('logfile.log')
99
+ #
100
+ # 3. Create a logger for the specified file.
101
+ #
102
+ # file = File.open('foo.log', File::WRONLY | File::APPEND)
103
+ # # To create new logfile, add File::CREAT like:
104
+ # # file = File.open('foo.log', File::WRONLY | File::APPEND | File::CREAT)
105
+ # logger = Logger.new(file)
106
+ #
107
+ # 4. Create a logger which ages the logfile once it reaches a certain size.
108
+ # Leave 10 "old" log files where each file is about 1,024,000 bytes.
109
+ #
110
+ # logger = Logger.new('foo.log', 10, 1024000)
111
+ #
112
+ # 5. Create a logger which ages the logfile daily/weekly/monthly.
113
+ #
114
+ # logger = Logger.new('foo.log', 'daily')
115
+ # logger = Logger.new('foo.log', 'weekly')
116
+ # logger = Logger.new('foo.log', 'monthly')
117
+ #
118
+ #
119
+ # ### How to log a message
120
+ #
121
+ # Notice the different methods (`fatal`, `error`, `info`) being used to log
122
+ # messages of various levels? Other methods in this family are `warn` and
123
+ # `debug`. `add` is used below to log a message of an arbitrary (perhaps
124
+ # dynamic) level.
125
+ #
126
+ # 1. Message in a block.
127
+ #
128
+ # logger.fatal { "Argument 'foo' not given." }
129
+ #
130
+ # 2. Message as a string.
131
+ #
132
+ # logger.error "Argument #{@foo} mismatch."
133
+ #
134
+ # 3. With progname.
135
+ #
136
+ # logger.info('initialize') { "Initializing..." }
137
+ #
138
+ # 4. With severity.
139
+ #
140
+ # logger.add(Logger::FATAL) { 'Fatal error!' }
141
+ #
142
+ #
143
+ # The block form allows you to create potentially complex log messages, but to
144
+ # delay their evaluation until and unless the message is logged. For example,
145
+ # if we have the following:
146
+ #
147
+ # logger.debug { "This is a " + potentially + " expensive operation" }
148
+ #
149
+ # If the logger's level is `INFO` or higher, no debug messages will be logged,
150
+ # and the entire block will not even be evaluated. Compare to this:
151
+ #
152
+ # logger.debug("This is a " + potentially + " expensive operation")
153
+ #
154
+ # Here, the string concatenation is done every time, even if the log level is
155
+ # not set to show the debug message.
156
+ #
157
+ # ### How to close a logger
158
+ #
159
+ # logger.close
160
+ #
161
+ # ### Setting severity threshold
162
+ #
163
+ # 1. Original interface.
164
+ #
165
+ # logger.sev_threshold = Logger::WARN
166
+ #
167
+ # 2. Log4r (somewhat) compatible interface.
168
+ #
169
+ # logger.level = Logger::INFO
170
+ #
171
+ # # DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN
172
+ #
173
+ # 3. Symbol or String (case insensitive)
174
+ #
175
+ # logger.level = :info
176
+ # logger.level = 'INFO'
177
+ #
178
+ # # :debug < :info < :warn < :error < :fatal < :unknown
179
+ #
180
+ # 4. Constructor
181
+ #
182
+ # Logger.new(logdev, level: Logger::INFO)
183
+ # Logger.new(logdev, level: :info)
184
+ # Logger.new(logdev, level: 'INFO')
185
+ #
186
+ #
187
+ # ## Format
188
+ #
189
+ # Log messages are rendered in the output stream in a certain format by default.
190
+ # The default format and a sample are shown below:
191
+ #
192
+ # Log format:
193
+ # SeverityID, [DateTime #pid] SeverityLabel -- ProgName: message
194
+ #
195
+ # Log sample:
196
+ # I, [1999-03-03T02:34:24.895701 #19074] INFO -- Main: info.
197
+ #
198
+ # You may change the date and time format via #datetime_format=.
199
+ #
200
+ # logger.datetime_format = '%Y-%m-%d %H:%M:%S'
201
+ # # e.g. "2004-01-03 00:54:26"
202
+ #
203
+ # or via the constructor.
204
+ #
205
+ # Logger.new(logdev, datetime_format: '%Y-%m-%d %H:%M:%S')
206
+ #
207
+ # Or, you may change the overall format via the #formatter= method.
208
+ #
209
+ # logger.formatter = proc do |severity, datetime, progname, msg|
210
+ # "#{datetime}: #{msg}\n"
211
+ # end
212
+ # # e.g. "2005-09-22 08:51:08 +0900: hello world"
213
+ #
214
+ # or via the constructor.
215
+ #
216
+ # Logger.new(logdev, formatter: proc {|severity, datetime, progname, msg|
217
+ # "#{datetime}: #{msg}\n"
218
+ # })
219
+ #
220
+ class Logger
221
+ interface _WriteCloser
222
+ def write: (_ToS) -> untyped
223
+
224
+ def close: () -> untyped
225
+ end
226
+ type logdev = _WriteCloser | String
227
+
228
+ include Logger::Severity
229
+
230
+ public
231
+
232
+ # Dump given message to the log device without any formatting. If no log device
233
+ # exists, return `nil`.
234
+ #
235
+ def <<: (untyped msg) -> (untyped | nil)
236
+
237
+ # ### Args
238
+ #
239
+ # `severity`
240
+ # : Severity. Constants are defined in Logger namespace: `DEBUG`, `INFO`,
241
+ # `WARN`, `ERROR`, `FATAL`, or `UNKNOWN`.
242
+ # `message`
243
+ # : The log message. A String or Exception.
244
+ # `progname`
245
+ # : Program name string. Can be omitted. Treated as a message if no
246
+ # `message` and `block` are given.
247
+ # `block`
248
+ # : Can be omitted. Called to get a message string if `message` is nil.
249
+ #
250
+ #
251
+ # ### Return
252
+ #
253
+ # When the given severity is not high enough (for this particular logger), log
254
+ # no message, and return `true`.
255
+ #
256
+ # ### Description
257
+ #
258
+ # Log a message if the given severity is high enough. This is the generic
259
+ # logging method. Users will be more inclined to use #debug, #info, #warn,
260
+ # #error, and #fatal.
261
+ #
262
+ # **Message format**: `message` can be any object, but it has to be converted to
263
+ # a String in order to log it. Generally, `inspect` is used if the given object
264
+ # is not a String. A special case is an `Exception` object, which will be
265
+ # printed in detail, including message, class, and backtrace. See #msg2str for
266
+ # the implementation if required.
267
+ #
268
+ # ### Bugs
269
+ #
270
+ # * Logfile is not locked.
271
+ # * Append open does not need to lock file.
272
+ # * If the OS supports multi I/O, records possibly may be mixed.
273
+ #
274
+ def add: (Integer severity, ?untyped message, ?untyped progname) ?{ () -> untyped } -> true
275
+
276
+ # Close the logging device.
277
+ #
278
+ def close: () -> untyped
279
+
280
+ # Returns the date format being used. See #datetime_format=
281
+ #
282
+ def datetime_format: () -> String?
283
+
284
+ # Set date-time format.
285
+ #
286
+ # `datetime_format`
287
+ # : A string suitable for passing to `strftime`.
288
+ #
289
+ def datetime_format=: (String datetime_format) -> String
290
+ | (nil datetime_format) -> nil
291
+
292
+ # Log a `DEBUG` message.
293
+ #
294
+ # See #info for more information.
295
+ #
296
+ def debug: (?untyped progname) ?{ () -> untyped } -> true
297
+
298
+ # Sets the severity to DEBUG.
299
+ #
300
+ def debug!: () -> Integer
301
+
302
+ # Returns `true` iff the current severity level allows for the printing of
303
+ # `DEBUG` messages.
304
+ #
305
+ def debug?: () -> bool
306
+
307
+ # Log an `ERROR` message.
308
+ #
309
+ # See #info for more information.
310
+ #
311
+ def error: (?untyped progname) ?{ () -> untyped } -> true
312
+
313
+ # Sets the severity to ERROR.
314
+ #
315
+ def error!: () -> Integer
316
+
317
+ # Returns `true` iff the current severity level allows for the printing of
318
+ # `ERROR` messages.
319
+ #
320
+ def error?: () -> bool
321
+
322
+ # Log a `FATAL` message.
323
+ #
324
+ # See #info for more information.
325
+ #
326
+ def fatal: (?untyped progname) ?{ () -> untyped } -> true
327
+
328
+ # Sets the severity to FATAL.
329
+ #
330
+ def fatal!: () -> Integer
331
+
332
+ # Returns `true` iff the current severity level allows for the printing of
333
+ # `FATAL` messages.
334
+ #
335
+ def fatal?: () -> bool
336
+
337
+ # Logging formatter, as a `Proc` that will take four arguments and return the
338
+ # formatted message. The arguments are:
339
+ #
340
+ # `severity`
341
+ # : The Severity of the log message.
342
+ # `time`
343
+ # : A Time instance representing when the message was logged.
344
+ # `progname`
345
+ # : The #progname configured, or passed to the logger method.
346
+ # `msg`
347
+ # : The *Object* the user passed to the log message; not necessarily a String.
348
+ #
349
+ #
350
+ # The block should return an Object that can be written to the logging device
351
+ # via `write`. The default formatter is used when no formatter is set.
352
+ #
353
+ def formatter: () -> (_Formatter | nil)
354
+
355
+ def formatter=: (_Formatter) -> _Formatter
356
+ | (nil) -> nil
357
+
358
+ # Log an `INFO` message.
359
+ #
360
+ # `message`
361
+ # : The message to log; does not need to be a String.
362
+ # `progname`
363
+ # : In the block form, this is the #progname to use in the log message. The
364
+ # default can be set with #progname=.
365
+ # `block`
366
+ # : Evaluates to the message to log. This is not evaluated unless the
367
+ # logger's level is sufficient to log the message. This allows you to
368
+ # create potentially expensive logging messages that are only called when
369
+ # the logger is configured to show them.
370
+ #
371
+ #
372
+ # ### Examples
373
+ #
374
+ # logger.info("MainApp") { "Received connection from #{ip}" }
375
+ # # ...
376
+ # logger.info "Waiting for input from user"
377
+ # # ...
378
+ # logger.info { "User typed #{input}" }
379
+ #
380
+ # You'll probably stick to the second form above, unless you want to provide a
381
+ # program name (which you can do with #progname= as well).
382
+ #
383
+ # ### Return
384
+ #
385
+ # See #add.
386
+ #
387
+ def info: (?untyped progname) ?{ () -> untyped } -> true
388
+
389
+ # Sets the severity to INFO.
390
+ #
391
+ def info!: () -> Integer
392
+
393
+ # Returns `true` iff the current severity level allows for the printing of
394
+ # `INFO` messages.
395
+ #
396
+ def info?: () -> bool
397
+
398
+ # Logging severity threshold (e.g. `Logger::INFO`).
399
+ #
400
+ def level: () -> Integer
401
+
402
+ # Set logging severity threshold.
403
+ #
404
+ # `severity`
405
+ # : The Severity of the log message.
406
+ #
407
+ #
408
+ def level=: (Integer | String severity) -> Integer
409
+
410
+ alias log add
411
+
412
+ # Program name to include in log messages.
413
+ #
414
+ def progname: () -> untyped
415
+
416
+ def progname=: (untyped) -> untyped
417
+
418
+ # ### Args
419
+ #
420
+ # `logdev`
421
+ # : The log device. This is a filename (String) or IO object (typically
422
+ # `STDOUT`, `STDERR`, or an open file). reopen the same filename if it is
423
+ # `nil`, do nothing for IO. Default is `nil`.
424
+ #
425
+ #
426
+ # ### Description
427
+ #
428
+ # Reopen a log device.
429
+ #
430
+ def reopen: () -> self
431
+ | (logdev?) -> self
432
+
433
+ # Logging severity threshold (e.g. `Logger::INFO`).
434
+ #
435
+ alias sev_threshold level
436
+
437
+ alias sev_threshold= level=
438
+
439
+ # Log an `UNKNOWN` message. This will be printed no matter what the logger's
440
+ # level is.
441
+ #
442
+ # See #info for more information.
443
+ #
444
+ def unknown: (?untyped progname) ?{ () -> untyped } -> true
445
+
446
+ # Log a `WARN` message.
447
+ #
448
+ # See #info for more information.
449
+ #
450
+ def warn: (?untyped progname) ?{ () -> untyped } -> true
451
+
452
+ # Sets the severity to WARN.
453
+ #
454
+ def warn!: () -> Integer
455
+
456
+ # Returns `true` iff the current severity level allows for the printing of
457
+ # `WARN` messages.
458
+ #
459
+ def warn?: () -> bool
460
+
461
+ private
462
+
463
+ def format_message: (String severity, Time datetime, untyped progname, untyped msg) -> _ToS
464
+
465
+ def format_severity: (Integer severity) -> String
466
+
467
+ # ### Args
468
+ #
469
+ # `logdev`
470
+ # : The log device. This is a filename (String) or IO object (typically
471
+ # `STDOUT`, `STDERR`, or an open file).
472
+ # `shift_age`
473
+ # : Number of old log files to keep, **or** frequency of rotation (`daily`,
474
+ # `weekly` or `monthly`). Default value is 0, which disables log file
475
+ # rotation.
476
+ # `shift_size`
477
+ # : Maximum logfile size in bytes (only applies when `shift_age` is a positive
478
+ # Integer). Defaults to `1048576` (1MB).
479
+ # `level`
480
+ # : Logging severity threshold. Default values is Logger::DEBUG.
481
+ # `progname`
482
+ # : Program name to include in log messages. Default value is nil.
483
+ # `formatter`
484
+ # : Logging formatter. Default values is an instance of Logger::Formatter.
485
+ # `datetime_format`
486
+ # : Date and time format. Default value is '%Y-%m-%d %H:%M:%S'.
487
+ # `binmode`
488
+ # : Use binary mode on the log device. Default value is false.
489
+ # `shift_period_suffix`
490
+ # : The log file suffix format for `daily`, `weekly` or `monthly` rotation.
491
+ # Default is '%Y%m%d'.
492
+ #
493
+ #
494
+ # ### Description
495
+ #
496
+ # Create an instance.
497
+ #
498
+ def initialize: (logdev logdev, ?Numeric | String shift_age, ?Integer shift_size, ?shift_period_suffix: String, ?binmode: bool, ?datetime_format: String, ?formatter: _Formatter, ?progname: String, ?level: Integer) -> void
499
+ end
500
+
501
+ Logger::ProgName: String
502
+
503
+ # Severity label for logging (max 5 chars).
504
+ #
505
+ Logger::SEV_LABEL: Array[String]
506
+
507
+ Logger::VERSION: String