rbs 1.2.1 → 1.3.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.
data/lib/rbs/parser.y CHANGED
@@ -1,5 +1,5 @@
1
1
  class RBS::Parser
2
- token tUIDENT tLIDENT tNAMESPACE tINTERFACEIDENT tGLOBALIDENT
2
+ token tUIDENT tLIDENT tUNDERSCOREIDENT tNAMESPACE tINTERFACEIDENT tGLOBALIDENT
3
3
  tLKEYWORD tUKEYWORD tLKEYWORD_Q_E tUKEYWORD_Q_E
4
4
  tIVAR tCLASSVAR
5
5
  tANNOTATION
@@ -12,6 +12,7 @@ class RBS::Parser
12
12
  kPREPEND kEXTENSION kINCOMPATIBLE
13
13
  type_TYPE type_SIGNATURE type_METHODTYPE tEOF
14
14
  kOUT kIN kUNCHECKED kOVERLOAD
15
+ kUNDERSCORE
15
16
 
16
17
  prechigh
17
18
  nonassoc kQUESTION
@@ -1326,7 +1327,7 @@ rule
1326
1327
  }
1327
1328
 
1328
1329
  var_name_opt:
1329
- | tLIDENT | tINTERFACEIDENT | tQUOTEDIDENT
1330
+ | tLIDENT | tINTERFACEIDENT | tQUOTEDIDENT | tUNDERSCOREIDENT | kUNDERSCORE
1330
1331
 
1331
1332
  qualified_name:
1332
1333
  namespace simple_name {
@@ -1713,12 +1714,16 @@ def next_token
1713
1714
  new_token(:tIVAR, input.matched.to_sym)
1714
1715
  when input.scan(/@@[a-zA-Z_]\w*/)
1715
1716
  new_token(:tCLASSVAR, input.matched.to_sym)
1716
- when input.scan(/_[a-zA-Z]\w*\b/)
1717
+ when input.scan(/_[A-Z]\w*\b/)
1717
1718
  new_token(:tINTERFACEIDENT)
1718
1719
  when input.scan(/[A-Z]\w*\b/)
1719
1720
  new_token(:tUIDENT)
1720
- when input.scan(/[a-z_]\w*\b/)
1721
+ when input.scan(/[a-z]\w*\b/)
1721
1722
  new_token(:tLIDENT)
1723
+ when input.scan(/_[a-z]\w*\b/)
1724
+ new_token(:tUNDERSCOREIDENT)
1725
+ when input.scan(/_/)
1726
+ new_token(:kUNDERSCORE)
1722
1727
  when input.scan(/"(\\"|[^"])*"/)
1723
1728
  s = input.matched.yield_self {|s| s[1, s.length - 2] }
1724
1729
  .gsub(DBL_QUOTE_STR_ESCAPE_SEQUENCES_RE) do |match|
@@ -148,7 +148,7 @@ module RBS
148
148
  types = [
149
149
  MethodType.new(
150
150
  type_params: [],
151
- type: function_type_from_body(def_body),
151
+ type: function_type_from_body(def_body, def_name),
152
152
  block: block_from_body(def_body),
153
153
  location: nil
154
154
  )
@@ -377,12 +377,16 @@ module RBS
377
377
  each_node node.children, &block
378
378
  end
379
379
 
380
- def function_type_from_body(node)
380
+ def function_type_from_body(node, def_name)
381
381
  table_node, args_node, *_ = node.children
382
382
 
383
383
  pre_num, _pre_init, opt, _first_post, post_num, _post_init, rest, kw, kwrest, _block = args_from_node(args_node)
384
384
 
385
- return_type = function_return_type_from_body(node)
385
+ return_type = if def_name == :initialize
386
+ Types::Bases::Void.new(location: nil)
387
+ else
388
+ function_return_type_from_body(node)
389
+ end
386
390
 
387
391
  fun = Types::Function.empty(return_type)
388
392
 
@@ -9,6 +9,7 @@ module RBS
9
9
  def initialize(patterns:, env:, merge:, owners_included: [])
10
10
  @patterns = patterns
11
11
  @decls = nil
12
+ @modules = []
12
13
  @env = env
13
14
  @merge = merge
14
15
  @owners_included = owners_included.map do |name|
@@ -39,7 +40,8 @@ module RBS
39
40
  def decls
40
41
  unless @decls
41
42
  @decls = []
42
- ObjectSpace.each_object(Module).select {|mod| target?(mod) }.sort_by{|mod| const_name(mod) }.each do |mod|
43
+ @modules = ObjectSpace.each_object(Module).to_a
44
+ @modules.select {|mod| target?(mod) }.sort_by{|mod| const_name(mod) }.each do |mod|
43
45
  case mod
44
46
  when Class
45
47
  generate_class mod
@@ -48,16 +50,21 @@ module RBS
48
50
  end
49
51
  end
50
52
  end
53
+
51
54
  @decls
52
55
  end
53
56
 
54
- def to_type_name(name)
57
+ def to_type_name(name, full_name: false)
55
58
  *prefix, last = name.split(/::/)
56
59
 
57
- if prefix.empty?
58
- TypeName.new(name: last.to_sym, namespace: Namespace.empty)
60
+ if full_name
61
+ if prefix.empty?
62
+ TypeName.new(name: last.to_sym, namespace: Namespace.empty)
63
+ else
64
+ TypeName.new(name: last.to_sym, namespace: Namespace.parse(prefix.join("::")))
65
+ end
59
66
  else
60
- TypeName.new(name: last.to_sym, namespace: Namespace.parse(prefix.join("::")))
67
+ TypeName.new(name: last.to_sym, namespace: Namespace.empty)
61
68
  end
62
69
  end
63
70
 
@@ -131,6 +138,11 @@ module RBS
131
138
  end
132
139
  end
133
140
 
141
+ return_type = if method.name == :initialize
142
+ Types::Bases::Void.new(location: nil)
143
+ else
144
+ untyped
145
+ end
134
146
  method_type = Types::Function.new(
135
147
  required_positionals: required_positionals,
136
148
  optional_positionals: optional_positionals,
@@ -139,7 +151,7 @@ module RBS
139
151
  required_keywords: required_keywords,
140
152
  optional_keywords: optional_keywords,
141
153
  rest_keywords: rest_keywords,
142
- return_type: untyped
154
+ return_type: return_type,
143
155
  )
144
156
 
145
157
  MethodType.new(
@@ -300,7 +312,7 @@ module RBS
300
312
  end
301
313
  end
302
314
 
303
- def generate_constants(mod)
315
+ def generate_constants(mod, decls)
304
316
  mod.constants(false).sort.each do |name|
305
317
  value = mod.const_get(name)
306
318
 
@@ -324,8 +336,8 @@ module RBS
324
336
  Types::ClassInstance.new(name: value_type_name, args: args, location: nil)
325
337
  end
326
338
 
327
- @decls << AST::Declarations::Constant.new(
328
- name: "#{const_name(mod)}::#{name}",
339
+ decls << AST::Declarations::Constant.new(
340
+ name: name,
329
341
  type: type,
330
342
  location: nil,
331
343
  comment: nil
@@ -333,28 +345,38 @@ module RBS
333
345
  end
334
346
  end
335
347
 
348
+ def generate_super_class(mod)
349
+ if mod.superclass == ::Object
350
+ nil
351
+ elsif const_name(mod.superclass).nil?
352
+ RBS.logger.warn("Skipping anonymous superclass #{mod.superclass} of #{mod}")
353
+ nil
354
+ else
355
+ super_name = to_type_name(const_name(mod.superclass), full_name: true)
356
+ super_args = type_args(super_name)
357
+ AST::Declarations::Class::Super.new(name: super_name, args: super_args, location: nil)
358
+ end
359
+ end
360
+
336
361
  def generate_class(mod)
337
362
  type_name = to_type_name(const_name(mod))
338
- super_class = if mod.superclass == ::Object
339
- nil
340
- elsif const_name(mod.superclass).nil?
341
- RBS.logger.warn("Skipping anonymous superclass #{mod.superclass} of #{mod}")
342
- nil
343
- else
344
- super_name = to_type_name(const_name(mod.superclass))
345
- super_args = type_args(super_name)
346
- AST::Declarations::Class::Super.new(name: super_name, args: super_args, location: nil)
347
- end
363
+ outer_decls = ensure_outer_module_declarations(mod)
364
+
365
+ # Check if a declaration exists for the actual module
366
+ decl = outer_decls.detect { |decl| decl.is_a?(AST::Declarations::Class) && decl.name.name == only_name(mod).to_sym }
367
+ unless decl
368
+ decl = AST::Declarations::Class.new(
369
+ name: to_type_name(only_name(mod)),
370
+ type_params: AST::Declarations::ModuleTypeParams.empty,
371
+ super_class: generate_super_class(mod),
372
+ members: [],
373
+ annotations: [],
374
+ location: nil,
375
+ comment: nil
376
+ )
348
377
 
349
- decl = AST::Declarations::Class.new(
350
- name: type_name,
351
- type_params: AST::Declarations::ModuleTypeParams.empty,
352
- super_class: super_class,
353
- members: [],
354
- annotations: [],
355
- location: nil,
356
- comment: nil
357
- )
378
+ outer_decls << decl
379
+ end
358
380
 
359
381
  each_included_module(type_name, mod) do |module_name, module_full_name, _|
360
382
  args = type_args(module_full_name)
@@ -380,9 +402,7 @@ module RBS
380
402
 
381
403
  generate_methods(mod, type_name, decl.members)
382
404
 
383
- @decls << decl
384
-
385
- generate_constants mod
405
+ generate_constants mod, decl.members
386
406
  end
387
407
 
388
408
  def generate_module(mod)
@@ -394,16 +414,23 @@ module RBS
394
414
  end
395
415
 
396
416
  type_name = to_type_name(name)
417
+ outer_decls = ensure_outer_module_declarations(mod)
418
+
419
+ # Check if a declaration exists for the actual class
420
+ decl = outer_decls.detect { |decl| decl.is_a?(AST::Declarations::Module) && decl.name.name == only_name(mod).to_sym }
421
+ unless decl
422
+ decl = AST::Declarations::Module.new(
423
+ name: to_type_name(only_name(mod)),
424
+ type_params: AST::Declarations::ModuleTypeParams.empty,
425
+ self_types: [],
426
+ members: [],
427
+ annotations: [],
428
+ location: nil,
429
+ comment: nil
430
+ )
397
431
 
398
- decl = AST::Declarations::Module.new(
399
- name: type_name,
400
- type_params: AST::Declarations::ModuleTypeParams.empty,
401
- self_types: [],
402
- members: [],
403
- annotations: [],
404
- location: nil,
405
- comment: nil
406
- )
432
+ outer_decls << decl
433
+ end
407
434
 
408
435
  each_included_module(type_name, mod) do |module_name, module_full_name, _|
409
436
  args = type_args(module_full_name)
@@ -429,9 +456,58 @@ module RBS
429
456
 
430
457
  generate_methods(mod, type_name, decl.members)
431
458
 
432
- @decls << decl
459
+ generate_constants mod, decl.members
460
+ end
461
+
462
+ # Generate/find outer module declarations
463
+ # This is broken down into another method to comply with `DRY`
464
+ # This generates/finds declarations in nested form & returns the last array of declarations
465
+ def ensure_outer_module_declarations(mod)
466
+ *outer_module_names, _ = const_name(mod).split(/::/) #=> parent = [A, B], mod = C
467
+ destination = @decls # Copy the entries in ivar @decls, not .dup
468
+
469
+ outer_module_names&.each do |outer_module_name|
470
+ outer_module = @modules.detect { |x| const_name(x) == outer_module_name }
471
+ outer_decl = destination.detect { |decl| decl.is_a?(outer_module.is_a?(Class) ? AST::Declarations::Class : AST::Declarations::Module) && decl.name.name == outer_module_name.to_sym }
472
+
473
+ # Insert AST::Declarations if declarations are not added previously
474
+ unless outer_decl
475
+ if outer_module.is_a?(Class)
476
+ outer_decl = AST::Declarations::Class.new(
477
+ name: to_type_name(outer_module_name),
478
+ type_params: AST::Declarations::ModuleTypeParams.empty,
479
+ super_class: generate_super_class(outer_module),
480
+ members: [],
481
+ annotations: [],
482
+ location: nil,
483
+ comment: nil
484
+ )
485
+ else
486
+ outer_decl = AST::Declarations::Module.new(
487
+ name: to_type_name(outer_module_name),
488
+ type_params: AST::Declarations::ModuleTypeParams.empty,
489
+ self_types: [],
490
+ members: [],
491
+ annotations: [],
492
+ location: nil,
493
+ comment: nil
494
+ )
495
+ end
496
+
497
+ destination << outer_decl
498
+ end
499
+
500
+ destination = outer_decl.members
501
+ end
502
+
503
+ # Return the array of declarations checked out at the end
504
+ destination
505
+ end
433
506
 
434
- generate_constants mod
507
+ # Returns the exact name & not compactly declared name
508
+ def only_name(mod)
509
+ # No nil check because this method is invoked after checking if the module exists
510
+ const_name(mod).split(/::/).last # (A::B::C) => C
435
511
  end
436
512
 
437
513
  def const_name(const)
data/lib/rbs/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RBS
2
- VERSION = "1.2.1"
2
+ VERSION = "1.3.0"
3
3
  end
@@ -80,6 +80,7 @@ module RBS
80
80
  def interface_ancestors: (TypeName, ?building_ancestors: Array[Definition::Ancestor::t]) -> Definition::InstanceAncestors
81
81
 
82
82
  def mixin_ancestors: (Environment::ClassEntry | Environment::ModuleEntry,
83
+ TypeName,
83
84
  included_modules: Array[Definition::Ancestor::Instance]?,
84
85
  included_interfaces:Array[Definition::Ancestor::Instance]?,
85
86
  prepended_modules: Array[Definition::Ancestor::Instance]?,
@@ -87,6 +88,7 @@ module RBS
87
88
  extended_interfaces: Array[Definition::Ancestor::Instance]?) -> void
88
89
 
89
90
  def mixin_ancestors0: (AST::Declarations::Class | AST::Declarations::Module | AST::Declarations::Interface,
91
+ TypeName,
90
92
  align_params: Substitution?,
91
93
  included_modules: Array[Definition::Ancestor::Instance]?,
92
94
  included_interfaces:Array[Definition::Ancestor::Instance]?,
data/sig/errors.rbs CHANGED
@@ -181,4 +181,19 @@ module RBS
181
181
 
182
182
  def location: () -> Location?
183
183
  end
184
+
185
+ class MixinClassError < DefinitionError
186
+ type member = AST::Members::Include | AST::Members::Prepend | AST::Members::Extend
187
+
188
+ attr_reader type_name: TypeName
189
+ attr_reader member: member
190
+
191
+ def initialize: (type_name: TypeName, member: member) -> void
192
+
193
+ def location: () -> Location?
194
+
195
+ def self.check!: (type_name: TypeName, env: Environment, member: member) -> void
196
+
197
+ def mixin_name: () -> String
198
+ end
184
199
  end
data/sig/namespace.rbs CHANGED
@@ -13,7 +13,7 @@ module RBS
13
13
  # RBS::Types::Union
14
14
  # ^^^^^^^^^^^^ Namespace
15
15
  #
16
- # Note that `Namespace` is a RBS specific concept and there is no corresponding concept in Ruby.
16
+ # Note that `Namespace` is an RBS specific concept and there is no corresponding concept in Ruby.
17
17
  #
18
18
  # There are _absolute_ and _relative_ namespaces.
19
19
  #
data/sig/polyfill.rbs CHANGED
@@ -11,24 +11,6 @@ module Gem
11
11
  end
12
12
  end
13
13
 
14
- class OptionParser
15
- def initialize: () ?{ (instance) -> void } -> void
16
-
17
- def on: [T] (*String) { (T) -> void } -> void
18
-
19
- attr_accessor version: String
20
-
21
- attr_accessor banner: String
22
-
23
- def order!: (Array[String]) -> void
24
-
25
- def parse!: (Array[String]) -> void
26
-
27
- def ver: () -> String
28
-
29
- def help: () -> String
30
- end
31
-
32
14
  module Enumerable[unchecked out Elem]
33
15
  def flat_map: [U] () { (Elem) -> Array[U] } -> Array[U]
34
16
  | [U] () { (Elem) -> U } -> Array[U]
data/stdlib/dbm/0/dbm.rbs CHANGED
@@ -61,23 +61,24 @@
61
61
  # puts db['822']
62
62
  #
63
63
  class DBM
64
- include Enumerable[untyped]
64
+ include Enumerable[[String, String]]
65
65
 
66
66
  # Open a dbm database and yields it if a block is given. See also `DBM.new`.
67
67
  #
68
- def self.open: (*untyped) -> ::DBM
68
+ def self.open: (String filename, ?Integer mode, ?Integer flags) -> DBM
69
+ | [T] (String filename, ?Integer mode, ?Integer flags) { (DBM) -> T } -> T
69
70
 
70
71
  public
71
72
 
72
73
  # Return a value from the database by locating the key string provided. If the
73
74
  # key is not found, returns nil.
74
75
  #
75
- def []: (untyped) -> untyped
76
+ def []: (String) -> String?
76
77
 
77
78
  # Stores the specified string value in the database, indexed via the string key
78
79
  # provided.
79
80
  #
80
- def []=: (untyped, untyped) -> untyped
81
+ def []=: (String, String) -> String
81
82
 
82
83
  # Deletes all data from the database.
83
84
  #
@@ -85,7 +86,7 @@ class DBM
85
86
 
86
87
  # Closes the database.
87
88
  #
88
- def close: () -> NilClass
89
+ def close: () -> void
89
90
 
90
91
  # Returns true if the database is closed, false otherwise.
91
92
  #
@@ -93,27 +94,31 @@ class DBM
93
94
 
94
95
  # Deletes an entry from the database.
95
96
  #
96
- def delete: (untyped) -> untyped
97
+ def delete: (String) -> void
97
98
 
98
99
  # Deletes all entries for which the code block returns true. Returns self.
99
100
  #
100
- def delete_if: () ?{ (untyped) -> bool } -> self
101
+ def delete_if: () { (String) -> boolish } -> self
101
102
 
102
103
  # Calls the block once for each [key, value] pair in the database. Returns self.
103
104
  #
104
- def each: (?untyped, ?untyped) -> Enumerator[untyped, ::DBM]
105
+ def each: () { ([String, String]) -> void } -> self
106
+ | () -> Enumerator[[String, String], self]
105
107
 
106
108
  # Calls the block once for each key string in the database. Returns self.
107
109
  #
108
- def each_key: () -> Enumerator[String, ::DBM]
110
+ def each_key: { (String) -> void } -> self
111
+ | () -> Enumerator[String, self]
109
112
 
110
113
  # Calls the block once for each [key, value] pair in the database. Returns self.
111
114
  #
112
- def each_pair: (?untyped, ?untyped) -> Enumerator[untyped, ::DBM]
115
+ def each_pair: () { ([String, String]) -> void } -> self
116
+ | () -> Enumerator[[String, String], self]
113
117
 
114
118
  # Calls the block once for each value string in the database. Returns self.
115
119
  #
116
- def each_value: () -> Enumerator[untyped, ::DBM]
120
+ def each_value: () { (String) -> void } -> self
121
+ | () -> Enumerator[String, self]
117
122
 
118
123
  # Returns true if the database is empty, false otherwise.
119
124
  #
@@ -123,7 +128,7 @@ class DBM
123
128
  # key is not found, returns `ifnone`. If `ifnone` is not given, raises
124
129
  # IndexError.
125
130
  #
126
- def fetch: (*String) -> untyped
131
+ def fetch: (String key, ?String ifnone) -> String
127
132
 
128
133
  # Returns true if the database contains the specified key, false otherwise.
129
134
  #
@@ -132,7 +137,7 @@ class DBM
132
137
  # Returns true if the database contains the specified string value, false
133
138
  # otherwise.
134
139
  #
135
- def has_value?: (untyped) -> bool
140
+ def has_value?: () -> bool
136
141
 
137
142
  # Returns true if the database contains the specified key, false otherwise.
138
143
  #
@@ -141,15 +146,15 @@ class DBM
141
146
  # Returns a Hash (not a DBM database) created by using each value in the
142
147
  # database as a key, with the corresponding key as its value.
143
148
  #
144
- def invert: () -> Hash[untyped, String]
149
+ def invert: () -> Hash[String, String]
145
150
 
146
151
  # Returns the key for the specified value.
147
152
  #
148
- def key: (untyped) -> (String | NilClass)
153
+ def key: (String) -> String?
149
154
 
150
155
  # Returns true if the database contains the specified key, false otherwise.
151
156
  #
152
- def key?: (untyped) -> bool
157
+ def key?: (String) -> bool
153
158
 
154
159
  # Returns an array of all the string keys in the database.
155
160
  #
@@ -161,33 +166,37 @@ class DBM
161
166
 
162
167
  # Returns true if the database contains the specified key, false otherwise.
163
168
  #
164
- def member?: (untyped) -> bool
169
+ def member?: (String) -> bool
165
170
 
166
171
  # Converts the contents of the database to an in-memory Hash, then calls
167
172
  # Hash#reject with the specified code block, returning a new Hash.
168
173
  #
169
- def reject: () -> Hash[untyped, untyped]
174
+ def reject: () { (String, String) -> boolish } -> Hash[String, String]
170
175
 
171
176
  # Deletes all entries for which the code block returns true. Returns self.
172
177
  #
173
- def reject!: () { (String, untyped) -> untyped } -> self
178
+ def reject!: () { (String, String) -> boolish } -> self
174
179
 
175
180
  # Replaces the contents of the database with the contents of the specified
176
181
  # object. Takes any object which implements the each_pair method, including Hash
177
182
  # and DBM objects.
178
183
  #
179
- def replace: (untyped) -> ::DBM
184
+ def replace: (_ReplaceSource) -> ::DBM
185
+
186
+ interface _ReplaceSource
187
+ def each_pair: () { ([String, String]) -> void } -> void
188
+ end
180
189
 
181
190
  # Returns a new array consisting of the [key, value] pairs for which the code
182
191
  # block returns true.
183
192
  #
184
- def select: () { () -> untyped } -> Array[untyped]
193
+ def select: () { ([String, String]) -> boolish } -> Array[[String, String]]
185
194
 
186
195
  # Removes a [key, value] pair from the database, and returns it. If the database
187
196
  # is empty, returns nil. The order in which values are removed/returned is not
188
197
  # guaranteed.
189
198
  #
190
- def shift: () -> Array[untyped]
199
+ def shift: () -> [String, String]?
191
200
 
192
201
  # Returns the number of entries in the database.
193
202
  #
@@ -196,35 +205,39 @@ class DBM
196
205
  # Stores the specified string value in the database, indexed via the string key
197
206
  # provided.
198
207
  #
199
- def store: (String, untyped) -> String
208
+ def store: (String, String) -> String
200
209
 
201
210
  # Converts the contents of the database to an array of [key, value] arrays, and
202
211
  # returns it.
203
212
  #
204
- def to_a: () -> Array[untyped]
213
+ def to_a: () -> Array[[String, String]]
205
214
 
206
215
  # Converts the contents of the database to an in-memory Hash object, and returns
207
216
  # it.
208
217
  #
209
- def to_hash: () -> Hash[String, untyped]
218
+ def to_hash: () -> Hash[String, String]
210
219
 
211
220
  # Updates the database with multiple values from the specified object. Takes any
212
221
  # object which implements the each_pair method, including Hash and DBM objects.
213
222
  #
214
- def update: (untyped) -> ::DBM
223
+ def update: (_UpdateSource) -> ::DBM
224
+
225
+ interface _UpdateSource
226
+ def each_pair: () { ([String, String]) -> void } -> void
227
+ end
215
228
 
216
229
  # Returns true if the database contains the specified string value, false
217
230
  # otherwise.
218
231
  #
219
- def value?: (untyped) -> bool
232
+ def value?: (String) -> bool
220
233
 
221
234
  # Returns an array of all the string values in the database.
222
235
  #
223
- def values: () -> Array[untyped]
236
+ def values: () -> Array[String]
224
237
 
225
238
  # Returns an array containing the values associated with the given keys.
226
239
  #
227
- def values_at: (*String) -> Array[untyped]
240
+ def values_at: (*String) -> Array[String]
228
241
 
229
242
  private
230
243
 
@@ -237,7 +250,7 @@ class DBM
237
250
  #
238
251
  # Flags should be one of READER, WRITER, WRCREAT or NEWDB.
239
252
  #
240
- def initialize: (*untyped) -> self
253
+ def initialize: (String filename, ?Integer mode, ?Integer flags) -> void
241
254
  end
242
255
 
243
256
  # Indicates that dbm_open() should open the database in read/write mode, create