From: "rubyFeedback (robert heiler) via ruby-core" <ruby-core@...>
Date: 2024-03-01T05:40:36+00:00
Subject: [ruby-core:117023] [Ruby master Feature#20318] Pattern matching `case ... in` support for triple-dot arguments

Issue #20318 has been updated by rubyFeedback (robert heiler).


Personally I find the double ... rather confusing. I understand the benefit of a more succint syntax - e. g. eliminating "(*args, **kwargs, &block)" - but even then I find the dual-triple-dot very strange. It seems rather "un-ruby" to me, however one wants to define that.

----------------------------------------
Feature #20318: Pattern matching `case ... in` support for triple-dot arguments
https://bugs.ruby-lang.org/issues/20318#change-107086

* Author: bradgessler (Brad Gessler)
* Status: Open
----------------------------------------

# Premise

Sometimes when I'm creating a method for an API, I'd like to do pattern matching against the arguments. Today I have to do something like this:

```ruby
def foo(*args, **kwargs, &block)
  case { args:, kwargs:, block: }
    in args: [name]
      puts name
    in args: [first_name, last_name]
      puts "Hi there #{first_name} #{last_name}"
    in kwargs: {greeting:}
      puts "Hello #{greeting}"
    else
      puts "No match: #{args}"
  end
end

foo "Hi"
foo "Brad", "Gessler"
foo greeting: "Brad"
```

Or an array like this:

```ruby
def bar(*args, **kwargs, &block)
  case [args, kwargs, block]
    in [name], {}, nil
      puts name
    in [first_name, last_name], {}, nil
      puts "Hi there #{first_name} #{last_name}"
    in [], {greeting:}, nil
      puts "Hello #{greeting}"
    else
      puts "No match: #{args}, #{kwargs}"
  end
end

bar "Howdy"
bar "Bradley", "Gessler"
bar greeting: "Bradley"
```

# Proposal

I'd like to propose the same thing, but for `...`, like this:

```ruby
def foo(...)
  case ...
    in args: [name]
      puts name
    in args: [first_name, last_name]
      puts "Hi there #{first_name} #{last_name}"
    in kwargs: {greeting:}
      puts "Hello #{greeting}"
    else
      puts "No match: #{args}"
  end
end

foo "Hi"
foo "Brad", "Gessler"
foo greeting: "Brad"
```

One thing I'm not sure sure about: the `args`, `kwargs`, and `block` names appear out of thin air, so ideally those could somehow be named or have a syntax that doesn't require those names.

The array would look like this:

```ruby
def bar(...)
  case ...
    in [name], {}, nil
      puts name
    in [first_name, last_name], {}, nil
      puts "Hi there #{first_name} #{last_name}"
    in [], {greeting:}, nil
      puts "Hello #{greeting}"
    else
      puts "No match: #{args}, #{kwargs}"
  end
end

bar "Howdy"
bar "Bradley", "Gessler"
bar greeting: "Bradley"
```



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/