Techioz Blog

Ruby ハッシュ パターン マッチング - オプションのパターン

概要

Ruby 3 のハッシュ パターン マッチングでは、残りに許可されたキーのみが含まれるように指定することはできますか? これまでのところ、私はこれしか思いつきませんでした:

opts = { value: 5, limit: 10 } # valid
# opts = { value: 5 } # valid
# opts = { value: 5, foo: 10 } # not valid

case opts
in value:, **rest if rest.nil? || (rest.keys - %i[limit]).empty?
end

Flowtype からインスピレーションを得たものは、value:、limit?:、さらには 値の: 整数、制限?: 整数

解決策

rest.nil に注意してください。あなたの例では決して true にはならないので、その部分はまったく必要ありません。

case opts
in value:, **rest if (rest.keys - %i[limit]).empty?
end

# or if you are using rails
case opts
in value:, **rest if rest.excluding(:limit).empty?
end

**残りは常にハッシュです。

あなたがやろうとしていることと同等のパターンマッチングはありません。これは、代替パターンを使用して得ることができる限り近いものです。

opts = {value: 5, limit: 10}
case opts
in value:, **rest if rest in {limit:_}|{}
  [value, rest]
end

#=> [5, {:limit=>10}]
opts = {value: 5}
case opts
in value:, **rest if rest in {limit:_}|{}
  [value, rest]
end

#=> [5, {}]
opts = {value: 5, foo: 1}
case opts
in value:, **rest if rest in {limit:_}|{}
  [value, rest]
end

#=> (irb):346:in `<main>': {:value=>5, :foo=>1}: guard clause does not return true (NoMatchingPatternError)