ruby-changes:60652
From: zverok <ko1@a...>
Date: Sat, 4 Apr 2020 23:17:14 +0900 (JST)
Subject: [ruby-changes:60652] 33260d404f (master): Enhance pattern matching introduction
https://git.ruby-lang.org/ruby.git/commit/?id=33260d404f From 33260d404f56e27bb6fccc36e91a34d165c13bb1 Mon Sep 17 00:00:00 2001 From: zverok <zverok.offline@g...> Date: Sun, 8 Mar 2020 16:30:40 +0200 Subject: Enhance pattern matching introduction diff --git a/doc/syntax/pattern_matching.rdoc b/doc/syntax/pattern_matching.rdoc index a7f7304..3bb9309 100644 --- a/doc/syntax/pattern_matching.rdoc +++ b/doc/syntax/pattern_matching.rdoc @@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/doc/syntax/pattern_matching.rdoc#L1 = Pattern matching -Pattern matching is an experimental feature allowing deep matching of structured values: checking the structure, and binding the matched parts to local variables. +Pattern matching is an experimental feature allowing deep matching of structured values: checking the structure and binding the matched parts to local variables. Pattern matching in Ruby is implemented with the +in+ operator, which can be used in a standalone expression: @@ -23,39 +23,28 @@ or within the +case+ statement: https://github.com/ruby/ruby/blob/trunk/doc/syntax/pattern_matching.rdoc#L23 Pattern matching is _exhaustive_: if variable doesn't match pattern (in a separate +in+ statement), or doesn't matches any branch of +case+ statement (and +else+ branch is absent), +NoMatchingPatternError+ is raised. -Therefore, standalone +in+ statement is most useful when expected data structure is known beforehand, to unpack parts of it: +Therefore, +case+ statement might be used for conditional matching and unpacking: - def connect_to_db(config) # imagine config is a huge configuration hash from YAML - # this statement will either unpack parts of the config into local variables, - # or raise if config's structure is unexpected - config in {connections: {db: {user:, password:}}, logging: {level: log_level}} - p [user, passsword, log_level] # local variables now contain relevant parts of the config - # ... - end - -whilst +case+ form can be used for matching and unpacking simultaneously: + config = {db: {user: 'admin', password: 'abc123'}} case config - in String - JSON.parse(config) # ...and then probably try to match it again + in db: {user:} # matches subhash and puts matched value in variable user + puts "Connect with user '#{user}'" + in connection: {username: } + puts "Connect with user '#{username}'" + else + puts "Unrecognized structure of config" + end + # Prints: "connect with user 'admin'" - in version: '1', db: - # hash with {version: '1'} is expected to have db: key - puts "database configuration: #{db}" +whilst standalone +in+ statement is most useful when expected data structure is known beforehand, to just unpack parts of it: - in version: '2', connections: {database:} - # hash with {version: '2'} is expected to have nested connection: database: structure - puts "database configuration: #{database}" + config = {db: {user: 'admin', password: 'abc123'}} - in String => user, String => password - # sometimes connection is passed as just a pair of (user, password) - puts "database configuration: #{user}:#{password}" + config in {db: {user:}} # will raise if the config's structure is unexpected - in Hash | Array - raise "Malformed config structure: #{config}" - else - raise "Unrecognized config type: #{config.class}" - end + puts "Connect with user '#{user}'" + # Prints: "connect with user 'admin'" See below for more examples and explanations of the syntax. -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/