{"atom":"regression/zef-ecosystem-cluster","family":"regression","slug":"zef-ecosystem-cluster","header":{"atom":"regression/zef-ecosystem-cluster","kind":"whole-program — a minimal repro, not yet reduced to an atom","source":"curated"},"axes":null,"cols":null,"engines":["rakudo-2026.07","rakupp-3.14.0"],"kinds":["ref","pp"],"defFrom":"rakupp:t/regression/zef-ecosystem-cluster.raku","counts":{"a":1,"f":0,"d":0,"c":0,"r":0,"n":0},"files":["atoms/regression/zef-ecosystem-cluster.grid"],"records":[["0001","","# Regression: the general fixes that made `zef install <name>` work from the LIVE\n# fez/cpan/p6c ecosystems under rakupp (search -> fetch -> extract -> install):\n#   1. the anonymous `$` state var: `$ = EXPR` re-assigns on EVERY evaluation\n#      (only the slot persists). zef's `::($ = $module)` plugin loader stuck at\n#      the first module name, constructing every plugin from the wrong class.\n#   2. composed subrule char-classes: `<-restricted +name-sep>` == one `name-sep`\n#      match OR any char not matching `restricted` (zef's identity grammar).\n#   3. `<( … )>` match-capture markers set the match's .from/.to.\n#   4. a separator quantifier: `X* %% [SEP]+`.\n#   5. IO::Path.basename ignores trailing slashes (\"http://x/\" -> \"x\").\n#   6. IO::Path.relative($base) (prefix case).\n#   7. Buf.append(Blob) appends the blob's BYTES (Proc stdout :bin chunks).\n# Contract: exit 0 + last line PASS.\nmy @fail;\n\n# 1. anonymous $ re-assigns per evaluation; $++ slot still persists\nmy @seen;\nfor <a b c> -> $m { @seen.push($ = $m) }\n@fail.push(\"anon-assign ({@seen.join(',')})\") unless @seen eqv [<a b c>];\nmy @n = (1..3).map({ $++ });\n@fail.push('anon-counter') unless @n[*-1] == 2; # slot persisted across calls\n\n# 2. composed subrule char class (zef's REQUIRE grammar shape)\ngrammar Ident {\n    token restricted { [':' | '<' | '>' | '(' | ')'] }\n    token name-sep   { < :: > }\n    regex name  { <-restricted +name-sep>+ }\n    token key   { <-restricted>+ }\n    regex value { '<' ~ '>' [<( [[ <!before \\>|\\<|\\\\> . ]+?]* %% ['\\\\' . ]+ )>] }\n    regex TOP   { ^^ <name> [':' <key> <value>]* $$ }\n}\nmy $m = Ident.parse('Abbreviations:ver<2.2.1>:auth<zef:tbrowder>');\n@fail.push('grammar-parse') unless $m;\n@fail.push(\"grammar-name ({$m<name>})\") unless $m && $m<name> eq 'Abbreviations';\n@fail.push('grammar-keys') unless $m && $m<key>.elems == 2;\n\n# 3. <( )> markers trim the overall match\n@fail.push('cap-markers') unless ('x123y' ~~ /x <( \\d+ )> y/) && ~$/ eq '123';\n\n# 4. quantified separator\n@fail.push('sep-quant') unless ('a,,b,,c' ~~ /^ [\\w+]* %% [\\,]+ $/).Bool;\n\n# 5. basename with trailing slash\n@fail.push('basename') unless 'http://360.zef.pm/'.IO.basename eq '360.zef.pm' && '/a/b/'.IO.basename eq 'b';\n\n# 6. relative\n@fail.push('relative') unless '/a/b/c/d.txt'.IO.relative('/a/b') eq 'c/d.txt';\n\n# 7. Buf.append(Blob) appends bytes\nmy $b = Buf.new;\n$b.append('AB'.encode);\n@fail.push('buf-append') unless $b.elems == 2 && $b.decode eq 'AB';\n\nif @fail { note \"FAILED: @fail[]\"; say 'FAIL' } else { say 'PASS' }","output PASS","a",["PASS","PASS"],0,[["budget","20s"]]]]}