From: "ntl (Nathan Ladd) via ruby-core" <ruby-core@...>
Date: 2024-03-06T20:10:18+00:00
Subject: [ruby-core:117069] [Ruby master Feature#20318] Pattern matching `case ... in` support for triple-dot arguments

Issue #20318 has been updated by ntl (Nathan Ladd).


It might be a good idea to consider how proc/lambda/block arguments could also have comparable syntax. For instance, a block argument example:

``` ruby
HTTP.post("http://example.com/some-resource", "some data") do |...|
in code: (200...300)
  puts "Success!"
in code: (300...400), location:
  puts "Redirect to #{location}"
  # post to location
in code: (500...600)
  puts "Server error"
  do_retry
end
```

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

* 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/