rbs 3.1.3 → 3.2.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +0 -6
  3. data/CHANGELOG.md +68 -0
  4. data/Gemfile +0 -6
  5. data/Gemfile.lock +12 -21
  6. data/README.md +1 -1
  7. data/Rakefile +44 -0
  8. data/Steepfile +3 -3
  9. data/core/array.rbs +0 -8
  10. data/core/builtin.rbs +28 -8
  11. data/core/constants.rbs +13 -5
  12. data/core/exception.rbs +1 -1
  13. data/core/global_variables.rbs +27 -27
  14. data/core/io.rbs +163 -172
  15. data/core/kernel.rbs +7 -4
  16. data/core/module.rbs +34 -32
  17. data/core/object.rbs +2 -2
  18. data/core/string_io.rbs +9 -0
  19. data/core/thread.rbs +25 -1
  20. data/core/time.rbs +3 -3
  21. data/docs/CONTRIBUTING.md +1 -1
  22. data/docs/rbs_by_example.md +16 -35
  23. data/docs/repo.md +1 -1
  24. data/docs/sigs.md +7 -7
  25. data/docs/stdlib.md +2 -3
  26. data/docs/syntax.md +40 -40
  27. data/lib/rbs/cli.rb +15 -4
  28. data/lib/rbs/collection/installer.rb +5 -2
  29. data/lib/rbs/collection/sources/stdlib.rb +5 -1
  30. data/lib/rbs/errors.rb +8 -1
  31. data/lib/rbs/file_finder.rb +1 -1
  32. data/lib/rbs/prototype/rb.rb +64 -6
  33. data/lib/rbs/prototype/rbi.rb +2 -6
  34. data/lib/rbs/prototype/runtime.rb +29 -8
  35. data/lib/rbs/subtractor.rb +17 -0
  36. data/lib/rbs/type_name.rb +4 -4
  37. data/lib/rbs/version.rb +1 -1
  38. data/rbs.gemspec +1 -1
  39. data/schema/decls.json +1 -1
  40. data/sig/errors.rbs +54 -0
  41. data/sig/parser.rbs +2 -2
  42. data/sig/prototype/rb.rbs +9 -1
  43. data/sig/subtractor.rbs +4 -0
  44. data/stdlib/logger/0/logger.rbs +1 -1
  45. data/stdlib/observable/0/observable.rbs +219 -0
  46. data/stdlib/uri/0/common.rbs +24 -0
  47. data/stdlib/zlib/0/buf_error.rbs +79 -0
  48. data/stdlib/zlib/0/data_error.rbs +79 -0
  49. data/stdlib/zlib/0/deflate.rbs +276 -0
  50. data/stdlib/zlib/0/error.rbs +89 -0
  51. data/stdlib/zlib/0/gzip_file/crc_error.rbs +115 -0
  52. data/stdlib/zlib/0/gzip_file/error.rbs +128 -0
  53. data/stdlib/zlib/0/gzip_file/length_error.rbs +115 -0
  54. data/stdlib/zlib/0/gzip_file/no_footer.rbs +114 -0
  55. data/stdlib/zlib/0/gzip_file.rbs +228 -0
  56. data/stdlib/zlib/0/gzip_reader.rbs +362 -0
  57. data/stdlib/zlib/0/gzip_writer.rbs +237 -0
  58. data/stdlib/zlib/0/inflate.rbs +249 -0
  59. data/stdlib/zlib/0/mem_error.rbs +79 -0
  60. data/stdlib/zlib/0/need_dict.rbs +82 -0
  61. data/stdlib/zlib/0/stream_end.rbs +80 -0
  62. data/stdlib/zlib/0/stream_error.rbs +80 -0
  63. data/stdlib/zlib/0/version_error.rbs +80 -0
  64. data/stdlib/zlib/0/zstream.rbs +270 -0
  65. metadata +24 -8
  66. data/stdlib/prime/0/integer-extension.rbs +0 -41
  67. data/stdlib/prime/0/manifest.yaml +0 -2
  68. data/stdlib/prime/0/prime.rbs +0 -372
@@ -9,6 +9,7 @@ module RBS
9
9
  attr_reader :env
10
10
  attr_reader :merge
11
11
  attr_reader :owners_included
12
+ attr_accessor :outline
12
13
 
13
14
  def initialize(patterns:, env:, merge:, owners_included: [])
14
15
  @patterns = patterns
@@ -19,6 +20,7 @@ module RBS
19
20
  @owners_included = owners_included.map do |name|
20
21
  Object.const_get(name)
21
22
  end
23
+ @outline = false
22
24
  end
23
25
 
24
26
  def target?(const)
@@ -378,7 +380,7 @@ module RBS
378
380
  RBS.logger.warn("Skipping anonymous superclass #{mod.superclass} of #{mod}")
379
381
  nil
380
382
  else
381
- super_name = to_type_name(const_name(mod.superclass), full_name: true)
383
+ super_name = to_type_name(const_name(mod.superclass), full_name: true).absolute!
382
384
  super_args = type_args(super_name)
383
385
  AST::Declarations::Class::Super.new(name: super_name, args: super_args, location: nil)
384
386
  end
@@ -393,7 +395,7 @@ module RBS
393
395
  unless decl
394
396
  decl = AST::Declarations::Class.new(
395
397
  name: to_type_name(only_name(mod)),
396
- type_params: [],
398
+ type_params: type_params(mod),
397
399
  super_class: generate_super_class(mod),
398
400
  members: [],
399
401
  annotations: [],
@@ -426,7 +428,7 @@ module RBS
426
428
  )
427
429
  end
428
430
 
429
- generate_methods(mod, type_name, decl.members)
431
+ generate_methods(mod, type_name, decl.members) unless outline
430
432
 
431
433
  generate_constants mod, decl.members
432
434
  end
@@ -447,7 +449,7 @@ module RBS
447
449
  unless decl
448
450
  decl = AST::Declarations::Module.new(
449
451
  name: to_type_name(only_name(mod)),
450
- type_params: [],
452
+ type_params: type_params(mod),
451
453
  self_types: [],
452
454
  members: [],
453
455
  annotations: [],
@@ -480,7 +482,7 @@ module RBS
480
482
  )
481
483
  end
482
484
 
483
- generate_methods(mod, type_name, decl.members)
485
+ generate_methods(mod, type_name, decl.members) unless outline
484
486
 
485
487
  generate_constants mod, decl.members
486
488
  end
@@ -502,7 +504,7 @@ module RBS
502
504
  if outer_module.is_a?(Class)
503
505
  outer_decl = AST::Declarations::Class.new(
504
506
  name: to_type_name(outer_module_name),
505
- type_params: [],
507
+ type_params: type_params(outer_module),
506
508
  super_class: generate_super_class(outer_module),
507
509
  members: [],
508
510
  annotations: [],
@@ -512,7 +514,7 @@ module RBS
512
514
  else
513
515
  outer_decl = AST::Declarations::Module.new(
514
516
  name: to_type_name(outer_module_name),
515
- type_params: [],
517
+ type_params: type_params(outer_module),
516
518
  self_types: [],
517
519
  members: [],
518
520
  annotations: [],
@@ -539,7 +541,17 @@ module RBS
539
541
 
540
542
  def const_name(const)
541
543
  @module_name_method ||= Module.instance_method(:name)
542
- @module_name_method.bind(const).call
544
+ name = @module_name_method.bind(const).call
545
+ return nil unless name
546
+
547
+ begin
548
+ Object.const_get(name)
549
+ rescue NameError
550
+ # Should generate const name if anonymous or internal module (e.g. NameError::message)
551
+ nil
552
+ else
553
+ name
554
+ end
543
555
  end
544
556
 
545
557
  def type_args(type_name)
@@ -550,6 +562,15 @@ module RBS
550
562
  end
551
563
  end
552
564
 
565
+ def type_params(mod)
566
+ type_name = to_type_name(const_name(mod), full_name: true)
567
+ if class_decl = env.class_decls[type_name.absolute!]
568
+ class_decl.type_params
569
+ else
570
+ []
571
+ end
572
+ end
573
+
553
574
  def block_from_ast_of(method)
554
575
  return nil if RUBY_VERSION < '3.1'
555
576
 
@@ -51,6 +51,7 @@ module RBS
51
51
  context = _ = [context, decl.name]
52
52
  children = call(decl.each_decl.to_a, context: context) +
53
53
  decl.each_member.reject { |m| member_exist?(owner, m, context: context) }
54
+ children = filter_redundunt_access_modifiers(children)
54
55
  return nil if children.empty?
55
56
 
56
57
  update_decl(decl, members: children)
@@ -144,6 +145,22 @@ module RBS
144
145
  end
145
146
  end
146
147
 
148
+ private def filter_redundunt_access_modifiers(decls)
149
+ decls = decls.dup
150
+ decls.pop while access_modifier?(decls.last)
151
+ decls = decls.map.with_index do |decl, i|
152
+ if access_modifier?(decl) && access_modifier?(decls[i + 1])
153
+ nil
154
+ else
155
+ decl
156
+ end
157
+ end.compact
158
+ end
159
+
160
+ private def access_modifier?(decl)
161
+ decl.is_a?(AST::Members::Public) || decl.is_a?(AST::Members::Private)
162
+ end
163
+
147
164
  private def update_decl(decl, members:)
148
165
  case decl
149
166
  when AST::Declarations::Class
data/lib/rbs/type_name.rb CHANGED
@@ -9,12 +9,12 @@ module RBS
9
9
  def initialize(namespace:, name:)
10
10
  @namespace = namespace
11
11
  @name = name
12
- @kind = case name.to_s[0,1]
13
- when /[A-Z]/
12
+ @kind = case
13
+ when name.match?(/\A[A-Z]/)
14
14
  :class
15
- when /[a-z]/
15
+ when name.match?(/\A[a-z]/)
16
16
  :alias
17
- when "_"
17
+ when name.start_with?("_")
18
18
  :interface
19
19
  else
20
20
  # Defaults to :class
data/lib/rbs/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RBS
4
- VERSION = "3.1.3"
4
+ VERSION = "3.2.0.pre.1"
5
5
  end
data/rbs.gemspec CHANGED
@@ -35,5 +35,5 @@ Gem::Specification.new do |spec|
35
35
  spec.bindir = "exe"
36
36
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
37
37
  spec.require_paths = ["lib"]
38
- spec.required_ruby_version = ">= 2.6"
38
+ spec.required_ruby_version = ">= 3.0"
39
39
  end
data/schema/decls.json CHANGED
@@ -60,7 +60,7 @@
60
60
  "required": ["declaration", "name", "type", "comment", "location"]
61
61
  },
62
62
  "global": {
63
- "title": "Global declaration: `$DEBUG: bool`, ...",
63
+ "title": "Global declaration: `$DEBUG: boolish`, ...",
64
64
  "type": "object",
65
65
  "properties": {
66
66
  "declaration": {
data/sig/errors.rbs CHANGED
@@ -16,9 +16,23 @@ module RBS
16
16
  class BaseError < StandardError
17
17
  end
18
18
 
19
+ interface _Location
20
+ %a{pure} def location: () -> Location[untyped, untyped]?
21
+ end
22
+
23
+ interface _DetailedMessage
24
+ def detailed_message: (**untyped) -> String
25
+ end
26
+
27
+ module DetailedMessageable : _Location, _DetailedMessage
28
+ def detailed_message: (?highlight: boolish, **untyped) -> String
29
+ end
30
+
19
31
  # Error class for errors raised during parsing.
20
32
  #
21
33
  class ParsingError < BaseError
34
+ include DetailedMessageable
35
+
22
36
  attr_reader location: Location[untyped, untyped]
23
37
  attr_reader error_message: String
24
38
  attr_reader token_type: String
@@ -67,6 +81,8 @@ module RBS
67
81
  end
68
82
 
69
83
  class NoTypeFoundError < DefinitionError
84
+ include DetailedMessageable
85
+
70
86
  attr_reader type_name: TypeName
71
87
  attr_reader location: Location[untyped, untyped]?
72
88
 
@@ -85,6 +101,8 @@ module RBS
85
101
  end
86
102
 
87
103
  class NoSelfTypeFoundError < DefinitionError
104
+ include DetailedMessageable
105
+
88
106
  attr_reader type_name: TypeName
89
107
  attr_reader location: Location[untyped, untyped]?
90
108
 
@@ -96,6 +114,8 @@ module RBS
96
114
  end
97
115
 
98
116
  class NoMixinFoundError < DefinitionError
117
+ include DetailedMessageable
118
+
99
119
  attr_reader type_name: TypeName
100
120
  attr_reader member: AST::Members::t
101
121
 
@@ -107,6 +127,8 @@ module RBS
107
127
  end
108
128
 
109
129
  class DuplicatedMethodDefinitionError < DefinitionError
130
+ include DetailedMessageable
131
+
110
132
  type ty = Types::ClassSingleton | Types::ClassInstance | Types::Interface
111
133
  type original = DefinitionBuilder::MethodBuilder::Methods::Definition::original
112
134
 
@@ -143,6 +165,8 @@ module RBS
143
165
  # ```
144
166
  #
145
167
  class DuplicatedInterfaceMethodDefinitionError < DefinitionError
168
+ include DetailedMessageable
169
+
146
170
  type ty = Types::ClassSingleton | Types::ClassInstance | Types::Interface
147
171
  type mixin_member = AST::Members::Include | AST::Members::Extend
148
172
 
@@ -155,11 +179,15 @@ module RBS
155
179
  def type_name: () -> TypeName
156
180
 
157
181
  def qualified_method_name: () -> String
182
+
183
+ def location: () -> AST::Members::Mixin::loc?
158
184
  end
159
185
 
160
186
  # The `alias` member declares an alias from unknown method
161
187
  #
162
188
  class UnknownMethodAliasError < DefinitionError
189
+ include DetailedMessageable
190
+
163
191
  attr_reader type_name: TypeName
164
192
  attr_reader original_name: Symbol
165
193
  attr_reader aliased_name: Symbol
@@ -178,12 +206,16 @@ module RBS
178
206
  # The *overloading* method definition cannot find *non-overloading* method definition
179
207
  #
180
208
  class InvalidOverloadMethodError < DefinitionError
209
+ include DetailedMessageable
210
+
181
211
  attr_reader type_name: TypeName
182
212
  attr_reader method_name: Symbol
183
213
  attr_reader kind: :instance | :singleton
184
214
  attr_reader members: Array[AST::Members::MethodDefinition]
185
215
 
186
216
  def initialize: (type_name: TypeName, method_name: Symbol, kind: :instance | :singleton, members: Array[AST::Members::MethodDefinition]) -> void
217
+
218
+ def location: () -> AST::Members::MethodDefinition::loc?
187
219
  end
188
220
 
189
221
  class GenericParameterMismatchError < LoadingError
@@ -201,6 +233,8 @@ module RBS
201
233
  end
202
234
 
203
235
  class InvalidVarianceAnnotationError < DefinitionError
236
+ include DetailedMessageable
237
+
204
238
  attr_reader type_name: TypeName
205
239
  attr_reader param: AST::TypeParam
206
240
  attr_reader location: Location[untyped, untyped]?
@@ -209,6 +243,8 @@ module RBS
209
243
  end
210
244
 
211
245
  class RecursiveAliasDefinitionError < DefinitionError
246
+ include DetailedMessageable
247
+
212
248
  type ty = Types::ClassInstance | Types::ClassSingleton | Types::Interface
213
249
  type defn = DefinitionBuilder::MethodBuilder::Methods::Definition
214
250
 
@@ -223,6 +259,8 @@ module RBS
223
259
  # MixinClassError is raised if a include/prepend/extend has a class (not a module) to mix-in
224
260
  #
225
261
  class MixinClassError < DefinitionError
262
+ include DetailedMessageable
263
+
226
264
  type member = AST::Members::Include | AST::Members::Prepend | AST::Members::Extend
227
265
 
228
266
  attr_reader type_name: TypeName
@@ -240,6 +278,8 @@ module RBS
240
278
  # InheritModuleError is raised if a class definition inherits a module (not a class)
241
279
  #
242
280
  class InheritModuleError < DefinitionError
281
+ include DetailedMessageable
282
+
243
283
  attr_reader super_decl: AST::Declarations::Class::Super
244
284
 
245
285
  def initialize: (AST::Declarations::Class::Super) -> void
@@ -254,6 +294,8 @@ module RBS
254
294
  end
255
295
 
256
296
  class RecursiveTypeAliasError < BaseError
297
+ include DetailedMessageable
298
+
257
299
  attr_reader alias_names: Array[TypeName]
258
300
  attr_reader location: Location[untyped, untyped]?
259
301
 
@@ -263,6 +305,8 @@ module RBS
263
305
  end
264
306
 
265
307
  class NonregularTypeAliasError < BaseError
308
+ include DetailedMessageable
309
+
266
310
  # Diagnostic reported from `TypeAliasRegularity`.
267
311
  attr_reader diagnostic: TypeAliasRegularity::Diagnostic
268
312
 
@@ -273,6 +317,8 @@ module RBS
273
317
  end
274
318
 
275
319
  class CyclicTypeParameterBound < BaseError
320
+ include DetailedMessageable
321
+
276
322
  attr_reader location: Location[untyped, untyped]?
277
323
 
278
324
  # Array of parameters which contains cyclic dependencies.
@@ -295,16 +341,24 @@ module RBS
295
341
  # ```
296
342
  #
297
343
  class InconsistentClassModuleAliasError < BaseError
344
+ include DetailedMessageable
345
+
298
346
  attr_reader alias_entry: Environment::ModuleAliasEntry | Environment::ClassAliasEntry
299
347
 
300
348
  def initialize: (Environment::ModuleAliasEntry | Environment::ClassAliasEntry) -> void
349
+
350
+ def location: () -> AST::Declarations::AliasDecl::loc?
301
351
  end
302
352
 
303
353
  # A module/class alias declaration is cyclic
304
354
  #
305
355
  class CyclicClassAliasDefinitionError < BaseError
356
+ include DetailedMessageable
357
+
306
358
  attr_reader alias_entry: Environment::ModuleAliasEntry | Environment::ClassAliasEntry
307
359
 
308
360
  def initialize: (Environment::ModuleAliasEntry | Environment::ClassAliasEntry) -> void
361
+
362
+ def location: () -> AST::Declarations::AliasDecl::loc?
309
363
  end
310
364
  end
data/sig/parser.rbs CHANGED
@@ -2,7 +2,7 @@ module RBS
2
2
  class Parser
3
3
  # Parse a method type and return it
4
4
  #
5
- # When `range` keyword is specified, it starts parsing from the `begin` to the `endo` the range.
5
+ # When `range` keyword is specified, it starts parsing from the `begin` to the `end` of the range.
6
6
  #
7
7
  # ```ruby
8
8
  # RBS::Parser.parse_method_type("() -> void") # => `() -> void`
@@ -25,7 +25,7 @@ module RBS
25
25
 
26
26
  # Parse a type and return it
27
27
  #
28
- # When `range` keyword is specified, it starts parsing from the `begin` to the `endo` the range.
28
+ # When `range` keyword is specified, it starts parsing from the `begin` to the `end` of the range.
29
29
  #
30
30
  # ```ruby
31
31
  # RBS::Parser.parse_type("String") # => `String`
data/sig/prototype/rb.rbs CHANGED
@@ -12,12 +12,18 @@ module RBS
12
12
 
13
13
  attr_accessor namespace: Namespace
14
14
 
15
- def initialize: (module_function: bool, singleton: bool, namespace: Namespace) -> void
15
+ attr_accessor in_def: bool
16
+
17
+ def initialize: (module_function: bool, singleton: bool, namespace: Namespace, in_def: bool) -> void
16
18
 
17
19
  def method_kind: () -> method_kind
18
20
 
19
21
  def attribute_kind: () -> (:singleton | :instance)
20
22
 
23
+ def enter_namespace: (Namespace) -> Context
24
+
25
+ def update: (?module_function: bool, ?singleton: bool, ?in_def: bool) -> Context
26
+
21
27
  def self.initial: (?namespace: Namespace) -> Context
22
28
  end
23
29
 
@@ -83,6 +89,8 @@ module RBS
83
89
  def is_accessibility?: (decl) -> bool
84
90
 
85
91
  def find_def_index_by_name: (Array[decl] decls, Symbol name) -> [Integer, AST::Members::MethodDefinition | AST::Members::AttrReader | AST::Members::AttrWriter]?
92
+
93
+ def sort_members!: (Array[decl] decls) -> void
86
94
  end
87
95
  end
88
96
  end
data/sig/subtractor.rbs CHANGED
@@ -24,6 +24,10 @@ module RBS
24
24
 
25
25
  private def mixin_exist?: (TypeName owner, AST::Members::Include | AST::Members::Extend | AST::Members::Prepend, context: Resolver::context) -> boolish
26
26
 
27
+ private def filter_redundunt_access_modifiers: (Array[AST::Declarations::t | AST::Members::t]) -> Array[AST::Declarations::t | AST::Members::t]
28
+
29
+ private def access_modifier?: (AST::Declarations::t | AST::Members::t?) -> bool
30
+
27
31
  private def update_decl: (decl_with_members, members: Array[AST::Declarations::t | AST::Members::t]) -> decl_with_members
28
32
 
29
33
  private def absolute_typename: (TypeName, context: Resolver::context) -> TypeName
@@ -796,7 +796,7 @@ class Logger
796
796
  # periodic log file rotation; default is `'%Y%m%d'`. See [Periodic
797
797
  # Rotation](rdoc-ref:Logger@Periodic+Rotation).
798
798
  #
799
- def initialize: (logdev logdev, ?Numeric | String shift_age, ?Integer shift_size, ?shift_period_suffix: String, ?binmode: boolish, ?datetime_format: String, ?formatter: _Formatter, ?progname: String, ?level: Integer | String | Symbol) -> void
799
+ def initialize: (logdev? logdev, ?Numeric | String shift_age, ?Integer shift_size, ?shift_period_suffix: String, ?binmode: boolish, ?datetime_format: String, ?formatter: _Formatter, ?progname: String, ?level: Integer | String | Symbol) -> void
800
800
  end
801
801
 
802
802
  Logger::ProgName: String
@@ -0,0 +1,219 @@
1
+ # <!-- rdoc-file=lib/observer.rb -->
2
+ # The Observer pattern (also known as publish/subscribe) provides a simple
3
+ # mechanism for one object to inform a set of interested third-party objects
4
+ # when its state changes.
5
+ #
6
+ # ## Mechanism
7
+ #
8
+ # The notifying class mixes in the `Observable` module, which provides the
9
+ # methods for managing the associated observer objects.
10
+ #
11
+ # The observable object must:
12
+ # * assert that it has `#changed`
13
+ # * call `#notify_observers`
14
+ #
15
+ #
16
+ # An observer subscribes to updates using Observable#add_observer, which also
17
+ # specifies the method called via #notify_observers. The default method for
18
+ # #notify_observers is #update.
19
+ #
20
+ # ### Example
21
+ #
22
+ # The following example demonstrates this nicely. A `Ticker`, when run,
23
+ # continually receives the stock `Price` for its `@symbol`. A `Warner` is a
24
+ # general observer of the price, and two warners are demonstrated, a `WarnLow`
25
+ # and a `WarnHigh`, which print a warning if the price is below or above their
26
+ # set limits, respectively.
27
+ #
28
+ # The `update` callback allows the warners to run without being explicitly
29
+ # called. The system is set up with the `Ticker` and several observers, and the
30
+ # observers do their duty without the top-level code having to interfere.
31
+ #
32
+ # Note that the contract between publisher and subscriber (observable and
33
+ # observer) is not declared or enforced. The `Ticker` publishes a time and a
34
+ # price, and the warners receive that. But if you don't ensure that your
35
+ # contracts are correct, nothing else can warn you.
36
+ #
37
+ # require "observer"
38
+ #
39
+ # class Ticker ### Periodically fetch a stock price.
40
+ # include Observable
41
+ #
42
+ # def initialize(symbol)
43
+ # @symbol = symbol
44
+ # end
45
+ #
46
+ # def run
47
+ # last_price = nil
48
+ # loop do
49
+ # price = Price.fetch(@symbol)
50
+ # print "Current price: #{price}\n"
51
+ # if price != last_price
52
+ # changed # notify observers
53
+ # last_price = price
54
+ # notify_observers(Time.now, price)
55
+ # end
56
+ # sleep 1
57
+ # end
58
+ # end
59
+ # end
60
+ #
61
+ # class Price ### A mock class to fetch a stock price (60 - 140).
62
+ # def self.fetch(symbol)
63
+ # 60 + rand(80)
64
+ # end
65
+ # end
66
+ #
67
+ # class Warner ### An abstract observer of Ticker objects.
68
+ # def initialize(ticker, limit)
69
+ # @limit = limit
70
+ # ticker.add_observer(self)
71
+ # end
72
+ # end
73
+ #
74
+ # class WarnLow < Warner
75
+ # def update(time, price) # callback for observer
76
+ # if price < @limit
77
+ # print "--- #{time.to_s}: Price below #@limit: #{price}\n"
78
+ # end
79
+ # end
80
+ # end
81
+ #
82
+ # class WarnHigh < Warner
83
+ # def update(time, price) # callback for observer
84
+ # if price > @limit
85
+ # print "+++ #{time.to_s}: Price above #@limit: #{price}\n"
86
+ # end
87
+ # end
88
+ # end
89
+ #
90
+ # ticker = Ticker.new("MSFT")
91
+ # WarnLow.new(ticker, 80)
92
+ # WarnHigh.new(ticker, 120)
93
+ # ticker.run
94
+ #
95
+ # Produces:
96
+ #
97
+ # Current price: 83
98
+ # Current price: 75
99
+ # --- Sun Jun 09 00:10:25 CDT 2002: Price below 80: 75
100
+ # Current price: 90
101
+ # Current price: 134
102
+ # +++ Sun Jun 09 00:10:25 CDT 2002: Price above 120: 134
103
+ # Current price: 134
104
+ # Current price: 112
105
+ # Current price: 79
106
+ # --- Sun Jun 09 00:10:25 CDT 2002: Price below 80: 79
107
+ #
108
+ # ### Usage with procs
109
+ #
110
+ # The `#notify_observers` method can also be used with +proc+s by using the
111
+ # `:call` as `func` parameter.
112
+ #
113
+ # The following example illustrates the use of a lambda:
114
+ #
115
+ # require 'observer'
116
+ #
117
+ # class Ticker
118
+ # include Observable
119
+ #
120
+ # def run
121
+ # # logic to retrieve the price (here 77.0)
122
+ # changed
123
+ # notify_observers(77.0)
124
+ # end
125
+ # end
126
+ #
127
+ # ticker = Ticker.new
128
+ # warner = ->(price) { puts "New price received: #{price}" }
129
+ # ticker.add_observer(warner, :call)
130
+ # ticker.run
131
+ #
132
+ module Observable
133
+ public
134
+
135
+ # <!--
136
+ # rdoc-file=lib/observer.rb
137
+ # - add_observer(observer, func=:update)
138
+ # -->
139
+ # Add `observer` as an observer on this object. So that it will receive
140
+ # notifications.
141
+ #
142
+ # `observer`
143
+ # : the object that will be notified of changes.
144
+ # `func`
145
+ # : Symbol naming the method that will be called when this Observable has
146
+ # changes.
147
+ #
148
+ # This method must return true for `observer.respond_to?` and will receive
149
+ # `*arg` when #notify_observers is called, where `*arg` is the value passed
150
+ # to #notify_observers by this Observable
151
+ #
152
+ def add_observer: (untyped observer, ?Symbol func) -> void
153
+
154
+ # <!--
155
+ # rdoc-file=lib/observer.rb
156
+ # - changed(state=true)
157
+ # -->
158
+ # Set the changed state of this object. Notifications will be sent only if the
159
+ # changed `state` is `true`.
160
+ #
161
+ # `state`
162
+ # : Boolean indicating the changed state of this Observable.
163
+ #
164
+ def changed: (?bool state) -> void
165
+
166
+ # <!--
167
+ # rdoc-file=lib/observer.rb
168
+ # - changed?()
169
+ # -->
170
+ # Returns true if this object's state has been changed since the last
171
+ # #notify_observers call.
172
+ #
173
+ def changed?: () -> bool
174
+
175
+ # <!--
176
+ # rdoc-file=lib/observer.rb
177
+ # - count_observers()
178
+ # -->
179
+ # Return the number of observers associated with this object.
180
+ #
181
+ def count_observers: () -> Integer
182
+
183
+ # <!--
184
+ # rdoc-file=lib/observer.rb
185
+ # - delete_observer(observer)
186
+ # -->
187
+ # Remove `observer` as an observer on this object so that it will no longer
188
+ # receive notifications.
189
+ #
190
+ # `observer`
191
+ # : An observer of this Observable
192
+ #
193
+ def delete_observer: (untyped observer) -> void
194
+
195
+ # <!--
196
+ # rdoc-file=lib/observer.rb
197
+ # - delete_observers()
198
+ # -->
199
+ # Remove all observers associated with this object.
200
+ #
201
+ def delete_observers: () -> void
202
+
203
+ # <!--
204
+ # rdoc-file=lib/observer.rb
205
+ # - notify_observers(*arg)
206
+ # -->
207
+ # Notify observers of a change in state **if** this object's changed state is
208
+ # `true`.
209
+ #
210
+ # This will invoke the method named in #add_observer, passing `*arg`. The
211
+ # changed state is then set to `false`.
212
+ #
213
+ # `*arg`
214
+ # : Any arguments to pass to the observers.
215
+ #
216
+ def notify_observers: (*untyped arg) -> void
217
+
218
+ VERSION: String
219
+ end
@@ -1,3 +1,27 @@
1
+ # <!-- rdoc-file=lib/uri/common.rb -->
2
+ # Base class for all URI exceptions.
3
+ #
4
+ class URI::Error < StandardError
5
+ end
6
+
7
+ # <!-- rdoc-file=lib/uri/common.rb -->
8
+ # Not a URI.
9
+ #
10
+ class URI::InvalidURIError < URI::Error
11
+ end
12
+
13
+ # <!-- rdoc-file=lib/uri/common.rb -->
14
+ # Not a URI component.
15
+ #
16
+ class URI::InvalidComponentError < URI::Error
17
+ end
18
+
19
+ # <!-- rdoc-file=lib/uri/common.rb -->
20
+ # URI is valid, bad usage is not.
21
+ #
22
+ class URI::BadURIError < URI::Error
23
+ end
24
+
1
25
  # <!-- rdoc-file=lib/uri.rb -->
2
26
  # URI is a module providing classes to handle Uniform Resource Identifiers
3
27
  # ([RFC2396](http://tools.ietf.org/html/rfc2396)).