Feature #21190
closedProposal for the Deconstruct Method in the MatchData Class
Description
Context:¶
The MatchData class currently lacks the deconstruct method, which is necessary for extracting values from a string using pattern matching in Ruby.
Current Extraction Method¶
Currently, extraction can be done as follows:
result = /(\d{2})(\d{2})(\d{9})/.match("5586987654321")
puts result[1] # => "55"
puts result[2] # => "86"
puts result[3] # => "987654321"
Proposed Solution:¶
Implement the deconstruct method in the MatchData class to allow conversion of the MatchData object into an array, enabling deconstruction of its components.
class MatchData
def deconstruct
self.to_a
end
end
result = /(\d{2})(\d{2})(\d{9})/.match("5586987654321")
result in [_ , country_code, area_code, number]
puts country_code # => "55"
puts area_code # => "86"
puts number # => "987654321"
Updated by jeremyevans0 (Jeremy Evans) 8 days ago
You can implement this more easily using named captures:
/(?<country_code>\d{2})(?<area_code>\d{2})(?<number>\d{9})/ =~ "5586987654321"
country_code # => "55"
area_code # => "86"
number # => "987654321"
I think proper use of named captures should handle most cases where you would want to use the proposed MatchData#deconstruct
. The remaining cases would be when you are passing MatchData as an argument to or result of a method call.
If we did want to implement this, it's questionable to me whether MatchData#deconstruct
should operate like MatchData#to_a
or MatchData#captures
(your example implies captures
would be a more useful behavior for that use case).
Updated by nobu (Nobuyoshi Nakada) 8 days ago
- Is duplicate of Feature #18821: Expose Pattern Matching interfaces in core classes added
Updated by nobu (Nobuyoshi Nakada) 8 days ago
- Status changed from Open to Closed
Updated by nobu (Nobuyoshi Nakada) 8 days ago
Match#destruct
and Match#destruct_keys
have been defined since ruby 3.2.
Match#destruct
is an alias of Match#captures
like @jeremyevans0 (Jeremy Evans) wrote, so your regexp match does not match 4-element pattern.
result = /(\d{2})(\d{2})(\d{9})/.match("5586987654321")
p result.deconstruct #=> ["55", "86", "987654321"]
p (result in [_, country_code, area_code, number]) #=> false
p (result in [country_code, area_code, number]) #=> true
p [country_code, area_code, number] #=> ["55", "86", "987654321"]