rbs 2.8.4 → 3.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +12 -4
- data/.github/workflows/comments.yml +11 -11
- data/.github/workflows/dependabot.yml +30 -0
- data/.github/workflows/ruby.yml +40 -49
- data/.github/workflows/typecheck.yml +36 -0
- data/.github/workflows/windows.yml +28 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +42 -2
- data/CHANGELOG.md +845 -1
- data/README.md +64 -4
- data/Rakefile +198 -18
- data/Steepfile +11 -11
- data/config.yml +311 -0
- data/core/array.rbs +2189 -1914
- data/core/basic_object.rbs +59 -84
- data/core/binding.rbs +7 -69
- data/core/builtin.rbs +210 -11
- data/core/class.rbs +37 -0
- data/core/comparable.rbs +23 -25
- data/core/complex.rbs +449 -227
- data/core/constants.rbs +29 -21
- data/core/data.rbs +415 -0
- data/core/dir.rbs +698 -415
- data/core/encoding.rbs +468 -843
- data/core/enumerable.rbs +495 -455
- data/core/enumerator/product.rbs +92 -0
- data/core/enumerator.rbs +106 -9
- data/core/env.rbs +1 -1
- data/core/errno.rbs +506 -605
- data/core/errors.rbs +15 -17
- data/core/exception.rbs +361 -145
- data/core/false_class.rbs +39 -26
- data/core/fiber.rbs +121 -14
- data/core/file.rbs +1262 -320
- data/core/file_test.rbs +62 -45
- data/core/float.rbs +187 -208
- data/core/gc.rbs +446 -196
- data/core/global_variables.rbs +29 -29
- data/core/hash.rbs +242 -349
- data/core/integer.rbs +246 -308
- data/core/io/buffer.rbs +373 -122
- data/core/io/wait.rbs +29 -17
- data/core/io.rbs +1881 -1518
- data/core/kernel.rbs +2116 -1538
- data/core/marshal.rbs +24 -14
- data/core/match_data.rbs +413 -166
- data/core/math.rbs +531 -291
- data/core/method.rbs +101 -32
- data/core/module.rbs +228 -64
- data/core/nil_class.rbs +106 -47
- data/core/numeric.rbs +206 -292
- data/core/object.rbs +73 -1168
- data/core/object_space/weak_key_map.rbs +166 -0
- data/core/object_space.rbs +5 -3
- data/core/proc.rbs +280 -39
- data/core/process.rbs +1318 -658
- data/core/ractor.rbs +200 -134
- data/core/random.rbs +21 -4
- data/core/range.rbs +309 -153
- data/core/rational.rbs +4 -12
- data/core/rb_config.rbs +64 -43
- data/core/rbs/unnamed/argf.rbs +411 -147
- data/core/rbs/unnamed/env_class.rbs +137 -253
- data/core/rbs/unnamed/random.rbs +49 -26
- data/core/refinement.rbs +16 -1
- data/core/regexp.rbs +1568 -862
- data/core/ruby_vm.rbs +719 -7
- data/core/rubygems/config_file.rbs +3 -0
- data/core/rubygems/errors.rbs +69 -6
- data/core/rubygems/rubygems.rbs +71 -17
- data/core/rubygems/version.rbs +11 -7
- data/{stdlib/set/0 → core}/set.rbs +80 -91
- data/core/signal.rbs +14 -8
- data/core/string.rbs +1732 -1607
- data/core/struct.rbs +467 -95
- data/core/symbol.rbs +215 -245
- data/core/thread.rbs +133 -89
- data/core/thread_group.rbs +9 -9
- data/core/time.rbs +1141 -841
- data/core/trace_point.rbs +181 -121
- data/core/true_class.rbs +58 -32
- data/core/unbound_method.rbs +103 -30
- data/core/warning.rbs +50 -5
- data/docs/CONTRIBUTING.md +1 -1
- data/docs/architecture.md +110 -0
- data/docs/collection.md +59 -5
- data/docs/data_and_struct.md +86 -0
- data/docs/gem.md +57 -0
- data/docs/rbs_by_example.md +16 -35
- data/docs/repo.md +1 -1
- data/docs/sigs.md +7 -7
- data/docs/stdlib.md +63 -5
- data/docs/syntax.md +255 -61
- data/docs/tools.md +1 -0
- data/ext/rbs_extension/extconf.rb +10 -0
- data/ext/rbs_extension/lexer.c +1741 -1548
- data/ext/rbs_extension/lexer.h +11 -1
- data/ext/rbs_extension/lexer.re +12 -6
- data/ext/rbs_extension/lexstate.c +26 -3
- data/ext/rbs_extension/location.c +119 -111
- data/ext/rbs_extension/location.h +32 -7
- data/ext/rbs_extension/main.c +3 -0
- data/ext/rbs_extension/parser.c +883 -481
- data/ext/rbs_extension/parserstate.c +65 -25
- data/ext/rbs_extension/parserstate.h +13 -3
- data/ext/rbs_extension/rbs_extension.h +1 -10
- data/ext/rbs_extension/unescape.c +7 -47
- data/goodcheck.yml +2 -2
- data/{ext/rbs_extension → include/rbs}/constants.h +26 -15
- data/include/rbs/ruby_objs.h +72 -0
- data/include/rbs.h +7 -0
- data/lib/rbs/annotate/annotations.rb +3 -3
- data/lib/rbs/annotate/formatter.rb +13 -3
- data/lib/rbs/annotate/rdoc_annotator.rb +1 -1
- data/lib/rbs/annotate/rdoc_source.rb +12 -3
- data/lib/rbs/ast/declarations.rb +85 -2
- data/lib/rbs/ast/directives.rb +39 -0
- data/lib/rbs/ast/members.rb +49 -15
- data/lib/rbs/ast/type_param.rb +104 -15
- data/lib/rbs/ast/visitor.rb +137 -0
- data/lib/rbs/buffer.rb +5 -0
- data/lib/rbs/cli/colored_io.rb +48 -0
- data/lib/rbs/cli/diff.rb +83 -0
- data/lib/rbs/cli/validate.rb +356 -0
- data/lib/rbs/cli.rb +253 -143
- data/lib/rbs/collection/cleaner.rb +8 -1
- data/lib/rbs/collection/config/lockfile.rb +92 -0
- data/lib/rbs/collection/config/lockfile_generator.rb +154 -65
- data/lib/rbs/collection/config.rb +19 -46
- data/lib/rbs/collection/installer.rb +12 -13
- data/lib/rbs/collection/sources/base.rb +2 -2
- data/lib/rbs/collection/sources/git.rb +146 -69
- data/lib/rbs/collection/sources/local.rb +81 -0
- data/lib/rbs/collection/sources/rubygems.rb +10 -12
- data/lib/rbs/collection/sources/stdlib.rb +14 -13
- data/lib/rbs/collection/sources.rb +15 -2
- data/lib/rbs/collection.rb +2 -1
- data/lib/rbs/definition.rb +13 -16
- data/lib/rbs/definition_builder/ancestor_builder.rb +100 -24
- data/lib/rbs/definition_builder/method_builder.rb +4 -4
- data/lib/rbs/definition_builder.rb +489 -584
- data/lib/rbs/diff.rb +125 -0
- data/lib/rbs/environment/use_map.rb +77 -0
- data/lib/rbs/environment.rb +406 -105
- data/lib/rbs/environment_loader.rb +48 -44
- data/lib/rbs/environment_walker.rb +1 -1
- data/lib/rbs/errors.rb +175 -56
- data/lib/rbs/file_finder.rb +28 -0
- data/lib/rbs/location_aux.rb +8 -7
- data/lib/rbs/locator.rb +37 -15
- data/lib/rbs/method_type.rb +23 -0
- data/lib/rbs/namespace.rb +1 -0
- data/lib/rbs/parser/lex_result.rb +15 -0
- data/lib/rbs/parser/token.rb +23 -0
- data/lib/rbs/parser_aux.rb +22 -13
- data/lib/rbs/prototype/helpers.rb +48 -22
- data/lib/rbs/prototype/node_usage.rb +99 -0
- data/lib/rbs/prototype/rb.rb +125 -31
- data/lib/rbs/prototype/rbi.rb +49 -36
- data/lib/rbs/prototype/runtime/helpers.rb +59 -0
- data/lib/rbs/prototype/runtime/reflection.rb +19 -0
- data/lib/rbs/prototype/runtime/value_object_generator.rb +279 -0
- data/lib/rbs/prototype/runtime.rb +273 -159
- data/lib/rbs/resolver/constant_resolver.rb +24 -8
- data/lib/rbs/resolver/type_name_resolver.rb +41 -7
- data/lib/rbs/sorter.rb +153 -123
- data/lib/rbs/substitution.rb +19 -0
- data/lib/rbs/subtractor.rb +201 -0
- data/lib/rbs/test/errors.rb +24 -11
- data/lib/rbs/test/guaranteed.rb +30 -0
- data/lib/rbs/test/hook.rb +45 -40
- data/lib/rbs/test/setup.rb +1 -1
- data/lib/rbs/test/tester.rb +1 -1
- data/lib/rbs/test/type_check.rb +120 -23
- data/lib/rbs/test.rb +6 -3
- data/lib/rbs/type_alias_dependency.rb +13 -3
- data/lib/rbs/type_alias_regularity.rb +21 -14
- data/lib/rbs/type_name.rb +18 -13
- data/lib/rbs/types.rb +352 -18
- data/lib/rbs/unit_test/convertibles.rb +176 -0
- data/lib/rbs/unit_test/spy.rb +136 -0
- data/lib/rbs/unit_test/type_assertions.rb +341 -0
- data/lib/rbs/unit_test/with_aliases.rb +143 -0
- data/lib/rbs/unit_test.rb +6 -0
- data/lib/rbs/validator.rb +55 -30
- data/lib/rbs/variance_calculator.rb +26 -23
- data/lib/rbs/vendorer.rb +3 -3
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +69 -22
- data/lib/rbs.rb +7 -2
- data/lib/rdoc/discover.rb +1 -1
- data/lib/rdoc_plugin/parser.rb +5 -5
- data/rbs.gemspec +12 -2
- data/schema/decls.json +1 -1
- data/schema/members.json +15 -10
- data/sig/ancestor_builder.rbs +4 -0
- data/sig/ancestor_graph.rbs +22 -2
- data/sig/annotate/formatter.rbs +2 -2
- data/sig/annotate/rdoc_annotater.rbs +1 -1
- data/sig/cli/colored_io.rbs +15 -0
- data/sig/cli/diff.rbs +21 -0
- data/sig/cli/validate.rbs +43 -0
- data/sig/cli.rbs +4 -0
- data/sig/collection/config/lockfile.rbs +74 -0
- data/sig/collection/config/lockfile_generator.rbs +66 -0
- data/sig/collection/config.rbs +5 -48
- data/sig/collection/installer.rbs +1 -1
- data/sig/collection/sources.rbs +105 -33
- data/sig/constant.rbs +1 -1
- data/sig/declarations.rbs +42 -3
- data/sig/definition.rbs +26 -10
- data/sig/definition_builder.rbs +103 -81
- data/sig/diff.rbs +28 -0
- data/sig/directives.rbs +61 -0
- data/sig/environment.rbs +175 -29
- data/sig/environment_loader.rbs +20 -18
- data/sig/errors.rbs +123 -2
- data/sig/file_finder.rbs +28 -0
- data/sig/location.rbs +0 -3
- data/sig/locator.rbs +14 -2
- data/sig/manifest.yaml +0 -1
- data/sig/members.rbs +32 -9
- data/sig/method_types.rbs +10 -4
- data/sig/namespace.rbs +2 -3
- data/sig/parser.rbs +55 -16
- data/sig/prototype/helpers.rbs +4 -0
- data/sig/prototype/node_usage.rbs +20 -0
- data/sig/prototype/rb.rbs +10 -2
- data/sig/prototype/rbi.rbs +2 -0
- data/sig/prototype/runtime.rbs +182 -0
- data/sig/rbs.rbs +1 -1
- data/sig/rdoc/rbs.rbs +4 -0
- data/sig/repository.rbs +7 -5
- data/sig/resolver/constant_resolver.rbs +3 -4
- data/sig/resolver/context.rbs +1 -1
- data/sig/resolver/type_name_resolver.rbs +5 -1
- data/sig/shims/bundler.rbs +38 -0
- data/sig/shims/rubygems.rbs +19 -0
- data/sig/sorter.rbs +23 -5
- data/sig/substitution.rbs +6 -0
- data/sig/subtractor.rbs +37 -0
- data/sig/test/errors.rbs +52 -0
- data/sig/test/guranteed.rbs +9 -0
- data/sig/test/type_check.rbs +19 -0
- data/sig/test.rbs +82 -0
- data/sig/type_alias_dependency.rbs +31 -0
- data/sig/type_alias_regularity.rbs +12 -6
- data/sig/type_param.rbs +45 -9
- data/sig/typename.rbs +8 -5
- data/sig/types.rbs +119 -12
- data/sig/unit_test/convertibles.rbs +154 -0
- data/sig/unit_test/spy.rbs +28 -0
- data/sig/unit_test/type_assertions.rbs +194 -0
- data/sig/unit_test/with_aliases.rbs +136 -0
- data/sig/use_map.rbs +35 -0
- data/sig/validator.rbs +12 -5
- data/sig/variance_calculator.rbs +3 -1
- data/sig/vendorer.rbs +1 -1
- data/sig/visitor.rbs +47 -0
- data/sig/writer.rbs +6 -2
- data/src/constants.c +153 -0
- data/src/ruby_objs.c +793 -0
- data/stdlib/base64/0/base64.rbs +298 -45
- data/stdlib/benchmark/0/benchmark.rbs +12 -3
- data/stdlib/bigdecimal/0/big_decimal.rbs +62 -198
- data/stdlib/cgi/0/core.rbs +68 -15
- data/stdlib/cgi/0/manifest.yaml +1 -0
- data/stdlib/coverage/0/coverage.rbs +50 -11
- data/stdlib/csv/0/csv.rbs +90 -119
- data/stdlib/csv/0/manifest.yaml +1 -0
- data/stdlib/date/0/date.rbs +806 -735
- data/stdlib/date/0/date_time.rbs +70 -211
- data/stdlib/dbm/0/dbm.rbs +0 -2
- data/stdlib/delegate/0/delegator.rbs +184 -0
- data/stdlib/delegate/0/kernel.rbs +47 -0
- data/stdlib/delegate/0/simple_delegator.rbs +96 -0
- data/stdlib/did_you_mean/0/did_you_mean.rbs +3 -8
- data/stdlib/digest/0/digest.rbs +48 -35
- data/stdlib/erb/0/erb.rbs +15 -39
- data/stdlib/etc/0/etc.rbs +174 -54
- data/stdlib/fileutils/0/fileutils.rbs +1234 -385
- data/stdlib/forwardable/0/forwardable.rbs +4 -4
- data/stdlib/io-console/0/io-console.rbs +82 -17
- data/stdlib/ipaddr/0/ipaddr.rbs +11 -6
- data/stdlib/json/0/json.rbs +434 -151
- data/stdlib/kconv/0/kconv.rbs +166 -0
- data/stdlib/logger/0/formatter.rbs +0 -2
- data/stdlib/logger/0/log_device.rbs +1 -3
- data/stdlib/logger/0/logger.rbs +465 -328
- data/stdlib/minitest/0/kernel.rbs +2 -2
- data/stdlib/minitest/0/minitest/abstract_reporter.rbs +4 -1
- data/stdlib/minitest/0/minitest/assertion.rbs +1 -0
- data/stdlib/minitest/0/minitest/assertions.rbs +58 -13
- data/stdlib/minitest/0/minitest/backtrace_filter.rbs +7 -0
- data/stdlib/minitest/0/minitest/bench_spec.rbs +8 -8
- data/stdlib/minitest/0/minitest/benchmark.rbs +17 -16
- data/stdlib/minitest/0/minitest/compress.rbs +13 -0
- data/stdlib/minitest/0/minitest/error_on_warning.rbs +3 -0
- data/stdlib/minitest/0/minitest/mock.rbs +9 -5
- data/stdlib/minitest/0/minitest/parallel/executor.rbs +4 -0
- data/stdlib/minitest/0/minitest/parallel/test/class_methods.rbs +0 -1
- data/stdlib/minitest/0/minitest/pride_io.rbs +8 -0
- data/stdlib/minitest/0/minitest/pride_lol.rbs +2 -0
- data/stdlib/minitest/0/minitest/progress_reporter.rbs +1 -1
- data/stdlib/minitest/0/minitest/reportable.rbs +2 -0
- data/stdlib/minitest/0/minitest/runnable.rbs +33 -1
- data/stdlib/minitest/0/minitest/spec/dsl/instance_methods.rbs +1 -1
- data/stdlib/minitest/0/minitest/spec/dsl.rbs +10 -6
- data/stdlib/minitest/0/minitest/spec.rbs +1 -1
- data/stdlib/minitest/0/minitest/statistics_reporter.rbs +5 -0
- data/stdlib/minitest/0/minitest/summary_reporter.rbs +0 -7
- data/stdlib/minitest/0/minitest/test/lifecycle_hooks.rbs +7 -7
- data/stdlib/minitest/0/minitest/test.rbs +7 -14
- data/stdlib/minitest/0/minitest/unexpected_error.rbs +2 -0
- data/stdlib/minitest/0/minitest/unexpected_warning.rbs +6 -0
- data/stdlib/minitest/0/minitest/unit.rbs +1 -2
- data/stdlib/minitest/0/minitest.rbs +41 -892
- data/stdlib/monitor/0/monitor.rbs +91 -10
- data/stdlib/mutex_m/0/mutex_m.rbs +0 -2
- data/stdlib/net-http/0/manifest.yaml +1 -1
- data/stdlib/net-http/0/net-http.rbs +3858 -964
- data/stdlib/net-protocol/0/manifest.yaml +2 -0
- data/stdlib/net-protocol/0/net-protocol.rbs +56 -0
- data/stdlib/net-smtp/0/manifest.yaml +2 -0
- data/stdlib/net-smtp/0/net-smtp.rbs +55 -0
- data/stdlib/nkf/0/nkf.rbs +35 -5
- data/stdlib/objspace/0/objspace.rbs +40 -18
- data/stdlib/observable/0/observable.rbs +217 -0
- data/stdlib/open-uri/0/manifest.yaml +4 -0
- data/stdlib/open-uri/0/open-uri.rbs +393 -0
- data/stdlib/open3/0/open3.rbs +147 -0
- data/stdlib/openssl/0/manifest.yaml +1 -0
- data/stdlib/openssl/0/openssl.rbs +681 -316
- data/stdlib/optparse/0/optparse.rbs +100 -65
- data/stdlib/pathname/0/pathname.rbs +24 -15
- data/stdlib/pp/0/manifest.yaml +2 -0
- data/stdlib/pp/0/pp.rbs +300 -0
- data/stdlib/prettyprint/0/prettyprint.rbs +2 -6
- data/stdlib/pstore/0/pstore.rbs +370 -156
- data/stdlib/psych/0/core_ext.rbs +12 -0
- data/stdlib/{yaml → psych}/0/dbm.rbs +3 -3
- data/stdlib/psych/0/manifest.yaml +3 -0
- data/stdlib/psych/0/psych.rbs +402 -0
- data/stdlib/{yaml → psych}/0/store.rbs +2 -2
- data/stdlib/pty/0/pty.rbs +63 -11
- data/stdlib/rdoc/0/code_object.rbs +51 -0
- data/stdlib/rdoc/0/comment.rbs +59 -0
- data/stdlib/rdoc/0/context.rbs +153 -0
- data/stdlib/rdoc/0/markup.rbs +117 -0
- data/stdlib/rdoc/0/parser.rbs +56 -0
- data/stdlib/rdoc/0/rdoc.rbs +13 -380
- data/stdlib/rdoc/0/ri.rbs +17 -0
- data/stdlib/rdoc/0/store.rbs +48 -0
- data/stdlib/rdoc/0/top_level.rbs +97 -0
- data/stdlib/resolv/0/resolv.rbs +16 -79
- data/stdlib/ripper/0/ripper.rbs +1648 -0
- data/stdlib/securerandom/0/securerandom.rbs +7 -2
- data/stdlib/shellwords/0/shellwords.rbs +11 -12
- data/stdlib/singleton/0/singleton.rbs +0 -3
- data/stdlib/socket/0/addrinfo.rbs +13 -18
- data/stdlib/socket/0/basic_socket.rbs +5 -10
- data/stdlib/socket/0/ip_socket.rbs +0 -2
- data/stdlib/socket/0/socket.rbs +77 -46
- data/stdlib/socket/0/tcp_server.rbs +0 -5
- data/stdlib/socket/0/tcp_socket.rbs +36 -3
- data/stdlib/socket/0/udp_socket.rbs +4 -5
- data/stdlib/socket/0/unix_server.rbs +0 -5
- data/stdlib/socket/0/unix_socket.rbs +2 -4
- data/{core/string_io.rbs → stdlib/stringio/0/stringio.rbs} +188 -107
- data/stdlib/strscan/0/string_scanner.rbs +1269 -425
- data/stdlib/tempfile/0/tempfile.rbs +224 -61
- data/stdlib/time/0/time.rbs +48 -35
- data/stdlib/timeout/0/timeout.rbs +17 -8
- data/stdlib/tmpdir/0/tmpdir.rbs +10 -3
- data/stdlib/tsort/0/tsort.rbs +0 -4
- data/stdlib/uri/0/common.rbs +271 -144
- data/stdlib/uri/0/file.rbs +5 -0
- data/stdlib/uri/0/ftp.rbs +1 -1
- data/stdlib/uri/0/generic.rbs +26 -22
- data/stdlib/uri/0/http.rbs +4 -4
- data/stdlib/uri/0/ldap.rbs +1 -1
- data/stdlib/uri/0/mailto.rbs +84 -0
- data/stdlib/uri/0/rfc2396_parser.rbs +3 -0
- data/stdlib/yaml/0/manifest.yaml +1 -2
- data/stdlib/yaml/0/yaml.rbs +1 -199
- data/stdlib/zlib/0/buf_error.rbs +10 -0
- data/stdlib/zlib/0/data_error.rbs +10 -0
- data/stdlib/zlib/0/deflate.rbs +210 -0
- data/stdlib/zlib/0/error.rbs +20 -0
- data/stdlib/zlib/0/gzip_file/crc_error.rbs +12 -0
- data/stdlib/zlib/0/gzip_file/error.rbs +23 -0
- data/stdlib/zlib/0/gzip_file/length_error.rbs +12 -0
- data/stdlib/zlib/0/gzip_file/no_footer.rbs +11 -0
- data/stdlib/zlib/0/gzip_file.rbs +156 -0
- data/stdlib/zlib/0/gzip_reader.rbs +293 -0
- data/stdlib/zlib/0/gzip_writer.rbs +166 -0
- data/stdlib/zlib/0/inflate.rbs +180 -0
- data/stdlib/zlib/0/mem_error.rbs +10 -0
- data/stdlib/zlib/0/need_dict.rbs +13 -0
- data/stdlib/zlib/0/stream_end.rbs +11 -0
- data/stdlib/zlib/0/stream_error.rbs +11 -0
- data/stdlib/zlib/0/version_error.rbs +11 -0
- data/stdlib/zlib/0/zlib.rbs +1 -3
- data/stdlib/zlib/0/zstream.rbs +200 -0
- data/templates/include/rbs/constants.h.erb +20 -0
- data/templates/include/rbs/ruby_objs.h.erb +10 -0
- data/templates/src/constants.c.erb +36 -0
- data/templates/src/ruby_objs.c.erb +27 -0
- data/templates/template.rb +122 -0
- metadata +136 -36
- data/Gemfile +0 -33
- data/Gemfile.lock +0 -118
- data/core/deprecated.rbs +0 -9
- data/ext/rbs_extension/constants.c +0 -135
- data/ext/rbs_extension/ruby_objs.c +0 -525
- data/ext/rbs_extension/ruby_objs.h +0 -43
- data/lib/rbs/constant_table.rb +0 -167
- data/lib/rbs/parser_compat/lexer_error.rb +0 -6
- data/lib/rbs/parser_compat/located_value.rb +0 -7
- data/lib/rbs/parser_compat/semantics_error.rb +0 -6
- data/lib/rbs/parser_compat/syntax_error.rb +0 -6
- data/lib/rbs/test/spy.rb +0 -6
- data/lib/rbs/type_name_resolver.rb +0 -67
- data/sig/constant_table.rbs +0 -30
- data/sig/shims/abstract_syntax_tree.rbs +0 -25
- data/sig/shims/pp.rbs +0 -3
- data/sig/shims/ripper.rbs +0 -8
- data/sig/shims.rbs +0 -69
- data/sig/type_name_resolver.rbs +0 -26
- data/stdlib/minitest/0/manifest.yaml +0 -2
- data/stdlib/prime/0/integer-extension.rbs +0 -41
- data/stdlib/prime/0/manifest.yaml +0 -2
- data/stdlib/prime/0/prime.rbs +0 -372
data/core/ractor.rbs
CHANGED
@@ -1,42 +1,47 @@
|
|
1
1
|
# <!-- rdoc-file=ractor.rb -->
|
2
|
-
# Ractor is
|
2
|
+
# Ractor is an Actor-model abstraction for Ruby that provides thread-safe
|
3
3
|
# parallel execution.
|
4
4
|
#
|
5
|
-
# Ractor.new
|
5
|
+
# Ractor.new makes a new Ractor, which can run in parallel.
|
6
6
|
#
|
7
7
|
# # The simplest ractor
|
8
8
|
# r = Ractor.new {puts "I am in Ractor!"}
|
9
9
|
# r.take # wait for it to finish
|
10
|
-
# #
|
10
|
+
# # Here, "I am in Ractor!" is printed
|
11
11
|
#
|
12
|
-
# Ractors do not share
|
13
|
-
#
|
14
|
-
#
|
12
|
+
# Ractors do not share all objects with each other. There are two main benefits
|
13
|
+
# to this: across ractors, thread-safety concerns such as data-races and
|
14
|
+
# race-conditions are not possible. The other benefit is parallelism.
|
15
15
|
#
|
16
|
-
# To achieve this,
|
17
|
-
#
|
18
|
-
# objects
|
16
|
+
# To achieve this, object sharing is limited across ractors. For example, unlike
|
17
|
+
# in threads, ractors can't access all the objects available in other ractors.
|
18
|
+
# Even objects normally available through variables in the outer scope are
|
19
|
+
# prohibited from being used across ractors.
|
19
20
|
#
|
20
21
|
# a = 1
|
21
22
|
# r = Ractor.new {puts "I am in Ractor! a=#{a}"}
|
22
23
|
# # fails immediately with
|
23
24
|
# # ArgumentError (can not isolate a Proc because it accesses outer variables (a).)
|
24
25
|
#
|
26
|
+
# The object must be explicitly shared:
|
27
|
+
# a = 1
|
28
|
+
# r = Ractor.new(a) { |a1| puts "I am in Ractor! a=#{a1}"}
|
29
|
+
#
|
25
30
|
# On CRuby (the default implementation), Global Virtual Machine Lock (GVL) is
|
26
|
-
# held per ractor, so ractors
|
27
|
-
# other.
|
31
|
+
# held per ractor, so ractors can perform in parallel without locking each
|
32
|
+
# other. This is unlike the situation with threads on CRuby.
|
28
33
|
#
|
29
|
-
# Instead of accessing
|
30
|
-
#
|
34
|
+
# Instead of accessing shared state, objects should be passed to and from
|
35
|
+
# ractors by sending and receiving them as messages.
|
31
36
|
#
|
32
37
|
# a = 1
|
33
38
|
# r = Ractor.new do
|
34
|
-
# a_in_ractor = receive # receive blocks
|
39
|
+
# a_in_ractor = receive # receive blocks until somebody passes a message
|
35
40
|
# puts "I am in Ractor! a=#{a_in_ractor}"
|
36
41
|
# end
|
37
42
|
# r.send(a) # pass it
|
38
43
|
# r.take
|
39
|
-
# #
|
44
|
+
# # Here, "I am in Ractor! a=1" is printed
|
40
45
|
#
|
41
46
|
# There are two pairs of methods for sending/receiving messages:
|
42
47
|
#
|
@@ -45,14 +50,13 @@
|
|
45
50
|
# * Ractor.yield and Ractor#take for when the *receiver* knows the sender
|
46
51
|
# (pull);
|
47
52
|
#
|
53
|
+
# In addition to that, any arguments passed to Ractor.new are passed to the
|
54
|
+
# block and available there as if received by Ractor.receive, and the last block
|
55
|
+
# value is sent outside of the ractor as if sent by Ractor.yield.
|
48
56
|
#
|
49
|
-
#
|
50
|
-
# available there as if received by Ractor.receive, and the last block value
|
51
|
-
# would be sent outside of the ractor as if sent by Ractor.yield.
|
52
|
-
#
|
53
|
-
# A little demonstration on a classic ping-pong:
|
57
|
+
# A little demonstration of a classic ping-pong:
|
54
58
|
#
|
55
|
-
# server = Ractor.new do
|
59
|
+
# server = Ractor.new(name: "server") do
|
56
60
|
# puts "Server starts: #{self.inspect}"
|
57
61
|
# puts "Server sends: ping"
|
58
62
|
# Ractor.yield 'ping' # The server doesn't know the receiver and sends to whoever interested
|
@@ -60,46 +64,49 @@
|
|
60
64
|
# puts "Server received: #{received}"
|
61
65
|
# end
|
62
66
|
#
|
63
|
-
# client = Ractor.new(server) do |srv| # The server is sent
|
67
|
+
# client = Ractor.new(server) do |srv| # The server is sent to the client, and available as srv
|
64
68
|
# puts "Client starts: #{self.inspect}"
|
65
|
-
# received = srv.take # The
|
69
|
+
# received = srv.take # The client takes a message from the server
|
66
70
|
# puts "Client received from " \
|
67
71
|
# "#{srv.inspect}: #{received}"
|
68
72
|
# puts "Client sends to " \
|
69
73
|
# "#{srv.inspect}: pong"
|
70
|
-
# srv.send 'pong' # The client sends a message
|
74
|
+
# srv.send 'pong' # The client sends a message to the server
|
71
75
|
# end
|
72
76
|
#
|
73
|
-
# [client, server].each(&:take) # Wait
|
77
|
+
# [client, server].each(&:take) # Wait until they both finish
|
74
78
|
#
|
75
|
-
# This will output:
|
79
|
+
# This will output something like:
|
76
80
|
#
|
77
|
-
# Server starts: #<Ractor:#2 test.rb:1 running>
|
81
|
+
# Server starts: #<Ractor:#2 server test.rb:1 running>
|
78
82
|
# Server sends: ping
|
79
83
|
# Client starts: #<Ractor:#3 test.rb:8 running>
|
80
|
-
# Client received from #<Ractor:#2
|
81
|
-
# Client sends to #<Ractor:#2
|
84
|
+
# Client received from #<Ractor:#2 server test.rb:1 blocking>: ping
|
85
|
+
# Client sends to #<Ractor:#2 server test.rb:1 blocking>: pong
|
82
86
|
# Server received: pong
|
83
87
|
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
# Ractor#
|
87
|
-
#
|
88
|
+
# Ractors receive their messages via the *incoming port*, and send them to the
|
89
|
+
# *outgoing port*. Either one can be disabled with Ractor#close_incoming and
|
90
|
+
# Ractor#close_outgoing, respectively. When a ractor terminates, its ports are
|
91
|
+
# closed automatically.
|
88
92
|
#
|
89
93
|
# ## Shareable and unshareable objects
|
90
94
|
#
|
91
|
-
# When
|
92
|
-
# whether the object is shareable or unshareable. Most
|
93
|
-
# unshareable objects.
|
95
|
+
# When an object is sent to and from a ractor, it's important to understand
|
96
|
+
# whether the object is shareable or unshareable. Most Ruby objects are
|
97
|
+
# unshareable objects. Even frozen objects can be unshareable if they contain
|
98
|
+
# (through their instance variables) unfrozen objects.
|
94
99
|
#
|
95
|
-
# Shareable objects are
|
96
|
-
#
|
97
|
-
# allows to check this, and Ractor.make_shareable tries to
|
98
|
-
# if it
|
100
|
+
# Shareable objects are those which can be used by several threads without
|
101
|
+
# compromising thread-safety, for example numbers, `true` and `false`.
|
102
|
+
# Ractor.shareable? allows you to check this, and Ractor.make_shareable tries to
|
103
|
+
# make the object shareable if it's not already, and gives an error if it can't
|
104
|
+
# do it.
|
99
105
|
#
|
100
|
-
# Ractor.shareable?(1) #=> true -- numbers and other immutable basic values are
|
101
|
-
# Ractor.shareable?('foo') #=> false, unless the string is frozen due to #
|
106
|
+
# Ractor.shareable?(1) #=> true -- numbers and other immutable basic values are shareable
|
107
|
+
# Ractor.shareable?('foo') #=> false, unless the string is frozen due to # frozen_string_literal: true
|
102
108
|
# Ractor.shareable?('foo'.freeze) #=> true
|
109
|
+
# Ractor.shareable?([Object.new].freeze) #=> false, inner object is unfrozen
|
103
110
|
#
|
104
111
|
# ary = ['hello', 'world']
|
105
112
|
# ary.frozen? #=> false
|
@@ -110,9 +117,9 @@
|
|
110
117
|
# ary[1].frozen? #=> true
|
111
118
|
#
|
112
119
|
# When a shareable object is sent (via #send or Ractor.yield), no additional
|
113
|
-
# processing
|
120
|
+
# processing occurs on it. It just becomes usable by both ractors. When an
|
114
121
|
# unshareable object is sent, it can be either *copied* or *moved*. The first is
|
115
|
-
# the default, and it
|
122
|
+
# the default, and it copies the object fully by deep cloning (Object#clone) the
|
116
123
|
# non-shareable parts of its structure.
|
117
124
|
#
|
118
125
|
# data = ['foo', 'bar'.freeze]
|
@@ -124,18 +131,19 @@
|
|
124
131
|
# r.take
|
125
132
|
# puts "Outside : #{data.object_id}, #{data[0].object_id}, #{data[1].object_id}"
|
126
133
|
#
|
127
|
-
# This will output:
|
134
|
+
# This will output something like:
|
128
135
|
#
|
129
136
|
# In ractor: 340, 360, 320
|
130
137
|
# Outside : 380, 400, 320
|
131
138
|
#
|
132
|
-
#
|
133
|
-
# changed
|
134
|
-
# array's element, which is a shareable frozen string,
|
139
|
+
# Note that the object ids of the array and the non-frozen string inside the
|
140
|
+
# array have changed in the ractor because they are different objects. The
|
141
|
+
# second array's element, which is a shareable frozen string, is the same
|
142
|
+
# object.
|
135
143
|
#
|
136
|
-
# Deep cloning of
|
137
|
-
#
|
138
|
-
# object to the receiving ractor, making it inaccessible
|
144
|
+
# Deep cloning of objects may be slow, and sometimes impossible. Alternatively,
|
145
|
+
# `move: true` may be used during sending. This will *move* the unshareable
|
146
|
+
# object to the receiving ractor, making it inaccessible to the sending ractor.
|
139
147
|
#
|
140
148
|
# data = ['foo', 'bar']
|
141
149
|
# r = Ractor.new do
|
@@ -156,15 +164,17 @@
|
|
156
164
|
# Notice that even `inspect` (and more basic methods like `__id__`) is
|
157
165
|
# inaccessible on a moved object.
|
158
166
|
#
|
159
|
-
#
|
160
|
-
#
|
161
|
-
#
|
162
|
-
# mutable objects are thread-safe, so the thread-safety property will be kept.
|
167
|
+
# Class and Module objects are shareable so the class/module definitions are
|
168
|
+
# shared between ractors. Ractor objects are also shareable. All operations on
|
169
|
+
# shareable objects are thread-safe, so the thread-safety property will be kept.
|
163
170
|
# We can not define mutable shareable objects in Ruby, but C extensions can
|
164
171
|
# introduce them.
|
165
172
|
#
|
166
|
-
# It is prohibited to access instance variables of
|
167
|
-
#
|
173
|
+
# It is prohibited to access (get) instance variables of shareable objects in
|
174
|
+
# other ractors if the values of the variables aren't shareable. This can occur
|
175
|
+
# because modules/classes are shareable, but they can have instance variables
|
176
|
+
# whose values are not. In non-main ractors, it's also prohibited to set
|
177
|
+
# instance variables on classes/modules (even if the value is shareable).
|
168
178
|
#
|
169
179
|
# class C
|
170
180
|
# class << self
|
@@ -172,11 +182,12 @@
|
|
172
182
|
# end
|
173
183
|
# end
|
174
184
|
#
|
175
|
-
# C.tricky =
|
185
|
+
# C.tricky = "unshareable".dup
|
176
186
|
#
|
177
187
|
# r = Ractor.new(C) do |cls|
|
178
188
|
# puts "I see #{cls}"
|
179
189
|
# puts "I can't see #{cls.tricky}"
|
190
|
+
# cls.tricky = true # doesn't get here, but this would also raise an error
|
180
191
|
# end
|
181
192
|
# r.take
|
182
193
|
# # I see C
|
@@ -186,7 +197,7 @@
|
|
186
197
|
# only one that can access non-shareable constants.
|
187
198
|
#
|
188
199
|
# GOOD = 'good'.freeze
|
189
|
-
# BAD = 'bad'
|
200
|
+
# BAD = 'bad'.dup
|
190
201
|
#
|
191
202
|
# r = Ractor.new do
|
192
203
|
# puts "GOOD=#{GOOD}"
|
@@ -211,8 +222,8 @@
|
|
211
222
|
#
|
212
223
|
# ## Ractors vs threads
|
213
224
|
#
|
214
|
-
# Each ractor
|
215
|
-
#
|
225
|
+
# Each ractor has its own main Thread. New threads can be created from inside
|
226
|
+
# ractors (and, on CRuby, they share the GVL with other threads of this ractor).
|
216
227
|
#
|
217
228
|
# r = Ractor.new do
|
218
229
|
# a = 1
|
@@ -223,33 +234,56 @@
|
|
223
234
|
#
|
224
235
|
# ## Note on code examples
|
225
236
|
#
|
226
|
-
# In examples below, sometimes we use the following method to wait
|
227
|
-
# that are not currently blocked
|
228
|
-
# method.
|
237
|
+
# In the examples below, sometimes we use the following method to wait for
|
238
|
+
# ractors that are not currently blocked to finish (or to make progress).
|
229
239
|
#
|
230
240
|
# def wait
|
231
241
|
# sleep(0.1)
|
232
242
|
# end
|
233
243
|
#
|
234
244
|
# It is **only for demonstration purposes** and shouldn't be used in a real
|
235
|
-
# code. Most of the
|
245
|
+
# code. Most of the time, #take is used to wait for ractors to finish.
|
236
246
|
#
|
237
247
|
# ## Reference
|
238
248
|
#
|
239
249
|
# See [Ractor design doc](rdoc-ref:ractor.md) for more details.
|
240
250
|
#
|
241
251
|
class Ractor
|
252
|
+
# <!--
|
253
|
+
# rdoc-file=ractor.rb
|
254
|
+
# - _require(feature)
|
255
|
+
# -->
|
256
|
+
# internal method
|
257
|
+
#
|
258
|
+
def self._require: (String feature) -> bool
|
259
|
+
|
260
|
+
# <!--
|
261
|
+
# rdoc-file=ractor.rb
|
262
|
+
# - [](sym)
|
263
|
+
# -->
|
264
|
+
# get a value from ractor-local storage of current Ractor
|
265
|
+
#
|
266
|
+
def self.[]: (Symbol) -> untyped
|
267
|
+
|
268
|
+
# <!--
|
269
|
+
# rdoc-file=ractor.rb
|
270
|
+
# - []=(sym, val)
|
271
|
+
# -->
|
272
|
+
# set a value in ractor-local storage of current Ractor
|
273
|
+
#
|
274
|
+
def self.[]=: (Symbol, untyped) -> untyped
|
275
|
+
|
242
276
|
# <!--
|
243
277
|
# rdoc-file=ractor.rb
|
244
278
|
# - count()
|
245
279
|
# -->
|
246
|
-
# Returns
|
280
|
+
# Returns the number of Ractors currently running or blocking (waiting).
|
247
281
|
#
|
248
282
|
# Ractor.count #=> 1
|
249
283
|
# r = Ractor.new(name: 'example') { Ractor.yield(1) }
|
250
284
|
# Ractor.count #=> 2 (main + example ractor)
|
251
285
|
# r.take # wait for Ractor.yield(1)
|
252
|
-
# r.take # wait
|
286
|
+
# r.take # wait until r will finish
|
253
287
|
# Ractor.count #=> 1
|
254
288
|
#
|
255
289
|
def self.count: () -> Integer
|
@@ -270,7 +304,15 @@ class Ractor
|
|
270
304
|
# -->
|
271
305
|
# returns main ractor
|
272
306
|
#
|
273
|
-
def self.main: () ->
|
307
|
+
def self.main: () -> Ractor
|
308
|
+
|
309
|
+
# <!--
|
310
|
+
# rdoc-file=ractor.rb
|
311
|
+
# - main?()
|
312
|
+
# -->
|
313
|
+
# return true if the current ractor is main ractor
|
314
|
+
#
|
315
|
+
def self.main?: () -> boolish
|
274
316
|
|
275
317
|
# <!--
|
276
318
|
# rdoc-file=ractor.rb
|
@@ -281,8 +323,8 @@ class Ractor
|
|
281
323
|
# `obj` and all the objects it refers to will be frozen, unless they are already
|
282
324
|
# shareable.
|
283
325
|
#
|
284
|
-
# If `copy` keyword is `true`,
|
285
|
-
#
|
326
|
+
# If `copy` keyword is `true`, it will copy objects before freezing them, and
|
327
|
+
# will not modify `obj` or its internal objects.
|
286
328
|
#
|
287
329
|
# Note that the specification and implementation of this method are not mature
|
288
330
|
# and may be changed in the future.
|
@@ -317,16 +359,16 @@ class Ractor
|
|
317
359
|
# -->
|
318
360
|
# Create a new Ractor with args and a block.
|
319
361
|
#
|
320
|
-
#
|
321
|
-
# inside the block will refer to the current Ractor.
|
362
|
+
# The given block (Proc) will be isolated (can't access any outer variables).
|
363
|
+
# `self` inside the block will refer to the current Ractor.
|
322
364
|
#
|
323
365
|
# r = Ractor.new { puts "Hi, I am #{self.inspect}" }
|
324
366
|
# r.take
|
325
367
|
# # Prints "Hi, I am #<Ractor:#2 test.rb:1 running>"
|
326
368
|
#
|
327
|
-
# `args` passed
|
328
|
-
#
|
329
|
-
# shareable,
|
369
|
+
# Any `args` passed are propagated to the block arguments by the same rules as
|
370
|
+
# objects sent via #send/Ractor.receive. If an argument in `args` is not
|
371
|
+
# shareable, it will be copied (via deep cloning, which might be inefficient).
|
330
372
|
#
|
331
373
|
# arg = [1, 2, 3]
|
332
374
|
# puts "Passing: #{arg} (##{arg.object_id})"
|
@@ -340,18 +382,18 @@ class Ractor
|
|
340
382
|
#
|
341
383
|
# Ractor's `name` can be set for debugging purposes:
|
342
384
|
#
|
343
|
-
# r = Ractor.new(name: 'my ractor') {}
|
385
|
+
# r = Ractor.new(name: 'my ractor') {}; r.take
|
344
386
|
# p r
|
345
387
|
# #=> #<Ractor:#3 my ractor test.rb:1 terminated>
|
346
388
|
#
|
347
|
-
def self.new: (*untyped args, ?name: string) { (
|
389
|
+
def self.new: (*untyped args, ?name: string) { (?) -> untyped } -> Ractor
|
348
390
|
|
349
391
|
# <!--
|
350
392
|
# rdoc-file=ractor.rb
|
351
393
|
# - Ractor.receive -> msg
|
352
394
|
# -->
|
353
|
-
# Receive
|
354
|
-
#
|
395
|
+
# Receive a message from the incoming port of the current ractor (which was sent
|
396
|
+
# there by #send from another ractor).
|
355
397
|
#
|
356
398
|
# r = Ractor.new do
|
357
399
|
# v1 = Ractor.receive
|
@@ -361,7 +403,7 @@ class Ractor
|
|
361
403
|
# r.take
|
362
404
|
# # Here will be printed: "Received: message1"
|
363
405
|
#
|
364
|
-
# Alternatively, private instance method `receive` may be used:
|
406
|
+
# Alternatively, the private instance method `receive` may be used:
|
365
407
|
#
|
366
408
|
# r = Ractor.new do
|
367
409
|
# v1 = receive
|
@@ -369,7 +411,7 @@ class Ractor
|
|
369
411
|
# end
|
370
412
|
# r.send('message1')
|
371
413
|
# r.take
|
372
|
-
# #
|
414
|
+
# # This prints: "Received: message1"
|
373
415
|
#
|
374
416
|
# The method blocks if the queue is empty.
|
375
417
|
#
|
@@ -397,7 +439,7 @@ class Ractor
|
|
397
439
|
# Received: message2
|
398
440
|
#
|
399
441
|
# If close_incoming was called on the ractor, the method raises
|
400
|
-
# Ractor::ClosedError if there are no more messages in incoming queue:
|
442
|
+
# Ractor::ClosedError if there are no more messages in the incoming queue:
|
401
443
|
#
|
402
444
|
# Ractor.new do
|
403
445
|
# close_incoming
|
@@ -414,8 +456,9 @@ class Ractor
|
|
414
456
|
# -->
|
415
457
|
# Receive only a specific message.
|
416
458
|
#
|
417
|
-
# Instead of Ractor.receive, Ractor.receive_if can
|
418
|
-
# and you can choose the
|
459
|
+
# Instead of Ractor.receive, Ractor.receive_if can be given a pattern (or any
|
460
|
+
# filter) in a block and you can choose the messages to accept that are
|
461
|
+
# available in your ractor's incoming queue.
|
419
462
|
#
|
420
463
|
# r = Ractor.new do
|
421
464
|
# p Ractor.receive_if{|msg| msg.match?(/foo/)} #=> "foo3"
|
@@ -433,9 +476,9 @@ class Ractor
|
|
433
476
|
# bar1
|
434
477
|
# baz2
|
435
478
|
#
|
436
|
-
# If the block returns a truthy value, the message
|
437
|
-
#
|
438
|
-
#
|
479
|
+
# If the block returns a truthy value, the message is removed from the incoming
|
480
|
+
# queue and returned. Otherwise, the message remains in the incoming queue and
|
481
|
+
# the next messages are checked by the given block.
|
439
482
|
#
|
440
483
|
# If there are no messages left in the incoming queue, the method will block
|
441
484
|
# until new messages arrive.
|
@@ -461,7 +504,7 @@ class Ractor
|
|
461
504
|
# Received successfully: [1, 2, 3]
|
462
505
|
#
|
463
506
|
# Note that you can not call receive/receive_if in the given block recursively.
|
464
|
-
#
|
507
|
+
# You should not do any tasks in the block other than message filtration.
|
465
508
|
#
|
466
509
|
# Ractor.current << true
|
467
510
|
# Ractor.receive_if{|msg| Ractor.receive}
|
@@ -480,8 +523,8 @@ class Ractor
|
|
480
523
|
# rdoc-file=ractor.rb
|
481
524
|
# - Ractor.select(*ractors, [yield_value:, move: false]) -> [ractor or symbol, obj]
|
482
525
|
# -->
|
483
|
-
#
|
484
|
-
#
|
526
|
+
# Wait for any ractor to have something in its outgoing port, read from this
|
527
|
+
# ractor, and then return that ractor and the object received.
|
485
528
|
#
|
486
529
|
# r1 = Ractor.new {Ractor.yield 'from 1'}
|
487
530
|
# r2 = Ractor.new {Ractor.yield 'from 2'}
|
@@ -490,9 +533,10 @@ class Ractor
|
|
490
533
|
#
|
491
534
|
# puts "received #{obj.inspect} from #{r.inspect}"
|
492
535
|
# # Prints: received "from 1" from #<Ractor:#2 test.rb:1 running>
|
536
|
+
# # But could just as well print "from r2" here, either prints could be first.
|
493
537
|
#
|
494
|
-
# If one of the given ractors is the current ractor, and it
|
495
|
-
#
|
538
|
+
# If one of the given ractors is the current ractor, and it is selected, `r`
|
539
|
+
# will contain the `:receive` symbol instead of the ractor object.
|
496
540
|
#
|
497
541
|
# r1 = Ractor.new(Ractor.current) do |main|
|
498
542
|
# main.send 'to main'
|
@@ -504,10 +548,10 @@ class Ractor
|
|
504
548
|
#
|
505
549
|
# r, obj = Ractor.select(r1, r2, Ractor.current)
|
506
550
|
# puts "received #{obj.inspect} from #{r.inspect}"
|
507
|
-
# #
|
551
|
+
# # Could print: received "to main" from :receive
|
508
552
|
#
|
509
|
-
# If `yield_value` is provided, that value may be yielded if another
|
510
|
-
# calling #take. In this case, the pair `[:yield, nil]`
|
553
|
+
# If `yield_value` is provided, that value may be yielded if another ractor is
|
554
|
+
# calling #take. In this case, the pair `[:yield, nil]` is returned:
|
511
555
|
#
|
512
556
|
# r1 = Ractor.new(Ractor.current) do |main|
|
513
557
|
# puts "Received from main: #{main.take}"
|
@@ -524,8 +568,8 @@ class Ractor
|
|
524
568
|
# Received from main: 123
|
525
569
|
# Received nil from :yield
|
526
570
|
#
|
527
|
-
# `move` boolean flag defines whether yielded value
|
528
|
-
#
|
571
|
+
# `move` boolean flag defines whether yielded value will be copied (default) or
|
572
|
+
# moved.
|
529
573
|
#
|
530
574
|
def self.select: (*Ractor ractors, ?move: boolish, ?yield_value: untyped) -> [ Ractor | Symbol, untyped ]
|
531
575
|
|
@@ -536,7 +580,7 @@ class Ractor
|
|
536
580
|
# Checks if the object is shareable by ractors.
|
537
581
|
#
|
538
582
|
# Ractor.shareable?(1) #=> true -- numbers and other immutable basic values are frozen
|
539
|
-
# Ractor.shareable?('foo') #=> false, unless the string is frozen due to #
|
583
|
+
# Ractor.shareable?('foo') #=> false, unless the string is frozen due to # frozen_string_literal: true
|
540
584
|
# Ractor.shareable?('foo'.freeze) #=> true
|
541
585
|
#
|
542
586
|
# See also the "Shareable and unshareable objects" section in the Ractor class
|
@@ -544,17 +588,34 @@ class Ractor
|
|
544
588
|
#
|
545
589
|
def self.shareable?: (untyped obj) -> bool
|
546
590
|
|
591
|
+
# <!--
|
592
|
+
# rdoc-file=ractor.rb
|
593
|
+
# - Ractor.store_if_absent(key){ init_block }
|
594
|
+
# -->
|
595
|
+
# If the correponding value is not set, yield a value with init_block and store
|
596
|
+
# the value in thread-safe manner. This method returns corresponding stored
|
597
|
+
# value.
|
598
|
+
#
|
599
|
+
# (1..10).map{
|
600
|
+
# Thread.new(it){|i|
|
601
|
+
# Ractor.store_if_absent(:s){ f(); i }
|
602
|
+
# #=> return stored value of key :s
|
603
|
+
# }
|
604
|
+
# }.map(&:value).uniq.size #=> 1 and f() is called only once
|
605
|
+
#
|
606
|
+
def self.store_if_absent: [A] (Symbol) { (nil) -> A } -> A
|
607
|
+
|
547
608
|
# <!--
|
548
609
|
# rdoc-file=ractor.rb
|
549
610
|
# - Ractor.yield(msg, move: false) -> nil
|
550
611
|
# -->
|
551
|
-
# Send a message to the current ractor's outgoing port to be
|
612
|
+
# Send a message to the current ractor's outgoing port to be accepted by #take.
|
552
613
|
#
|
553
614
|
# r = Ractor.new {Ractor.yield 'Hello from ractor'}
|
554
615
|
# puts r.take
|
555
616
|
# # Prints: "Hello from ractor"
|
556
617
|
#
|
557
|
-
#
|
618
|
+
# This method is blocking, and will return only when somebody consumes the sent
|
558
619
|
# message.
|
559
620
|
#
|
560
621
|
# r = Ractor.new do
|
@@ -580,12 +641,10 @@ class Ractor
|
|
580
641
|
# wait
|
581
642
|
# # `yield': The outgoing-port is already closed (Ractor::ClosedError)
|
582
643
|
#
|
583
|
-
# The meaning of `move` argument is the same as for #send.
|
644
|
+
# The meaning of the `move` argument is the same as for #send.
|
584
645
|
#
|
585
646
|
def self.yield: (untyped obj, ?move: boolish) -> untyped
|
586
647
|
|
587
|
-
public
|
588
|
-
|
589
648
|
# <!--
|
590
649
|
# rdoc-file=ractor.rb
|
591
650
|
# - <<(obj, move: false)
|
@@ -597,25 +656,27 @@ class Ractor
|
|
597
656
|
# rdoc-file=ractor.rb
|
598
657
|
# - [](sym)
|
599
658
|
# -->
|
600
|
-
# get a value from ractor-local storage
|
659
|
+
# get a value from ractor-local storage of current Ractor Obsolete and use
|
660
|
+
# Ractor.[] instead.
|
601
661
|
#
|
602
|
-
def []: (
|
662
|
+
def []: (interned sym) -> untyped
|
603
663
|
|
604
664
|
# <!--
|
605
665
|
# rdoc-file=ractor.rb
|
606
666
|
# - []=(sym, val)
|
607
667
|
# -->
|
608
|
-
# set a value in ractor-local storage
|
668
|
+
# set a value in ractor-local storage of current Ractor Obsolete and use
|
669
|
+
# Ractor.[]= instead.
|
609
670
|
#
|
610
|
-
def []=: [T] (
|
671
|
+
def []=: [T] (interned sym, T val) -> T
|
611
672
|
|
612
673
|
# <!--
|
613
674
|
# rdoc-file=ractor.rb
|
614
675
|
# - ractor.close_incoming -> true | false
|
615
676
|
# -->
|
616
|
-
# Closes the incoming port and returns
|
617
|
-
# to Ractor.receive in the ractor, and #send to the ractor will
|
618
|
-
# Ractor::ClosedError.
|
677
|
+
# Closes the incoming port and returns whether it was already closed. All
|
678
|
+
# further attempts to Ractor.receive in the ractor, and #send to the ractor will
|
679
|
+
# fail with Ractor::ClosedError.
|
619
680
|
#
|
620
681
|
# r = Ractor.new {sleep(500)}
|
621
682
|
# r.close_incoming #=> false
|
@@ -629,9 +690,9 @@ class Ractor
|
|
629
690
|
# rdoc-file=ractor.rb
|
630
691
|
# - ractor.close_outgoing -> true | false
|
631
692
|
# -->
|
632
|
-
# Closes the outgoing port and returns
|
633
|
-
# to Ractor.yield in the ractor, and #take from the ractor will
|
634
|
-
# Ractor::ClosedError.
|
693
|
+
# Closes the outgoing port and returns whether it was already closed. All
|
694
|
+
# further attempts to Ractor.yield in the ractor, and #take from the ractor will
|
695
|
+
# fail with Ractor::ClosedError.
|
635
696
|
#
|
636
697
|
# r = Ractor.new {sleep(500)}
|
637
698
|
# r.close_outgoing #=> false
|
@@ -660,7 +721,7 @@ class Ractor
|
|
660
721
|
# rdoc-file=ractor.rb
|
661
722
|
# - ractor.send(msg, move: false) -> self
|
662
723
|
# -->
|
663
|
-
# Send a message to a Ractor's incoming queue to be
|
724
|
+
# Send a message to a Ractor's incoming queue to be accepted by Ractor.receive.
|
664
725
|
#
|
665
726
|
# r = Ractor.new do
|
666
727
|
# value = Ractor.receive
|
@@ -677,7 +738,7 @@ class Ractor
|
|
677
738
|
# puts "Sent successfully"
|
678
739
|
# # Prints: "Sent successfully" immediately
|
679
740
|
#
|
680
|
-
#
|
741
|
+
# An attempt to send to a ractor which already finished its execution will raise
|
681
742
|
# Ractor::ClosedError.
|
682
743
|
#
|
683
744
|
# r = Ractor.new {}
|
@@ -697,11 +758,11 @@ class Ractor
|
|
697
758
|
# r.close_incoming
|
698
759
|
# r.send('test')
|
699
760
|
# # Ractor::ClosedError (The incoming-port is already closed)
|
700
|
-
# # The error
|
761
|
+
# # The error is raised immediately, not when the ractor tries to receive
|
701
762
|
#
|
702
|
-
# If the `obj` is unshareable, by default it
|
703
|
-
# cloning. If
|
704
|
-
# becomes inaccessible to sender.
|
763
|
+
# If the `obj` is unshareable, by default it will be copied into the receiving
|
764
|
+
# ractor by deep cloning. If `move: true` is passed, the object is *moved* into
|
765
|
+
# the receiving ractor and becomes inaccessible to the sender.
|
705
766
|
#
|
706
767
|
# r = Ractor.new {puts "Received: #{receive}"}
|
707
768
|
# msg = 'message'
|
@@ -714,7 +775,7 @@ class Ractor
|
|
714
775
|
# Received: message
|
715
776
|
# in `p': undefined method `inspect' for #<Ractor::MovedObject:0x000055c99b9b69b8>
|
716
777
|
#
|
717
|
-
# All references to the object and its parts will become invalid
|
778
|
+
# All references to the object and its parts will become invalid to the sender.
|
718
779
|
#
|
719
780
|
# r = Ractor.new {puts "Received: #{receive}"}
|
720
781
|
# s = 'message'
|
@@ -732,7 +793,7 @@ class Ractor
|
|
732
793
|
# # Ractor::MovedError (can not send any methods to a moved object)
|
733
794
|
# # ...but its item was still a reference to `s`, which was moved
|
734
795
|
#
|
735
|
-
# If the object
|
796
|
+
# If the object is shareable, `move: true` has no effect on it:
|
736
797
|
#
|
737
798
|
# r = Ractor.new {puts "Received: #{receive}"}
|
738
799
|
# s = 'message'.freeze
|
@@ -745,8 +806,8 @@ class Ractor
|
|
745
806
|
# rdoc-file=ractor.rb
|
746
807
|
# - ractor.take -> msg
|
747
808
|
# -->
|
748
|
-
#
|
749
|
-
# Ractor.yield or at ractor's
|
809
|
+
# Get a message from the ractor's outgoing port, which was put there by
|
810
|
+
# Ractor.yield or at ractor's termination.
|
750
811
|
#
|
751
812
|
# r = Ractor.new do
|
752
813
|
# Ractor.yield 'explicit yield'
|
@@ -756,10 +817,10 @@ class Ractor
|
|
756
817
|
# puts r.take #=> 'last value'
|
757
818
|
# puts r.take # Ractor::ClosedError (The outgoing-port is already closed)
|
758
819
|
#
|
759
|
-
# The fact that the last value is also
|
760
|
-
# can be used as
|
761
|
-
#
|
762
|
-
#
|
820
|
+
# The fact that the last value is also sent to the outgoing port means that
|
821
|
+
# `take` can be used as an analog of Thread#join ("just wait until ractor
|
822
|
+
# finishes"). However, it will raise if somebody has already consumed that
|
823
|
+
# message.
|
763
824
|
#
|
764
825
|
# If the outgoing port was closed with #close_outgoing, the method will raise
|
765
826
|
# Ractor::ClosedError.
|
@@ -773,7 +834,7 @@ class Ractor
|
|
773
834
|
# # Ractor::ClosedError (The outgoing-port is already closed)
|
774
835
|
# # The error would be raised immediately, not when ractor will try to receive
|
775
836
|
#
|
776
|
-
# If an uncaught exception is raised in the Ractor, it is propagated
|
837
|
+
# If an uncaught exception is raised in the Ractor, it is propagated by take as
|
777
838
|
# a Ractor::RemoteError.
|
778
839
|
#
|
779
840
|
# r = Ractor.new {raise "Something weird happened"}
|
@@ -786,8 +847,9 @@ class Ractor
|
|
786
847
|
# p e.cause # => #<RuntimeError: Something weird happened>
|
787
848
|
# end
|
788
849
|
#
|
789
|
-
# Ractor::ClosedError is a descendant of StopIteration, so the
|
790
|
-
# ractor will break
|
850
|
+
# Ractor::ClosedError is a descendant of StopIteration, so the termination of
|
851
|
+
# the ractor will break out of any loops that receive this message without
|
852
|
+
# propagating the error:
|
791
853
|
#
|
792
854
|
# r = Ractor.new do
|
793
855
|
# 3.times {|i| Ractor.yield "message #{i}"}
|
@@ -828,6 +890,7 @@ class Ractor
|
|
828
890
|
# rdoc-file=ractor.rb
|
829
891
|
# - receive_if(&b)
|
830
892
|
# -->
|
893
|
+
# same as Ractor.receive_if
|
831
894
|
#
|
832
895
|
def receive_if: () { (untyped) -> boolish } -> untyped
|
833
896
|
|
@@ -910,8 +973,6 @@ class Ractor
|
|
910
973
|
# # Ractor::MovedError (can not send any methods to a moved object)
|
911
974
|
#
|
912
975
|
class MovedObject < BasicObject
|
913
|
-
public
|
914
|
-
|
915
976
|
# <!--
|
916
977
|
# rdoc-file=ractor.c
|
917
978
|
# - !(*args)
|
@@ -992,11 +1053,16 @@ class Ractor
|
|
992
1053
|
# end
|
993
1054
|
#
|
994
1055
|
class RemoteError < Ractor::Error
|
995
|
-
|
996
|
-
|
1056
|
+
# <!-- rdoc-file=ractor.rb -->
|
1057
|
+
# The Ractor an uncaught exception is raised in.
|
1058
|
+
#
|
997
1059
|
def ractor: () -> Ractor
|
998
1060
|
end
|
999
1061
|
|
1000
1062
|
class UnsafeError < Ractor::Error
|
1001
1063
|
end
|
1064
|
+
|
1065
|
+
%a{annotate:rdoc:skip}
|
1066
|
+
class Selector
|
1067
|
+
end
|
1002
1068
|
end
|