From: "willcosgrove (Will Cosgrove) via ruby-core" Date: 2024-03-06T04:39:56+00:00 Subject: [ruby-core:117064] [Ruby master Feature#20318] Pattern matching `case ... in` support for triple-dot arguments Issue #20318 has been updated by willcosgrove (Will Cosgrove). I'm going to throw my suggestion into the ring with no idea how hard it would be to implement. ``` ruby def foo when (name) # foo('ko1') puts name when (first_name, last_name) # foo('ko1', 'ssd') puts "Hi there #{first_name} #{last_name}" when (greeting:) # foo(greeting: 'hello') puts "Hello #{greeting}" else puts "No match: #{args}" end ``` I know there's a conflation happening in the pattern matching vocabulary with `when` vs `in`, but to me `when` reads clearer for method overloading. It reads to me as "foo, when called like this ..." I also think that being able to "pattern match" the same way you would in a method parameter list is more intuitive, at least to me, than the pattern matching syntax. ---------------------------------------- Feature #20318: Pattern matching `case ... in` support for triple-dot arguments https://bugs.ruby-lang.org/issues/20318#change-107138 * 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/