From 130c37d6e60b0b654b93cb09c37b18718e35c0b9 Mon Sep 17 00:00:00 2001 From: Earlopain <14981592+Earlopain@users.noreply.github.com> Date: Fri, 6 Feb 2026 20:08:46 +0100 Subject: [PATCH 01/10] [ruby/prism] More docs improvements (https://github.com/ruby/prism/pull/3910) * Update C call seqs * Prefixing them with self is unusual * Also use `.` instead of `::` to refer to class methods * Capitalize location in docs It allows it to be linked to in docs * Miscelanous other doc tweaks * Format code as code * Nodoc some missed methods * Fix method reference * Really try to nodoc ffi module The previous approach was wrong, to nodoc the class methods it must be specified at the module itself. As a result, the private methods like `dump_options` are also removed. * Remove some def-style comments They are mostly redundant with the method signature and don't look great when rendered. Still remaining on nodes. I will improve docs for them in a separate PR https://github.com/ruby/prism/commit/94e5525521 --- lib/prism.rb | 8 +- lib/prism/desugar_compiler.rb | 60 +++---- lib/prism/ffi.rb | 4 +- lib/prism/parse_result.rb | 10 +- lib/prism/pattern.rb | 2 +- prism/api_pack.c | 2 +- prism/config.yml | 177 ++++++++++---------- prism/extension.c | 80 ++++----- prism/templates/lib/prism/dispatcher.rb.erb | 8 - 9 files changed, 172 insertions(+), 179 deletions(-) diff --git a/lib/prism.rb b/lib/prism.rb index 781bd4bb0115db..4fbe67a717e009 100644 --- a/lib/prism.rb +++ b/lib/prism.rb @@ -56,18 +56,18 @@ def initialize(version) end # :call-seq: - # Prism::lex_compat(source, **options) -> LexCompat::Result + # lex_compat(source, **options) -> LexCompat::Result # # Returns a parse result whose value is an array of tokens that closely - # resembles the return value of Ripper::lex. + # resembles the return value of Ripper.lex. # - # For supported options, see Prism::parse. + # For supported options, see Prism.parse. def self.lex_compat(source, **options) LexCompat.new(source, **options).result # steep:ignore end # :call-seq: - # Prism::load(source, serialized, freeze) -> ParseResult + # load(source, serialized, freeze) -> ParseResult # # Load the serialized AST using the source as a reference into a tree. def self.load(source, serialized, freeze = false) diff --git a/lib/prism/desugar_compiler.rb b/lib/prism/desugar_compiler.rb index 5d7d38d84153ce..7d4201c1c47b50 100644 --- a/lib/prism/desugar_compiler.rb +++ b/lib/prism/desugar_compiler.rb @@ -254,137 +254,137 @@ def desugar # :nodoc: # DesugarCompiler is a compiler that desugars Ruby code into a more primitive # form. This is useful for consumers that want to deal with fewer node types. class DesugarCompiler < MutationCompiler - # @@foo &&= bar + # `@@foo &&= bar` # # becomes # - # @@foo && @@foo = bar + # `@@foo && @@foo = bar` def visit_class_variable_and_write_node(node) node.desugar end - # @@foo ||= bar + # `@@foo ||= bar` # # becomes # - # defined?(@@foo) ? @@foo : @@foo = bar + # `defined?(@@foo) ? @@foo : @@foo = bar` def visit_class_variable_or_write_node(node) node.desugar end - # @@foo += bar + # `@@foo += bar` # # becomes # - # @@foo = @@foo + bar + # `@@foo = @@foo + bar` def visit_class_variable_operator_write_node(node) node.desugar end - # Foo &&= bar + # `Foo &&= bar` # # becomes # - # Foo && Foo = bar + # `Foo && Foo = bar` def visit_constant_and_write_node(node) node.desugar end - # Foo ||= bar + # `Foo ||= bar` # # becomes # - # defined?(Foo) ? Foo : Foo = bar + # `defined?(Foo) ? Foo : Foo = bar` def visit_constant_or_write_node(node) node.desugar end - # Foo += bar + # `Foo += bar` # # becomes # - # Foo = Foo + bar + # `Foo = Foo + bar` def visit_constant_operator_write_node(node) node.desugar end - # $foo &&= bar + # `$foo &&= bar` # # becomes # - # $foo && $foo = bar + # `$foo && $foo = bar` def visit_global_variable_and_write_node(node) node.desugar end - # $foo ||= bar + # `$foo ||= bar` # # becomes # - # defined?($foo) ? $foo : $foo = bar + # `defined?($foo) ? $foo : $foo = bar` def visit_global_variable_or_write_node(node) node.desugar end - # $foo += bar + # `$foo += bar` # # becomes # - # $foo = $foo + bar + # `$foo = $foo + bar` def visit_global_variable_operator_write_node(node) node.desugar end - # @foo &&= bar + # `@foo &&= bar` # # becomes # - # @foo && @foo = bar + # `@foo && @foo = bar` def visit_instance_variable_and_write_node(node) node.desugar end - # @foo ||= bar + # `@foo ||= bar` # # becomes # - # @foo || @foo = bar + # `@foo || @foo = bar` def visit_instance_variable_or_write_node(node) node.desugar end - # @foo += bar + # `@foo += bar` # # becomes # - # @foo = @foo + bar + # `@foo = @foo + bar` def visit_instance_variable_operator_write_node(node) node.desugar end - # foo &&= bar + # `foo &&= bar` # # becomes # - # foo && foo = bar + # `foo && foo = bar` def visit_local_variable_and_write_node(node) node.desugar end - # foo ||= bar + # `foo ||= bar` # # becomes # - # foo || foo = bar + # `foo || foo = bar` def visit_local_variable_or_write_node(node) node.desugar end - # foo += bar + # `foo += bar` # # becomes # - # foo = foo + bar + # `foo = foo + bar` def visit_local_variable_operator_write_node(node) node.desugar end diff --git a/lib/prism/ffi.rb b/lib/prism/ffi.rb index 520c773b43a408..1bcbfc367ccc3f 100644 --- a/lib/prism/ffi.rb +++ b/lib/prism/ffi.rb @@ -12,7 +12,7 @@ # autoloaded from within a non-main Ractor. require "prism/serialize" if defined?(Ractor) -module Prism +module Prism # :nodoc: module LibRubyParser # :nodoc: extend FFI::Library @@ -233,7 +233,7 @@ def self.with_file(filepath) # The version constant is set by reading the result of calling pm_version. VERSION = LibRubyParser.pm_version.read_string.freeze - class << self # :nodoc: + class << self # Mirror the Prism.dump API by using the serialization API. def dump(source, **options) LibRubyParser::PrismString.with_string(source) { |string| dump_common(string, options) } diff --git a/lib/prism/parse_result.rb b/lib/prism/parse_result.rb index 53ca168c0e81a1..07529c4295cc87 100644 --- a/lib/prism/parse_result.rb +++ b/lib/prism/parse_result.rb @@ -519,7 +519,7 @@ def adjoin(string) # This represents a comment that was encountered during parsing. It is the # base class for all comment types. class Comment - # The location of this comment in the source. + # The Location of this comment in the source. attr_reader :location # Create a new comment object with the given location. @@ -556,7 +556,7 @@ def inspect # :nodoc: # EmbDocComment objects correspond to comments that are surrounded by =begin # and =end. class EmbDocComment < Comment - # This can only be true for inline comments. + # Returns false. This can only be true for inline comments. def trailing? false end @@ -670,9 +670,9 @@ def inspect # :nodoc: end end - # This represents the result of a call to ::parse or ::parse_file. It contains - # the requested structure, any comments that were encounters, and any errors - # that were encountered. + # This represents the result of a call to Prism.parse or Prism.parse_file. + # It contains the requested structure, any comments that were encounters, + # and any errors that were encountered. class Result # The list of comments that were encountered during parsing. attr_reader :comments diff --git a/lib/prism/pattern.rb b/lib/prism/pattern.rb index 4a0c5ef54de46a..dde9d3b6f96b06 100644 --- a/lib/prism/pattern.rb +++ b/lib/prism/pattern.rb @@ -41,7 +41,7 @@ class Pattern class CompilationError < StandardError # Create a new CompilationError with the given representation of the node # that caused the error. - def initialize(repr) + def initialize(repr) # :nodoc: super(<<~ERROR) prism was unable to compile the pattern you provided into a usable expression. It failed on to understand the node represented by: diff --git a/prism/api_pack.c b/prism/api_pack.c index 98509ae65ccae0..84dc613de0a03a 100644 --- a/prism/api_pack.c +++ b/prism/api_pack.c @@ -173,7 +173,7 @@ pack_encoding_to_ruby(pm_pack_encoding encoding) { /** * call-seq: - * Pack::parse(version, variant, source) -> Format + * parse(version, variant, source) -> Format * * Parse the given source and return a format object. */ diff --git a/prism/config.yml b/prism/config.yml index 4e1560481e9d9e..f6e99c66b11566 100644 --- a/prism/config.yml +++ b/prism/config.yml @@ -817,7 +817,7 @@ nodes: - name: keyword_loc type: location comment: | - The location of the `alias` keyword. + The Location of the `alias` keyword. alias $foo $bar ^^^^^ @@ -865,7 +865,7 @@ nodes: - name: keyword_loc type: location comment: | - Represents the location of the `alias` keyword. + Represents the Location of the `alias` keyword. alias foo bar ^^^^^ @@ -895,7 +895,7 @@ nodes: - name: operator_loc type: location comment: | - Represents the alternation operator location. + Represents the alternation operator Location. foo => bar | baz ^ @@ -931,7 +931,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `and` keyword or the `&&` operator. + The Location of the `and` keyword or the `&&` operator. left and right ^^^ @@ -966,7 +966,7 @@ nodes: - name: opening_loc type: location? comment: | - Represents the optional source location for the opening token. + Represents the optional source Location for the opening token. [1,2,3] # "[" %w[foo bar baz] # "%w[" @@ -975,7 +975,7 @@ nodes: - name: closing_loc type: location? comment: | - Represents the optional source location for the closing token. + Represents the optional source Location for the closing token. [1,2,3] # "]" %w[foo bar baz] # "]" @@ -1031,14 +1031,14 @@ nodes: - name: opening_loc type: location? comment: | - Represents the opening location of the array pattern. + Represents the opening Location of the array pattern. foo in [1, 2] ^ - name: closing_loc type: location? comment: | - Represents the closing location of the array pattern. + Represents the closing Location of the array pattern. foo in [1, 2] ^ @@ -1089,7 +1089,7 @@ nodes: - name: operator_loc type: location? comment: | - The location of the `=>` operator, if present. + The Location of the `=>` operator, if present. { foo => bar } ^^ @@ -1111,7 +1111,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `**` operator. + The Location of the `**` operator. { **x } ^^ @@ -1140,7 +1140,7 @@ nodes: - name: begin_keyword_loc type: location? comment: | - Represents the location of the `begin` keyword. + Represents the Location of the `begin` keyword. begin x end ^^^^^ @@ -1179,7 +1179,7 @@ nodes: - name: end_keyword_loc type: location? comment: | - Represents the location of the `end` keyword. + Represents the Location of the `end` keyword. begin x end ^^^ @@ -1204,7 +1204,7 @@ nodes: - name: operator_loc type: location comment: | - Represents the location of the `&` operator. + Represents the Location of the `&` operator. foo(&args) ^ @@ -1265,14 +1265,14 @@ nodes: - name: opening_loc type: location comment: | - Represents the location of the opening `{` or `do`. + Represents the Location of the opening `{` or `do`. [1, 2, 3].each { |i| puts x } ^ - name: closing_loc type: location comment: | - Represents the location of the closing `}` or `end`. + Represents the Location of the closing `}` or `end`. [1, 2, 3].each { |i| puts x } ^ @@ -1295,14 +1295,14 @@ nodes: - name: name_loc type: location? comment: | - Represents the location of the block parameter name. + Represents the Location of the block parameter name. def a(&b) ^ - name: operator_loc type: location comment: | - Represents the location of the `&` operator. + Represents the Location of the `&` operator. def a(&b) ^ @@ -1342,7 +1342,7 @@ nodes: - name: opening_loc type: location? comment: | - Represents the opening location of the block parameters. + Represents the opening Location of the block parameters. -> (a, b = 1; local) { } ^ @@ -1353,7 +1353,7 @@ nodes: - name: closing_loc type: location? comment: | - Represents the closing location of the block parameters. + Represents the closing Location of the block parameters. -> (a, b = 1; local) { } ^ @@ -1383,7 +1383,7 @@ nodes: - name: keyword_loc type: location comment: | - The location of the `break` keyword. + The Location of the `break` keyword. break foo ^^^^^ @@ -1406,14 +1406,14 @@ nodes: - name: call_operator_loc type: location? comment: | - Represents the location of the call operator. + Represents the Location of the call operator. foo.bar &&= value ^ - name: message_loc type: location? comment: | - Represents the location of the message. + Represents the Location of the message. foo.bar &&= value ^^^ @@ -1434,7 +1434,7 @@ nodes: - name: operator_loc type: location comment: | - Represents the location of the operator. + Represents the Location of the operator. foo.bar &&= value ^^^ @@ -1471,7 +1471,7 @@ nodes: - name: call_operator_loc type: location? comment: | - Represents the location of the call operator. + Represents the Location of the call operator. foo.bar ^ @@ -1488,14 +1488,15 @@ nodes: - name: message_loc type: location? comment: | - Represents the location of the message. + Represents the Location of the message. foo.bar ^^^ - name: opening_loc type: location? comment: | - Represents the location of the left parenthesis. + Represents the Location of the left parenthesis. + foo(bar) ^ - name: arguments @@ -1509,14 +1510,14 @@ nodes: - name: closing_loc type: location? comment: | - Represents the location of the right parenthesis. + Represents the Location of the right parenthesis. foo(bar) ^ - name: equal_loc type: location? comment: | - Represents the location of the equal sign, in the case that this is an attribute write. + Represents the Location of the equal sign, in the case that this is an attribute write. foo.bar = value ^ @@ -1567,14 +1568,14 @@ nodes: - name: call_operator_loc type: location? comment: | - Represents the location of the call operator. + Represents the Location of the call operator. foo.bar += value ^ - name: message_loc type: location? comment: | - Represents the location of the message. + Represents the Location of the message. foo.bar += value ^^^ @@ -1602,7 +1603,7 @@ nodes: - name: binary_operator_loc type: location comment: | - Represents the location of the binary operator. + Represents the Location of the binary operator. foo.bar += value ^^ @@ -1633,14 +1634,14 @@ nodes: - name: call_operator_loc type: location? comment: | - Represents the location of the call operator. + Represents the Location of the call operator. foo.bar ||= value ^ - name: message_loc type: location? comment: | - Represents the location of the message. + Represents the Location of the message. foo.bar ||= value ^^^ @@ -1661,7 +1662,7 @@ nodes: - name: operator_loc type: location comment: | - Represents the location of the operator. + Represents the Location of the operator. foo.bar ||= value ^^^ @@ -1692,7 +1693,7 @@ nodes: - name: call_operator_loc type: location comment: | - Represents the location of the call operator. + Represents the Location of the call operator. foo.bar = 1 ^ @@ -1706,7 +1707,7 @@ nodes: - name: message_loc type: location comment: | - Represents the location of the message. + Represents the Location of the message. foo.bar = 1 ^^^ @@ -1744,7 +1745,7 @@ nodes: - name: operator_loc type: location comment: | - Represents the location of the `=>` operator. + Represents the Location of the `=>` operator. foo => bar ^^ @@ -1782,14 +1783,14 @@ nodes: - name: case_keyword_loc type: location comment: | - Represents the location of the `case` keyword. + Represents the Location of the `case` keyword. case true; in false; end ^^^^ - name: end_keyword_loc type: location comment: | - Represents the location of the `end` keyword. + Represents the Location of the `end` keyword. case true; in false; end ^^^ @@ -1829,14 +1830,14 @@ nodes: - name: case_keyword_loc type: location comment: | - Represents the location of the `case` keyword. + Represents the Location of the `case` keyword. case true; when false; end ^^^^ - name: end_keyword_loc type: location comment: | - Represents the location of the `end` keyword. + Represents the Location of the `end` keyword. case true; when false; end ^^^ @@ -1854,7 +1855,7 @@ nodes: - name: class_keyword_loc type: location comment: | - Represents the location of the `class` keyword. + Represents the Location of the `class` keyword. class Foo end ^^^^^ @@ -1867,7 +1868,7 @@ nodes: - name: inheritance_operator_loc type: location? comment: | - Represents the location of the `<` operator. + Represents the Location of the `<` operator. class Foo < Bar ^ @@ -1893,7 +1894,7 @@ nodes: - name: end_keyword_loc type: location comment: | - Represents the location of the `end` keyword. + Represents the Location of the `end` keyword. class Foo end ^^^ @@ -1920,14 +1921,14 @@ nodes: - name: name_loc type: location comment: | - Represents the location of the variable name. + Represents the Location of the variable name. @@target &&= value ^^^^^^^^ - name: operator_loc type: location comment: | - Represents the location of the `&&=` operator. + Represents the Location of the `&&=` operator. @@target &&= value ^^^ @@ -2015,7 +2016,7 @@ nodes: - name: name_loc type: location comment: | - The location of the variable name. + The Location of the variable name. @@foo = :bar ^^^^^ @@ -2033,7 +2034,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `=` operator. + The Location of the `=` operator. @@foo = :bar ^ @@ -2129,7 +2130,7 @@ nodes: - name: delimiter_loc type: location comment: | - The location of the `::` delimiter. + The Location of the `::` delimiter. ::Foo ^^ @@ -2139,7 +2140,7 @@ nodes: - name: name_loc type: location comment: | - The location of the name of the constant. + The Location of the name of the constant. ::Foo ^^^ @@ -2215,7 +2216,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `=` operator. + The Location of the `=` operator. ::ABC = 123 ^ @@ -2275,7 +2276,7 @@ nodes: - name: name_loc type: location comment: | - The location of the constant name. + The Location of the constant name. FOO = 1 ^^^ @@ -2293,7 +2294,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `=` operator. + The Location of the `=` operator. FOO = :bar ^ @@ -2474,7 +2475,7 @@ nodes: - name: opening_loc type: location? comment: | - The location of the opening brace. + The Location of the opening brace. foo in [*bar, baz, *qux] ^ @@ -2484,7 +2485,7 @@ nodes: - name: closing_loc type: location? comment: | - The location of the closing brace. + The Location of the closing brace. foo in [*bar, baz, *qux] ^ @@ -2574,28 +2575,28 @@ nodes: - name: for_keyword_loc type: location comment: | - The location of the `for` keyword. + The Location of the `for` keyword. for i in a end ^^^ - name: in_keyword_loc type: location comment: | - The location of the `in` keyword. + The Location of the `in` keyword. for i in a end ^^ - name: do_keyword_loc type: location? comment: | - The location of the `do` keyword, if present. + The Location of the `do` keyword, if present. for i in a do end ^^ - name: end_keyword_loc type: location comment: | - The location of the `end` keyword. + The Location of the `end` keyword. for i in a end ^^^ @@ -2723,7 +2724,7 @@ nodes: - name: name_loc type: location comment: | - The location of the global variable's name. + The Location of the global variable's name. $foo = :bar ^^^^ @@ -2741,7 +2742,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `=` operator. + The Location of the `=` operator. $foo = :bar ^ @@ -2755,7 +2756,7 @@ nodes: - name: opening_loc type: location comment: | - The location of the opening brace. + The Location of the opening brace. { a => b } ^ @@ -2775,7 +2776,7 @@ nodes: - name: closing_loc type: location comment: | - The location of the closing brace. + The Location of the closing brace. { a => b } ^ @@ -2826,7 +2827,7 @@ nodes: - name: opening_loc type: location? comment: | - The location of the opening brace. + The Location of the opening brace. foo => { a: 1 } ^ @@ -2836,7 +2837,7 @@ nodes: - name: closing_loc type: location? comment: | - The location of the closing brace. + The Location of the closing brace. foo => { a: 1 } ^ @@ -2862,7 +2863,7 @@ nodes: - name: if_keyword_loc type: location? comment: | - The location of the `if` keyword if present. + The Location of the `if` keyword if present. bar if foo ^^ @@ -2887,7 +2888,7 @@ nodes: - name: then_keyword_loc type: location? comment: | - The location of the `then` keyword (if present) or the `?` in a ternary expression, `nil` otherwise. + The Location of the `then` keyword (if present) or the `?` in a ternary expression, `nil` otherwise. if foo then bar end ^^^^ @@ -2928,7 +2929,7 @@ nodes: - name: end_keyword_loc type: location? comment: | - The location of the `end` keyword if present, `nil` otherwise. + The Location of the `end` keyword if present, `nil` otherwise. if foo bar @@ -3213,7 +3214,7 @@ nodes: - name: name_loc type: location comment: | - The location of the variable name. + The Location of the variable name. @_x = 1 ^^^ @@ -3231,7 +3232,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `=` operator. + The Location of the `=` operator. @x = y ^ @@ -3538,7 +3539,7 @@ nodes: - name: name_loc type: location comment: | - The location of the variable name. + The Location of the variable name. foo = :bar ^^^ @@ -3560,7 +3561,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `=` operator. + The Location of the `=` operator. x = :y ^ @@ -3660,7 +3661,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the operator. + The Location of the operator. foo => bar ^^ @@ -3781,14 +3782,14 @@ nodes: - name: lparen_loc type: location? comment: | - The location of the opening parenthesis. + The Location of the opening parenthesis. a, (b, c) = 1, 2, 3 ^ - name: rparen_loc type: location? comment: | - The location of the closing parenthesis. + The Location of the closing parenthesis. a, (b, c) = 1, 2, 3 ^ @@ -3870,21 +3871,21 @@ nodes: - name: lparen_loc type: location? comment: | - The location of the opening parenthesis. + The Location of the opening parenthesis. (a, b, c) = 1, 2, 3 ^ - name: rparen_loc type: location? comment: | - The location of the closing parenthesis. + The Location of the closing parenthesis. (a, b, c) = 1, 2, 3 ^ - name: operator_loc type: location comment: | - The location of the operator. + The Location of the operator. a, b, c = 1, 2, 3 ^ @@ -4018,7 +4019,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `or` keyword or the `||` operator. + The Location of the `or` keyword or the `||` operator. left or right ^^ @@ -4101,21 +4102,21 @@ nodes: - name: operator_loc type: location comment: | - The location of the `^` operator + The Location of the `^` operator foo in ^(bar) ^ - name: lparen_loc type: location comment: | - The location of the opening parenthesis. + The Location of the opening parenthesis. foo in ^(bar) ^ - name: rparen_loc type: location comment: | - The location of the closing parenthesis. + The Location of the closing parenthesis. foo in ^(bar) ^ @@ -4145,7 +4146,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `^` operator + The Location of the `^` operator foo in ^bar ^ @@ -4223,7 +4224,7 @@ nodes: - name: operator_loc type: location comment: | - The location of the `..` or `...` operator. + The Location of the `..` or `...` operator. comment: | Represents the use of the `..` or `...` operators. @@ -4449,7 +4450,7 @@ nodes: fields: - name: filepath type: string - comment: Represents the file path being parsed. This corresponds directly to the `filepath` option given to the various `Prism::parse*` APIs. + comment: Represents the file path being parsed. This corresponds directly to the `filepath` option given to the various `Prism.parse*` APIs. comment: | Represents the use of the `__FILE__` keyword. @@ -4576,7 +4577,7 @@ nodes: - name: keyword_loc type: location comment: | - The location of the `unless` keyword. + The Location of the `unless` keyword. unless cond then bar end ^^^^^^ @@ -4597,7 +4598,7 @@ nodes: - name: then_keyword_loc type: location? comment: | - The location of the `then` keyword, if present. + The Location of the `then` keyword, if present. unless cond then bar end ^^^^ @@ -4621,7 +4622,7 @@ nodes: - name: end_keyword_loc type: location? comment: | - The location of the `end` keyword, if present. + The Location of the `end` keyword, if present. unless cond then bar end ^^^ diff --git a/prism/extension.c b/prism/extension.c index fe3cd6a8f38cb1..c4395b1cbcca4d 100644 --- a/prism/extension.c +++ b/prism/extension.c @@ -390,10 +390,10 @@ dump_input(pm_string_t *input, const pm_options_t *options) { /** * call-seq: - * Prism::dump(source, **options) -> String + * dump(source, **options) -> String * * Dump the AST corresponding to the given string to a string. For supported - * options, see Prism::parse. + * options, see Prism.parse. */ static VALUE dump(int argc, VALUE *argv, VALUE self) { @@ -423,10 +423,10 @@ dump(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::dump_file(filepath, **options) -> String + * dump_file(filepath, **options) -> String * * Dump the AST corresponding to the given file to a string. For supported - * options, see Prism::parse. + * options, see Prism.parse. */ static VALUE dump_file(int argc, VALUE *argv, VALUE self) { @@ -795,10 +795,10 @@ parse_lex_input(pm_string_t *input, const pm_options_t *options, bool return_nod /** * call-seq: - * Prism::lex(source, **options) -> LexResult + * lex(source, **options) -> LexResult * * Return a LexResult instance that contains an array of Token instances - * corresponding to the given string. For supported options, see Prism::parse. + * corresponding to the given string. For supported options, see Prism.parse. */ static VALUE lex(int argc, VALUE *argv, VALUE self) { @@ -815,10 +815,10 @@ lex(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::lex_file(filepath, **options) -> LexResult + * lex_file(filepath, **options) -> LexResult * * Return a LexResult instance that contains an array of Token instances - * corresponding to the given file. For supported options, see Prism::parse. + * corresponding to the given file. For supported options, see Prism.parse. */ static VALUE lex_file(int argc, VALUE *argv, VALUE self) { @@ -866,7 +866,7 @@ parse_input(pm_string_t *input, const pm_options_t *options) { /** * call-seq: - * Prism::parse(source, **options) -> ParseResult + * parse(source, **options) -> ParseResult * * Parse the given string and return a ParseResult instance. The options that * are supported are: @@ -934,10 +934,10 @@ parse(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::parse_file(filepath, **options) -> ParseResult + * parse_file(filepath, **options) -> ParseResult * * Parse the given file and return a ParseResult instance. For supported - * options, see Prism::parse. + * options, see Prism.parse. */ static VALUE parse_file(int argc, VALUE *argv, VALUE self) { @@ -969,11 +969,11 @@ profile_input(pm_string_t *input, const pm_options_t *options) { /** * call-seq: - * Prism::profile(source, **options) -> nil + * profile(source, **options) -> nil * * Parse the given string and return nothing. This method is meant to allow * profilers to avoid the overhead of reifying the AST to Ruby. For supported - * options, see Prism::parse. + * options, see Prism.parse. */ static VALUE profile(int argc, VALUE *argv, VALUE self) { @@ -990,11 +990,11 @@ profile(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::profile_file(filepath, **options) -> nil + * profile_file(filepath, **options) -> nil * * Parse the given file and return nothing. This method is meant to allow * profilers to avoid the overhead of reifying the AST to Ruby. For supported - * options, see Prism::parse. + * options, see Prism.parse. */ static VALUE profile_file(int argc, VALUE *argv, VALUE self) { @@ -1042,10 +1042,10 @@ parse_stream_fgets(char *string, int size, void *stream) { /** * call-seq: - * Prism::parse_stream(stream, **options) -> ParseResult + * parse_stream(stream, **options) -> ParseResult * * Parse the given object that responds to `gets` and return a ParseResult - * instance. The options that are supported are the same as Prism::parse. + * instance. The options that are supported are the same as Prism.parse. */ static VALUE parse_stream(int argc, VALUE *argv, VALUE self) { @@ -1095,10 +1095,10 @@ parse_input_comments(pm_string_t *input, const pm_options_t *options) { /** * call-seq: - * Prism::parse_comments(source, **options) -> Array + * parse_comments(source, **options) -> Array * * Parse the given string and return an array of Comment objects. For supported - * options, see Prism::parse. + * options, see Prism.parse. */ static VALUE parse_comments(int argc, VALUE *argv, VALUE self) { @@ -1115,10 +1115,10 @@ parse_comments(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::parse_file_comments(filepath, **options) -> Array + * parse_file_comments(filepath, **options) -> Array * * Parse the given file and return an array of Comment objects. For supported - * options, see Prism::parse. + * options, see Prism.parse. */ static VALUE parse_file_comments(int argc, VALUE *argv, VALUE self) { @@ -1137,17 +1137,17 @@ parse_file_comments(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::parse_lex(source, **options) -> ParseLexResult + * parse_lex(source, **options) -> ParseLexResult * * Parse the given string and return a ParseLexResult instance that contains a * 2-element array, where the first element is the AST and the second element is * an array of Token instances. * * This API is only meant to be used in the case where you need both the AST and - * the tokens. If you only need one or the other, use either Prism::parse or - * Prism::lex. + * the tokens. If you only need one or the other, use either Prism.parse or + * Prism.lex. * - * For supported options, see Prism::parse. + * For supported options, see Prism.parse. */ static VALUE parse_lex(int argc, VALUE *argv, VALUE self) { @@ -1164,17 +1164,17 @@ parse_lex(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::parse_lex_file(filepath, **options) -> ParseLexResult + * parse_lex_file(filepath, **options) -> ParseLexResult * * Parse the given file and return a ParseLexResult instance that contains a * 2-element array, where the first element is the AST and the second element is * an array of Token instances. * * This API is only meant to be used in the case where you need both the AST and - * the tokens. If you only need one or the other, use either Prism::parse_file - * or Prism::lex_file. + * the tokens. If you only need one or the other, use either Prism.parse_file + * or Prism.lex_file. * - * For supported options, see Prism::parse. + * For supported options, see Prism.parse. */ static VALUE parse_lex_file(int argc, VALUE *argv, VALUE self) { @@ -1210,10 +1210,10 @@ parse_input_success_p(pm_string_t *input, const pm_options_t *options) { /** * call-seq: - * Prism::parse_success?(source, **options) -> bool + * parse_success?(source, **options) -> bool * * Parse the given string and return true if it parses without errors. For - * supported options, see Prism::parse. + * supported options, see Prism.parse. */ static VALUE parse_success_p(int argc, VALUE *argv, VALUE self) { @@ -1230,10 +1230,10 @@ parse_success_p(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::parse_failure?(source, **options) -> bool + * parse_failure?(source, **options) -> bool * * Parse the given string and return true if it parses with errors. For - * supported options, see Prism::parse. + * supported options, see Prism.parse. */ static VALUE parse_failure_p(int argc, VALUE *argv, VALUE self) { @@ -1242,10 +1242,10 @@ parse_failure_p(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::parse_file_success?(filepath, **options) -> bool + * parse_file_success?(filepath, **options) -> bool * * Parse the given file and return true if it parses without errors. For - * supported options, see Prism::parse. + * supported options, see Prism.parse. */ static VALUE parse_file_success_p(int argc, VALUE *argv, VALUE self) { @@ -1264,10 +1264,10 @@ parse_file_success_p(int argc, VALUE *argv, VALUE self) { /** * call-seq: - * Prism::parse_file_failure?(filepath, **options) -> bool + * parse_file_failure?(filepath, **options) -> bool * * Parse the given file and return true if it parses with errors. For - * supported options, see Prism::parse. + * supported options, see Prism.parse. */ static VALUE parse_file_failure_p(int argc, VALUE *argv, VALUE self) { @@ -1298,7 +1298,7 @@ string_query(pm_string_query_t result) { /** * call-seq: - * Prism::StringQuery::local?(string) -> bool + * local?(string) -> bool * * Returns true if the string constitutes a valid local variable name. Note that * this means the names that can be set through Binding#local_variable_set, not @@ -1312,7 +1312,7 @@ string_query_local_p(VALUE self, VALUE string) { /** * call-seq: - * Prism::StringQuery::constant?(string) -> bool + * constant?(string) -> bool * * Returns true if the string constitutes a valid constant name. Note that this * means the names that can be set through Module#const_set, not necessarily the @@ -1326,7 +1326,7 @@ string_query_constant_p(VALUE self, VALUE string) { /** * call-seq: - * Prism::StringQuery::method_name?(string) -> bool + * method_name?(string) -> bool * * Returns true if the string constitutes a valid method name. */ diff --git a/prism/templates/lib/prism/dispatcher.rb.erb b/prism/templates/lib/prism/dispatcher.rb.erb index 16ce421cc5d093..e4ca84db2421d2 100644 --- a/prism/templates/lib/prism/dispatcher.rb.erb +++ b/prism/templates/lib/prism/dispatcher.rb.erb @@ -41,16 +41,12 @@ module Prism end # Register a listener for one or more events. - # - # def register: (Listener, *Symbol) -> void def register(listener, *events) register_events(listener, events) end # Register all public methods of a listener that match the pattern # `on__(enter|leave)`. - # - # def register_public_methods: (Listener) -> void def register_public_methods(listener) register_events(listener, listener.public_methods(false).grep(/\Aon_.+_(?:enter|leave)\z/)) end @@ -61,13 +57,9 @@ module Prism end # Walks `root` dispatching events to all registered listeners. - # - # def dispatch: (Node) -> void alias dispatch visit # Dispatches a single event for `node` to all registered listeners. - # - # def dispatch_once: (Node) -> void def dispatch_once(node) node.accept(DispatchOnce.new(listeners)) end From 7b3370a5579956404d742a2e104d72e7c89480e4 Mon Sep 17 00:00:00 2001 From: Luke Gruber Date: Fri, 6 Feb 2026 14:26:07 -0500 Subject: [PATCH 02/10] Wake timer to create new SNT when needed for dedicated task (#16009) When removing a thread from `running_threads`, if we're on a shared native thread and we're running a dedicated task, we need to wake the timer thread so it can create a new SNT if necessary. We only do this if it's waiting forever without the 10ms quantum timeout for now, because max 10ms of wait is considered "good enough". In the future, perhaps we can force the timer thread to wake if this becomes an issue (`timer_thread_wakeup_force`). Fixes [Bug #21504] --- test/ruby/test_ractor.rb | 39 +++++++++++++++++++++++++++++++++++++++ thread_pthread.c | 37 +++++++++++++++++++++++++++++++------ thread_pthread_mn.c | 17 +++-------------- 3 files changed, 73 insertions(+), 20 deletions(-) diff --git a/test/ruby/test_ractor.rb b/test/ruby/test_ractor.rb index 6ae511217aca09..d449f9f8143c06 100644 --- a/test/ruby/test_ractor.rb +++ b/test/ruby/test_ractor.rb @@ -201,6 +201,45 @@ def test_max_cpu_1 RUBY end + def test_timer_thread_create_snt_for_dedicated_task + omit "timer thread works differently" if windows? + omit "test relies on this as a best-effort safety mechanism" unless defined?(Process::WNOHANG) + assert_separately([{ "RUBY_MAX_CPU" => "2" }], <<~'RUBY', timeout: 30) + $VERBOSE = nil + CHILD_PID = 0 + + rs = [] + 2.times do |i| + rs << Ractor.new(i) do |j| + if j == 0 + pid = spawn("sleep 60", close_others: true) + Object.const_set(:CHILD_PID, pid) + Process.waitpid(pid) # block forever (dedicated task) + else + while CHILD_PID == 0 + sleep 1 # make sure first ractor blocks forever first (this is what we're testing) + end + 1_000.times do + [nil] * 100 + end + end + end + end + + rs.last.join + begin + result = Process.waitpid(CHILD_PID, Process::WNOHANG) + rescue Errno::ECHILD, Errno::ESRCH + # If it's somehow not a child (not running?), don't send it a signal + else + if result.nil? + Process.kill('KILL', CHILD_PID) rescue nil + end + end + rs.first.join # reap + RUBY + end + def test_symbol_proc_is_shareable pr = :symbol.to_proc assert_make_shareable(pr) diff --git a/thread_pthread.c b/thread_pthread.c index 5b461efec877d6..f455ac828ea937 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -90,6 +90,11 @@ static const void *const condattr_monotonic = NULL; #endif #endif +#ifndef MINIMUM_SNT +// make at least MINIMUM_SNT snts for debug. +#define MINIMUM_SNT 0 +#endif + #ifdef HAVE_SCHED_YIELD #define native_thread_yield() (void)sched_yield() #else @@ -554,6 +559,20 @@ ractor_sched_timeslice_threads_contain_p(rb_vm_t *vm, rb_thread_t *th) static void ractor_sched_barrier_join_signal_locked(rb_vm_t *vm); +static bool +need_more_shared_native_threads_p(rb_vm_t *vm) +{ + ASSERT_ractor_sched_locked(vm, NULL); + + unsigned int schedulable_ractor_cnt = vm->ractor.cnt; + unsigned int snt_cnt = vm->ractor.sched.snt_cnt; + RUBY_ASSERT(schedulable_ractor_cnt >= 1); + if (!vm->ractor.main_ractor->threads.sched.enable_mn_threads) { + schedulable_ractor_cnt--; // do not need snt for main ractor + } + return snt_cnt < MINIMUM_SNT || (snt_cnt < schedulable_ractor_cnt && snt_cnt < vm->ractor.sched.max_cpu); +} + // setup timeslice signals by the timer thread. static void thread_sched_setup_running_threads(struct rb_thread_sched *sched, rb_ractor_t *cr, rb_vm_t *vm, @@ -564,6 +583,7 @@ thread_sched_setup_running_threads(struct rb_thread_sched *sched, rb_ractor_t *c #endif rb_thread_t *del_timeslice_th; + bool wakeup_timer_thread = false; if (del_th && sched->is_running_timeslice) { del_timeslice_th = del_th; @@ -592,6 +612,12 @@ thread_sched_setup_running_threads(struct rb_thread_sched *sched, rb_ractor_t *c ractor_sched_barrier_join_signal_locked(vm); } sched->is_running = false; + + // If we need more SNTs, the timer thread should be awake and monitoring the situation so it can correct it. + if (!del_th->has_dedicated_nt && del_th->nt->dedicated > 0 && (sched->running != NULL || vm->ractor.sched.grq_cnt > 0) && + need_more_shared_native_threads_p(vm)) { + wakeup_timer_thread = true; + } } if (add_th) { @@ -616,7 +642,7 @@ thread_sched_setup_running_threads(struct rb_thread_sched *sched, rb_ractor_t *c ccan_list_add(&vm->ractor.sched.timeslice_threads, &add_timeslice_th->sched.node.timeslice_threads); sched->is_running_timeslice = true; if (was_empty) { - timer_thread_wakeup_locked(vm); + wakeup_timer_thread = true; } } @@ -625,6 +651,10 @@ thread_sched_setup_running_threads(struct rb_thread_sched *sched, rb_ractor_t *c ccan_list_del_init(&del_timeslice_th->sched.node.timeslice_threads); } + if (wakeup_timer_thread) { + timer_thread_wakeup_locked(vm); + } + VM_ASSERT(ractor_sched_running_threads_size(vm) == vm->ractor.sched.running_cnt); VM_ASSERT(ractor_sched_timeslice_threads_size(vm) <= vm->ractor.sched.running_cnt); } @@ -1264,11 +1294,6 @@ ractor_sched_enq(rb_vm_t *vm, rb_ractor_t *r) #define SNT_KEEP_SECONDS 0 #endif -#ifndef MINIMUM_SNT -// make at least MINIMUM_SNT snts for debug. -#define MINIMUM_SNT 0 -#endif - static rb_ractor_t * ractor_sched_deq(rb_vm_t *vm, rb_ractor_t *cr) { diff --git a/thread_pthread_mn.c b/thread_pthread_mn.c index 69e81e5fbcf00f..d6602cea77d25a 100644 --- a/thread_pthread_mn.c +++ b/thread_pthread_mn.c @@ -394,25 +394,14 @@ nt_free_stack(void *mstack) rb_native_mutex_unlock(&nt_machine_stack_lock); } - static int native_thread_check_and_create_shared(rb_vm_t *vm) { bool need_to_make = false; - rb_native_mutex_lock(&vm->ractor.sched.lock); + ractor_sched_lock(vm, NULL); { - unsigned int schedulable_ractor_cnt = vm->ractor.cnt; - RUBY_ASSERT(schedulable_ractor_cnt >= 1); - - if (!vm->ractor.main_ractor->threads.sched.enable_mn_threads) - schedulable_ractor_cnt--; // do not need snt for main ractor - - unsigned int snt_cnt = vm->ractor.sched.snt_cnt; - if (((int)snt_cnt < MINIMUM_SNT) || - (snt_cnt < schedulable_ractor_cnt && - snt_cnt < vm->ractor.sched.max_cpu)) { - + if (need_more_shared_native_threads_p(vm)) { RUBY_DEBUG_LOG("added snt:%u dnt:%u ractor_cnt:%u grq_cnt:%u", vm->ractor.sched.snt_cnt, vm->ractor.sched.dnt_cnt, @@ -426,7 +415,7 @@ native_thread_check_and_create_shared(rb_vm_t *vm) RUBY_DEBUG_LOG("snt:%d ractor_cnt:%d", (int)vm->ractor.sched.snt_cnt, (int)vm->ractor.cnt); } } - rb_native_mutex_unlock(&vm->ractor.sched.lock); + ractor_sched_unlock(vm, NULL); if (need_to_make) { struct rb_native_thread *nt = native_thread_alloc(); From 954094a910c2dcf459caeb61e20143df0864f914 Mon Sep 17 00:00:00 2001 From: Luke Gruber Date: Fri, 6 Feb 2026 16:08:57 -0500 Subject: [PATCH 03/10] Take VM Lock during rb_gc_{un}register_address (#16097) The `Rice` C++ library uses an Anchor class that uses RAII to call `rb_gc_register_address`, `rb_gc_unregister_address` during init+destruct. It's unclear if this API is meant to be used at runtime like this, but we can at least lock the VM so it works safely across Ractors and doesn't mangle the `global_object_list` table. --- gc.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/gc.c b/gc.c index 53a65d6acb8aab..4e1bb39e21f0b9 100644 --- a/gc.c +++ b/gc.c @@ -3633,9 +3633,11 @@ rb_gc_register_address(VALUE *addr) VALUE obj = *addr; struct global_object_list *tmp = ALLOC(struct global_object_list); - tmp->next = vm->global_object_list; - tmp->varptr = addr; - vm->global_object_list = tmp; + RB_VM_LOCKING() { + tmp->next = vm->global_object_list; + tmp->varptr = addr; + vm->global_object_list = tmp; + } /* * Because some C extensions have assignment-then-register bugs, @@ -3653,22 +3655,25 @@ void rb_gc_unregister_address(VALUE *addr) { rb_vm_t *vm = GET_VM(); - struct global_object_list *tmp = vm->global_object_list; - - if (tmp->varptr == addr) { - vm->global_object_list = tmp->next; - SIZED_FREE(tmp); - return; - } - while (tmp->next) { - if (tmp->next->varptr == addr) { - struct global_object_list *t = tmp->next; + struct global_object_list *tmp; + RB_VM_LOCKING() { + tmp = vm->global_object_list; + if (tmp->varptr == addr) { + vm->global_object_list = tmp->next; + SIZED_FREE(tmp); + } + else { + while (tmp->next) { + if (tmp->next->varptr == addr) { + struct global_object_list *t = tmp->next; - tmp->next = tmp->next->next; - SIZED_FREE(t); - break; + tmp->next = tmp->next->next; + SIZED_FREE(t); + break; + } + tmp = tmp->next; + } } - tmp = tmp->next; } } From d79ce7e4e98f3f37e8afe106e739b71601b1a3e8 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Fri, 6 Feb 2026 18:14:56 +0000 Subject: [PATCH 04/10] [ruby/error_highlight] [DOC] Fix link in ErrorHighlight https://github.com/ruby/error_highlight/commit/6096a05b2f --- lib/error_highlight/base.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/error_highlight/base.rb b/lib/error_highlight/base.rb index bc4a62c9d63508..5fffe5ec34e360 100644 --- a/lib/error_highlight/base.rb +++ b/lib/error_highlight/base.rb @@ -28,7 +28,7 @@ module ErrorHighlight # Currently, ErrorHighlight.spot only supports a single-line code fragment. # Therefore, if the return value is not nil, first_lineno and last_lineno will have # the same value. If the relevant code fragment spans multiple lines - # (e.g., Array#[] of +ary[(newline)expr(newline)]+), the method will return nil. + # (e.g., Array#[] of ary[(newline)expr(newline)]), the method will return nil. # This restriction may be removed in the future. def self.spot(obj, **opts) case obj From 900182e2656bf5a74f26e36c1be1108c6ba0f53d Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Fri, 6 Feb 2026 17:33:35 -0600 Subject: [PATCH 05/10] [ruby/strscan] [DOC] Fix links (https://github.com/ruby/strscan/pull/190) https://github.com/ruby/strscan/commit/f6033e5253 --- doc/strscan/link_refs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/strscan/link_refs.txt b/doc/strscan/link_refs.txt index 19f6f7ce5c9533..04c441998285bd 100644 --- a/doc/strscan/link_refs.txt +++ b/doc/strscan/link_refs.txt @@ -1,5 +1,5 @@ [1]: rdoc-ref:StringScanner@Stored+String -[2]: rdoc-ref:StringScanner@Byte+Position+-28Position-29 +[2]: rdoc-ref:StringScanner@Byte+Position+Position [3]: rdoc-ref:StringScanner@Target+Substring [4]: rdoc-ref:StringScanner@Setting+the+Target+Substring [5]: rdoc-ref:StringScanner@Traversing+the+Target+Substring From 474dd925832995e959cd87ccdbc1445679162772 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Fri, 6 Feb 2026 19:01:45 +0000 Subject: [PATCH 06/10] [ruby/net-http] [DOC] Fix links in module Net https://github.com/ruby/net-http/commit/e95d812325 --- lib/net/http.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/net/http.rb b/lib/net/http.rb index 98639978a2fbf6..53295fe90cfccc 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -37,7 +37,7 @@ class HTTPHeaderSyntaxError < StandardError; end # For information about \HTTP, see: # # - {Hypertext Transfer Protocol}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol]. - # - {Technical overview}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Technical_overview]. + # - {Technology}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Technology]. # # == About the Examples # @@ -72,7 +72,7 @@ class HTTPHeaderSyntaxError < StandardError; end # # - If performance is important, consider using sessions, which lower request overhead. # This {session}[rdoc-ref:Net::HTTP@Sessions] has multiple requests for - # {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods] + # {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Method] # and {WebDAV methods}[https://en.wikipedia.org/wiki/WebDAV#Implementation]: # # Net::HTTP.start(hostname) do |http| @@ -198,7 +198,7 @@ class HTTPHeaderSyntaxError < StandardError; end # In the block, you can use these instance methods, # each of which that sends a single request: # - # - {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods]: + # - {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Method]: # # - #get, #request_get: GET. # - #head, #request_head: HEAD. @@ -447,7 +447,7 @@ class HTTPHeaderSyntaxError < StandardError; end # if the response has header 'Content-Range'. # # Otherwise decompression (or not) depends on the value of header - # {Content-Encoding}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-encoding-response-header]: + # {Content-Encoding}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Content-Encoding_2]: # # - 'deflate', 'gzip', or 'x-gzip': # decompresses the body and deletes the header. From f8eed5846926508451fe274dff09137769fa2a35 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Fri, 6 Feb 2026 19:39:38 +0000 Subject: [PATCH 07/10] [DOC] Fix links in String --- doc/string/bytes.rdoc | 2 +- doc/string/chars.rdoc | 2 +- doc/string/codepoints.rdoc | 2 +- doc/string/getbyte.rdoc | 2 +- doc/string/grapheme_clusters.rdoc | 2 +- doc/string/inspect.rdoc | 2 +- doc/string/intern.rdoc | 2 +- doc/string/ord.rdoc | 2 +- doc/string/partition.rdoc | 2 +- doc/string/rpartition.rdoc | 2 +- doc/string/scan.rdoc | 2 +- doc/string/split.rdoc | 2 +- string.c | 10 +++++----- 13 files changed, 17 insertions(+), 17 deletions(-) diff --git a/doc/string/bytes.rdoc b/doc/string/bytes.rdoc index 6dde0a745d9b84..16fa8e0bb077da 100644 --- a/doc/string/bytes.rdoc +++ b/doc/string/bytes.rdoc @@ -4,4 +4,4 @@ Returns an array of the bytes in +self+: 'こんにちは'.bytes # => [227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175] -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/chars.rdoc b/doc/string/chars.rdoc index d4d15bf2ad541d..47fb01b43a66fc 100644 --- a/doc/string/chars.rdoc +++ b/doc/string/chars.rdoc @@ -4,4 +4,4 @@ Returns an array of the characters in +self+: 'こんにちは'.chars # => ["こ", "ん", "に", "ち", "は"] ''.chars # => [] -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/codepoints.rdoc b/doc/string/codepoints.rdoc index 22cb22c8890df1..0ad866389e075f 100644 --- a/doc/string/codepoints.rdoc +++ b/doc/string/codepoints.rdoc @@ -5,4 +5,4 @@ each codepoint is the integer value for a character: 'こんにちは'.codepoints # => [12371, 12435, 12395, 12385, 12399] ''.codepoints # => [] -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/getbyte.rdoc b/doc/string/getbyte.rdoc index 1d0ed2a5a488ad..974e21c473f96e 100644 --- a/doc/string/getbyte.rdoc +++ b/doc/string/getbyte.rdoc @@ -20,4 +20,4 @@ More examples: s.bytes # => [227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175] s.getbyte(2) # => 147 -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/grapheme_clusters.rdoc b/doc/string/grapheme_clusters.rdoc index 07ea1e318b5573..ee8b45700e46e7 100644 --- a/doc/string/grapheme_clusters.rdoc +++ b/doc/string/grapheme_clusters.rdoc @@ -16,4 +16,4 @@ Details: s.chars # => ["a", "̈"] # Two characters. s.chars.map {|char| char.ord } # => [97, 776] # Their values. -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/inspect.rdoc b/doc/string/inspect.rdoc index 907828c2afc22c..398a5a74c54956 100644 --- a/doc/string/inspect.rdoc +++ b/doc/string/inspect.rdoc @@ -35,4 +35,4 @@ A few, however, have special renderings: 13.chr.inspect # => "\"\\r\"" # CR 27.chr.inspect # => "\"\\e\"" # ESC -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/intern.rdoc b/doc/string/intern.rdoc index eded6ac3d727c9..c82302b906ec5e 100644 --- a/doc/string/intern.rdoc +++ b/doc/string/intern.rdoc @@ -4,5 +4,5 @@ creating it if it did not already exist: 'foo'.intern # => :foo 'こんにちは'.intern # => :こんにちは -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/ord.rdoc b/doc/string/ord.rdoc index 87b469db0205ce..8c460d3ba4a84c 100644 --- a/doc/string/ord.rdoc +++ b/doc/string/ord.rdoc @@ -4,4 +4,4 @@ Returns the integer ordinal of the first character of +self+: 'hello'.ord # => 104 'こんにちは'.ord # => 12371 -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/partition.rdoc b/doc/string/partition.rdoc index 614ad029d49885..b2e620a9fc24e4 100644 --- a/doc/string/partition.rdoc +++ b/doc/string/partition.rdoc @@ -40,4 +40,4 @@ then performs the equivalent of self.index(pattern) 'hello'.partition('x') # => ["hello", "", ""] 'こんにちは'.partition('に') # => ["こん", "に", "ちは"] -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/rpartition.rdoc b/doc/string/rpartition.rdoc index eed03949a56e52..add95b1f40d921 100644 --- a/doc/string/rpartition.rdoc +++ b/doc/string/rpartition.rdoc @@ -44,4 +44,4 @@ then searches for the last matching substring 'hello'.rpartition('') # => ["hello", "", ""] 'こんにちは'.rpartition('に') # => ["こん", "に", "ちは"] -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/scan.rdoc b/doc/string/scan.rdoc index 04a2b02ff4ec1b..d39b5b6dfa7fb3 100644 --- a/doc/string/scan.rdoc +++ b/doc/string/scan.rdoc @@ -32,4 +32,4 @@ With a block given, calls the block with each result; returns +self+: # => ["w", "o"] # => ["r", "l"] -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/doc/string/split.rdoc b/doc/string/split.rdoc index 1aee1de0a4cca7..8679149003fdd2 100644 --- a/doc/string/split.rdoc +++ b/doc/string/split.rdoc @@ -98,4 +98,4 @@ But the latter: - Has poorer performance because it creates an intermediate array. - Returns an array (instead of +self+). -Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. +Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. diff --git a/string.c b/string.c index c99362b74d8d52..417e9893cef882 100644 --- a/string.c +++ b/string.c @@ -7060,7 +7060,7 @@ rb_str_include(VALUE str, VALUE arg) * 'abcdef'.to_i # => 0 * '2'.to_i(2) # => 0 * - * Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. + * Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. */ static VALUE @@ -7092,7 +7092,7 @@ rb_str_to_i(int argc, VALUE *argv, VALUE str) * * 'abcdef'.to_f # => 0.0 * - * See {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. + * See {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. */ static VALUE @@ -9619,7 +9619,7 @@ rb_str_each_line(int argc, VALUE *argv, VALUE str) * "This is line four.", * "This is line five."] * - * Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. + * Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. */ static VALUE @@ -10762,7 +10762,7 @@ rb_str_scan(VALUE str, VALUE pat) * '0o777'.hex # => 0 * '0d999'.hex # => 55705 * - * Related: See {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. + * Related: See {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. */ static VALUE @@ -10848,7 +10848,7 @@ rb_str_hex(VALUE str) * 'foo'.oct # => 0 * ''.oct # => 0 * - * Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString]. + * Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non-String]. */ static VALUE From aff0581e4f122bf0a650b882eff4d7d082f21bc7 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Fri, 6 Feb 2026 21:07:59 +0000 Subject: [PATCH 08/10] [DOC] Fix link in Time --- time.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/time.c b/time.c index b2eed2daf3b85c..acc20d2c9757b4 100644 --- a/time.c +++ b/time.c @@ -3821,8 +3821,7 @@ time_to_i(VALUE time) * {Epoch seconds}[rdoc-ref:Time@Epoch+Seconds]; * subseconds are included. * - * The stored value of +self+ is a - * {Rational}[rdoc-ref:Rational@#method-i-to_f], + * The stored value of +self+ is a Rational, * which means that the returned value may be approximate: * * Time.utc(1970, 1, 1, 0, 0, 0).to_f # => 0.0 From a81e558837208a474ab941b12e697e0e9743e7eb Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Fri, 6 Feb 2026 19:55:01 +0000 Subject: [PATCH 09/10] [ruby/stringio] [DOC] Fix links in StringIO https://github.com/ruby/stringio/commit/d4b27b8681 --- doc/stringio/stringio.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index 8931d1c30c7d79..ce7872f98af401 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -690,11 +690,11 @@ Reading: [basic reading]: rdoc-ref:StringIO@Basic+Reading [basic writing]: rdoc-ref:StringIO@Basic+Writing -[bom (byte order mark)]: rdoc-ref:StringIO@BOM+-28Byte+Order+Mark-29 +[bom (byte order mark)]: rdoc-ref:StringIO@BOM+Byte+Order+Mark [data mode]: rdoc-ref:StringIO@Data+Mode [encodings]: rdoc-ref:StringIO@Encodings [end-of-stream]: rdoc-ref:StringIO@End-of-Stream [line number]: rdoc-ref:StringIO@Line+Number -[open/closed streams]: rdoc-ref:StringIO@Open-2FClosed+Streams +[open/closed streams]: rdoc-ref:StringIO@OpenClosed+Streams [position]: rdoc-ref:StringIO@Position -[read/write mode]: rdoc-ref:StringIO@Read-2FWrite+Mode +[read/write mode]: rdoc-ref:StringIO@ReadWrite+Mode From ff55280320efd350432e2862cc52e4d84f893936 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Thu, 5 Feb 2026 18:31:18 -0500 Subject: [PATCH 10/10] Remove useless reserved field in vm_throw_data --- internal/imemo.h | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/imemo.h b/internal/imemo.h index 6534cec5d7ca9f..f94f0111fcb951 100644 --- a/internal/imemo.h +++ b/internal/imemo.h @@ -57,7 +57,6 @@ struct vm_svar { /*! THROW_DATA */ struct vm_throw_data { VALUE flags; - VALUE reserved; const VALUE throw_obj; const struct rb_control_frame_struct *catch_frame; int throw_state;