From 4bb3a6355513b0a74e416bc48ec63173847d2175 Mon Sep 17 00:00:00 2001 From: Vinicius Stock Date: Mon, 5 Jan 2026 15:25:33 -0300 Subject: [PATCH] Define `Heading` conditionally as a struct Rubies older than v4.0.0 have their documentation data serialized using a struct, so if we change it to a class it fails. To maintain compatibility, we define `Heading` conditionally as a struct on older rubies. Co-authored-by: Stan Lo --- lib/rdoc/markup/heading.rb | 49 ++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/lib/rdoc/markup/heading.rb b/lib/rdoc/markup/heading.rb index e07b00bcc0..36f3603de4 100644 --- a/lib/rdoc/markup/heading.rb +++ b/lib/rdoc/markup/heading.rb @@ -2,6 +2,33 @@ module RDoc class Markup + # IMPORTANT! This weird workaround is required to ensure that RDoc can correctly deserializing Marshal data from + # older rubies. Older rubies have `Heading` as a struct, so if we change it to a class, deserialization fails + if RUBY_VERSION.start_with?("4.") + class Heading < Element + #: String + attr_reader :text + + #: Integer + attr_accessor :level + + #: (Integer, String) -> void + def initialize(level, text) + super() + + @level = level + @text = text + end + + #: (Object) -> bool + def ==(other) + other.is_a?(Heading) && other.level == @level && other.text == @text + end + end + else + Heading = Struct.new(:level, :text) + end + # A heading with a level (1-6) and text # # RDoc syntax: @@ -13,13 +40,8 @@ class Markup # # Heading 1 # ## Heading 2 # ### Heading 3 - class Heading < Element - #: String - attr_reader :text - - #: Integer - attr_accessor :level - + # + class Heading # A singleton RDoc::Markup::ToLabel formatter for headings. #: () -> RDoc::Markup::ToLabel def self.to_label @@ -43,19 +65,6 @@ def to_html.handle_regexp_CROSSREF(target) end end - #: (Integer, String) -> void - def initialize(level, text) - super() - - @level = level - @text = text - end - - #: (Object) -> bool - def ==(other) - other.is_a?(Heading) && other.level == @level && other.text == @text - end - # @override #: (untyped) -> void def accept(visitor)