Project

General

Profile

Actions

Feature #17006

open

Let `Kernel#Hash` take a block to provide the default value

Added by sawa (Tsuyoshi Sawada) 10 months ago. Updated 10 months ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:99042]

Description

Sometimes, we need to create a hash that has explicit key-value pairs as well as a default value, but there has not been a way to do that at once. The most naive way is to do like this:

h = {a: 1, b: 2}
h.default_proc = ->(h, k){raise "Unknown key #{k}"}
h # => ...

A more sophisticated way is this:

Hash.new{|h, k| raise "Unknown key #{k}"}.merge({a: 1, b: 2})

But that is still not short enough, and it also looks backwards, i.e., we usually want to specify the explicit key-value pairs before the default value.

My proposal is to allow Kernel#Hash to take a block that provides the default value in the same way as the block of Hash.new:

Hash({a: 1, b: 2}){|h, k| raise "Unknown key #{k}"}
Actions #1

Updated by sawa (Tsuyoshi Sawada) 10 months ago

  • Description updated (diff)

Updated by nobu (Nobuyoshi Nakada) 10 months ago

The description mentions the default value first, but the proposal will solve the default proc only.

Updated by sawa (Tsuyoshi Sawada) 10 months ago

nobu (Nobuyoshi Nakada) wrote in #note-2:

The description mentions the default value first, but the proposal will solve the default proc only.

Default value is a special (static) case of default proc, so I think having the latter would be enough:

Hash({a: 1, b: 2}){0}

If there is concern for efficiency, at least for strings, we can turn on the frozen string mode.

# frozen_string_literal: true

Hash({1 => "a", 2 => "b"}){"c"}
Actions

Also available in: Atom PDF