Skip to content

Add NamedTuple#reverse_merge #15023

@stephannv

Description

@stephannv

This would be useful in cases like this:

# Instead of
def my_button(text, **html_options)
  a(text, **{class: "btn btn-default", role: "button" }.merge(html_options))
end

def my_input(name, **html_options)
  input(**{type: "text", name: name, id: name}.merge(html_options)
end

# We could write
def my_button(text, **html_options)
  a(text, **html_options.reverse_merge(class: "btn btn-default", role: "button"))
end

def my_input(name, **html_options)
  input(**html_options.reverse_merge(type: "text", name: name, id: name))
end

I think it makes clear that intent is to use the html_options primarily.

I think the code would be something like this:

  def reverse_merge(other : NamedTuple)
    other.merge(**self)
  end

  def reverse_merge(**other)
    reverse_merge(other)
  end

Based on @straight-shoota comment on Crystal discord channel.

stephann: In another case, I wanted to merge values into a named tuple, but I wanted that existing values not to be overwritten, instead of **options.merge(x: 1, y: 2), I had to make **{ x: 1, y: 2 }.merge(options). Which isn't a problem at all, but it would be nice to have something like options.with_defaults(x: 1, y: 2), or options.reverse_merge(x:1 , y: 2).

straight-shoota: I believe an implementation of NamedTuple#reverse_merge could be accepted. IIRC something like this was mentioned in a discussion some time ago, but I can't find it.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions