{"id":20057614,"url":"https://github.com/todesking/patm","last_synced_at":"2025-07-05T03:36:21.980Z","repository":{"id":16219030,"uuid":"18966223","full_name":"todesking/patm","owner":"todesking","description":"Pattern matching library for Ruby","archived":false,"fork":false,"pushed_at":"2014-05-25T15:31:08.000Z","size":520,"stargazers_count":18,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-22T05:36:02.729Z","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":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/todesking.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-04-20T14:42:04.000Z","updated_at":"2017-09-21T03:04:08.000Z","dependencies_parsed_at":"2022-07-12T15:14:13.624Z","dependency_job_id":null,"html_url":"https://github.com/todesking/patm","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/todesking/patm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/todesking%2Fpatm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/todesking%2Fpatm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/todesking%2Fpatm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/todesking%2Fpatm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/todesking","download_url":"https://codeload.github.com/todesking/patm/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/todesking%2Fpatm/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262209824,"owners_count":23275471,"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-11-13T12:59:39.865Z","updated_at":"2025-07-05T03:36:21.960Z","avatar_url":"https://github.com/todesking.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PATM: PATtern Matcher for Ruby\n\n[![Build Status](https://travis-ci.org/todesking/patm.svg?branch=master)](https://travis-ci.org/todesking/patm)\n[![Code Climate](https://codeclimate.com/github/todesking/patm.png)](https://codeclimate.com/github/todesking/patm)\n\nPATM is extremely faster pattern match library.\n\nFeatures: Match value/classes, Capture, Array/Hash decomposition.\n\n## Usage\n\n```ruby\nrequire 'patm'\n```\n\n```ruby\n# With DSL\nclass A\n  extend ::Patm::DSL\n\n  define_matcher :match1 do|r|\n    p = Patm\n    r.on [:x, p._1, p._2] do|m|\n      [m._1, m._2]\n    end\n  end\n\n  define_matcher :match2 do|r|\n    r.on [:a, Patm._xs \u0026 Patm._1] do|m, _self|\n      _self.match1(m._1)\n    end\n    # ...\n    r.else do\n      nil\n    end\n  end\nend\n\nA.new.match1([:x, 1, 2])\n# =\u003e [1, 2]\n```\n\n```ruby\n# With case(simple but slow)\ndef match(obj)\n  p = Patm\n  _xs = Patm._xs\n  case obj\n  when m = Patm.match([:x, p._1, p._2])\n    [m._2, m._1]\n  when m = Patm.match([1, _xs\u0026p._1])\n    m._1\n  end\nend\n\nmatch([1, 2, 3])\n# =\u003e [2, 3]\n\nmatch([:x, :y, :z])\n# =\u003e [:z, :y]\n\nmatch([])\n# =\u003e nil\n```\n\n```ruby\n# With pre-built Rule\nrule = Patm::Rule.new do|r|\n  p = Patm\n  _xs = Patm._xs\n  r.on [:x, p._1, p._2] do|m|\n    [m._2, m._1]\n  end\n  r.on [1, _xs\u0026p._1] do|m|\n    m._1\n  end\nend\n\nrule.apply([1,2,3])\n# =\u003e [2, 3]\n\nrule.apply([:x, :y, :z])\n# =\u003e [:z, :y]\n\nrule.apply([])\n# =\u003e nil\n```\n\n## DSL\n\n```ruby\nclass PatternMatcher\n  extend Patm::DSL\n\n  define_matcher(:match) do|r| # r is instance of Patm::Rule\n    # r.on( PATTERN ) {|match, _self|\n    #   First argument is instance of Patm::Match. Use it to access captured value.\n    #   ex. m._1, m._2, ..., m[capture_name]\n    #\n    #   Second argument is instance of the class. Use it to access other methods.\n    #   ex. _self.other_method\n    # }\n    #\n    # r.else {|value, _self|\n    #   First argument is the value. Second is instance of the class.\n    # }\n  end\nend\n\nmatcher = PatternMatcher.new\n\nmatcher.match(1)\n```\n\n## Patterns\n\n### Value\n\nValue patterns such as `1, :x, String, ...` matches if `pattern === target_value` is true.\n\n### Struct\n\n```ruby\nA = Struct.new(:x, :y)\n\n# ...\ndefine_matcher :match_struct do|r|\n  # use Patm[struct_class].( ... ) for match struct\n  # argument is a Hash(member_name =\u003e pattern) or patterns that correspond struct members.\n  r.on Patm[A].(x: 1, y: Patm._1) {|m| m._1 }\n  r.on Patm[A].(2, Patm._1) {|m| m._1 }\nend\n```\n\n### Array\n\n`[1, 2, _any]` matches `[1, 2, 3]`, `[1, 2, :x]`, etc.\n\n`[1, 2, _xs]` matches `[1, 2]`, `[1, 2, 3]`, `[1, 2, 3, 4]`, etc.\n\n`[1, _xs, 2]` matches `[1, 2]`, `[1, 10, 2]`, etc.\n\nNote: More than one `_xs` in same array is invalid.\n\n### Hash\n\n`{a: 1}` matches `{a: 1}`, `{a: 1, b: 2}`, etc.\n\n`{a: 1, Patm.exact =\u003e true}` matches only `{a: 1}`.\n\n`{a: 1, b: Patm.opt(2)}` matches `{a: 1}`, `{a: 1, b: 2}`.\n\n### Capture\n\n`_1`, `_2`, etc matches any value, and capture the value as correspond match group.\n\n`Pattern#[capture_name]` also used for capture.`Patm._any[:foo]` capture any value as `foo`.\n\nCaptured values are accessible through `Match#_1, _2, ...` and `Match#[capture_name]`\n\n### Compose\n\n`_1\u0026[_any, _any]` matches any two element array, and capture the array as _1.\n`Patm.or(1, 2)` matches 1 or 2.\n\n\n## Performance\n\nsee [benchmark code](./benchmark/comparison.rb) for details\n\nMachine: MacBook Air(Late 2010) C2D 1.8GHz, OS X 10.9.2\n\n```\nRUBY_VERSION: 2.1.2 p95\n\nBenchmark: Empty(x10000)\n                    user     system      total        real\nmanual          0.010000   0.000000   0.010000 (  0.012252)\npatm            0.060000   0.000000   0.060000 (  0.057050)\npattern_match   1.710000   0.010000   1.720000 (  1.765749)\n\nBenchmark: SimpleConst(x10000)\n                    user     system      total        real\nmanual          0.020000   0.000000   0.020000 (  0.018274)\npatm            0.060000   0.000000   0.060000 (  0.075068)\npatm_case       0.160000   0.000000   0.160000 (  0.161002)\npattern_match   1.960000   0.020000   1.980000 (  2.007936)\n\nBenchmark: ArrayDecomposition(x10000)\n                    user     system      total        real\nmanual          0.050000   0.000000   0.050000 (  0.047948)\npatm            0.250000   0.000000   0.250000 (  0.254039)\npatm_case       1.710000   0.000000   1.710000 (  1.765656)\npattern_match  12.890000   0.060000  12.950000 ( 13.343334)\n\nBenchmark: VarArray(x10000)\n                    user     system      total        real\nmanual          0.050000   0.000000   0.050000 (  0.052425)\npatm            0.210000   0.000000   0.210000 (  0.223190)\npatm_case       1.440000   0.000000   1.440000 (  1.587535)\npattern_match  10.050000   0.070000  10.120000 ( 10.898683)\n```\n\n\n## Changes\n\n### 3.1.0\n\n- Struct matcher\n\n### 3.0.0\n\n- If given value can't match any pattern and no `else`, `Patm::NoMatchError` raised(Instead of return nil).\n- RuleCache is now obsoleted. Use DSL.\n- More optimized compiler\n\n### 2.0.1\n\n- Bugfix: About pattern `Patm._1 \u0026 Array`.\n- Bugfix: Compiler bug fix.\n\n### 2.0.0\n\n- Named capture\n- Patm::GROUPS is obsolete. Use `pattern[number_or_name]` or `Patm._1, _2, ...` instead.\n- More optimize for compiled pattern.\n- Hash patterns\n\n### 1.0.0\n\n- DSL\n- Compile is enabled by default\n- Change interface\n\n### 0.1.0\n\n- Faster matching with pattern compilation\n- Fix StackOverflow bug for `[Patm.or()]`\n\n### 0.0.1\n\n- Initial release\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftodesking%2Fpatm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftodesking%2Fpatm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftodesking%2Fpatm/lists"}