{"id":15405690,"url":"https://github.com/zverok/pattern-matching-prototype","last_synced_at":"2025-07-06T13:08:10.963Z","repository":{"id":136288783,"uuid":"138767547","full_name":"zverok/pattern-matching-prototype","owner":"zverok","description":"Showcase of possible Ruby core language pattern matching","archived":false,"fork":false,"pushed_at":"2018-06-26T16:58:08.000Z","size":4,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-26T11:11:14.498Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zverok.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-26T16:57:45.000Z","updated_at":"2018-11-10T09:44:21.000Z","dependencies_parsed_at":"2023-06-25T22:56:11.274Z","dependency_job_id":null,"html_url":"https://github.com/zverok/pattern-matching-prototype","commit_stats":{"total_commits":1,"total_committers":1,"mean_commits":1.0,"dds":0.0,"last_synced_commit":"d6cbcc2c52f8f37b4cceb6462134f69c775bd0c5"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zverok%2Fpattern-matching-prototype","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zverok%2Fpattern-matching-prototype/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zverok%2Fpattern-matching-prototype/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zverok%2Fpattern-matching-prototype/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zverok","download_url":"https://codeload.github.com/zverok/pattern-matching-prototype/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244823916,"owners_count":20516372,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-01T16:18:16.236Z","updated_at":"2025-03-21T15:43:04.198Z","avatar_url":"https://github.com/zverok.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"This is _proof-of-concept_ (released as a gem just for the sake of experimentation) for a discussion of how the reasonable amount of _new_ pattern-matching features in Ruby language core could look.\n\nThe detailed description and discussion of problem scope could be found in a corresponding [blog post](https://zverok.github.io/blog/2018-06-26-pattern-matching.html).\n\nHere, just to show the idea, the small example of \"imaginary\" syntax of enhanced `case` matching:\n\n```ruby\ndef parse_coord(lat, *lngs)\n  print \"parsing (%p, *%p) =\u003e \" % [lat, lngs]\n\n  case (lat, *lngs)                       # several variables can be matched at once\n  when (String)\n    puts \"one string\"\n  when (Integer, Integer =\u003e lng)          # matched sub-pattern could be bound to local variable\n    puts \"two integers %p, %p\" %\n      [lat, lng]\n  when (Integer, Integer =\u003e lng, Hash =\u003e opts)\n    puts \"two integers \u0026 opts: %p, %p, %p\" %\n      [lat, lng, opts]\n  when (Integer, *Integer)                # array of objects of same type matched with \"splat\" syntax\n    puts \"integer + array of integers\"\n  when (_, _, Hash =\u003e opts)               # _ is skip/match any value\n    puts \"something + Hash %p\" % opts\n  else\n    puts \"no matches\"\n  end\nend\n\nparse_coord(10, 20)                     # (Integer, Integer =\u003e lng) pattern works\nparse_coord('10,20')                    # (String)\nparse_coord(10, 20, rectangular: true)  # (Integer, Integer =\u003e lng, Hash =\u003e opts)\nparse_coord(10, 20, 30)                 # (Integer, *Integer)\nparse_coord('foo', 'bar', rectangular: true) # (_, _, Hash =\u003e opts)\nparse_coord('10,20', 30)                # Note that (String) pattern should NOT match this\nparse_coord(10, 20, '30')               # Note that (Integer, *Integer) pattern should NOT match this\n```\n\nAnd here is how the library imitates it:\n\n* `M()` instead of just `()` (and array of case arguments instead of `()` again);\n* `binding_of_caller` with predefined local variables hack to bind variables;\n* `Class#to_a` defined (instead of `*` being special syntax in this context).\n\n```ruby\ndef parse_coord(lat, *lngs)\n  lng, opts = nil # binding will need that\n\n  print \"parsing (%p, *%p) =\u003e \" % [lat, lngs]\n\n  case [lat, *lngs]\n  when M(String)\n    puts \"one string\"\n  when M(Integer, Integer =\u003e :lng)\n    puts \"two integers %p, %p\" % [lat, lng]\n  when M(Integer, Integer =\u003e :lng, Hash =\u003e :opts)\n    puts \"two integers \u0026 opts: %p, %p, %p\" %\n      [lat, lng, opts]\n  when M(Integer, *Integer)\n    puts \"integer + array of integers\"\n  when M(_, _, Hash =\u003e :opts)\n    puts \"something + Hash %p\" % opts\n  else\n    puts \"no matches\"\n  end\nend\n```\n\nRun `ruby demo.rb` to see code above work (including binding to local variables).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzverok%2Fpattern-matching-prototype","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzverok%2Fpattern-matching-prototype","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzverok%2Fpattern-matching-prototype/lists"}