From e3ce8f5dac3b6e70671d43dd3874d2646c249d32 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Sun, 29 Jun 2025 11:54:34 -0700 Subject: [PATCH] Work correctly on Ruby 4.0 On Ruby 4.0, method.source_location returns an array with 5 entries instead of 2. Additional entries are start column, end line, and end column. Don't assume start_line is the last entry in the array, always use offset 1. If the end line is available, use it instead of splitting the method source and trying to determine the number of lines in it. Do not require method_source on Ruby 4.0+, since it will not be used. --- lib/m/test_method.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/m/test_method.rb b/lib/m/test_method.rb index 0601072..25fcfd8 100644 --- a/lib/m/test_method.rb +++ b/lib/m/test_method.rb @@ -1,4 +1,4 @@ -require "method_source" +require "method_source" if RUBY_VERSION < "4" module M ### Simple data structure for what a test method contains. @@ -15,17 +15,17 @@ def self.create suite_class, test_method # look up the ruby Method instance for it method = suite_class.instance_method test_method - # Ruby can find the starting line for us, so pull that out of the array - start_line = method.source_location.last + # Ruby can find the starting line for us, so pull that out of the array. + # Ruby 4.0+ can also provide the ending line. + start_line, end_line = method.source_location.values_at(1, 3) - # Ruby can't find the end line however, and I'm too lazy to write + # Ruby < 4.0 can't find the end line however, and I'm too lazy to write # a parser. Instead, `method_source` adds `Method#source` so we can # deduce this ourselves. # # The end line should be the number of line breaks in the method source, # added to the starting line and subtracted by one. - - end_line = method.source.split("\n").size + start_line - 1 + end_line ||= method.source.split("\n").size + start_line - 1 # Shove the given attributes into a new databag new test_method, start_line, end_line