Project

General

Profile

Actions

Feature #20953

open

Array#fetch_values vs #values_at protocols

Added by zverok (Victor Shepelev) 3 days ago. Updated about 9 hours ago.

Status:
Open
Target version:
-
[ruby-core:120250]

Description

I believe that the user might expect #fetch_values to be a stricter version of #values_at, confirming to the same protocol for arguments.

But the current implementation for #fetch_values is simpler:

[1, 2, 3, 4, 5].values_at(0, 3..4)    #=> [1, 4, 5]
[1, 2, 3, 4, 5].fetch_values(0, 3..4) # TypeError: in 'Array#fetch': no implicit conversion of Range into Integer

I believe aligning the implementations would lessen confusion (even if it makes #fetch_values implementation somewhat less trivial).

The practical example of usefulness:

HEADERS = %w[Name Department]

def table_headers(rows)
  HEADERS.fetch_values(...rows.map(&:size).max) { '<unknown'> }
  # Or, alternatively:
  # HEADERS.fetch_values(...rows.map(&:size).max) { raise ArgumentError, "No header defined for column #{it + 1}" }
end

table_headers([
  ['John'],
  ['Jane'],
]) #=> ["Name"]

table_headers([
  ['John'],
  ['Jane', 'Engineering'],
]) #=> ["Name", "Department"]

table_headers([
  ['John', 'Accounting', 'Feb 24'],
  ['Jane', 'Engineering'],
]) #=> ["Name", "Department", "<unknown>"]
# or ArgumentError No header defined for column 3

(Obviously, we can use fetch_values(*(0...max_row_size)) as an argument, but it feels like an unjustified extra work when values_at already can do this.)

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0