{"atom":"regression/user-method-vs-mop-noop","family":"regression","slug":"user-method-vs-mop-noop","header":{"atom":"regression/user-method-vs-mop-noop","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/user-method-vs-mop-noop.raku","counts":{"a":1,"f":0,"d":0,"c":0,"r":0,"n":0},"files":["atoms/regression/user-method-vs-mop-noop.grid"],"records":[["0001","","# Regression: a user-defined method whose name collides with a metamodel no-op\n# (compose / publish_method_cache / set_rw / …) must NOT be shadowed by rakupp's\n# `.^compose`-style no-op handler. This broke Cro.compose (returned the invocant\n# `Cro` instead of a Cro::CompositeConnector), silently killing Cro::HTTP::Client\n# at connection setup. `.^compose` (the real metamodel call) must still no-op.\n# Contract: exit 0 + last line PASS.\nmy @fail;\n\n# a plain `method compose` runs and returns its own value, not the invocant\nclass Pipe {\n    has $.tag;\n    method compose(*@p) { Pipe.new(tag => @p.join(',')) }\n}\nmy $p = Pipe.compose(1, 2, 3);\n@fail.push(\"compose-defined\") unless $p.defined;\n@fail.push(\"compose-tag ({$p.tag // 'undef'})\") unless $p.defined && $p.tag eq '1,2,3';\n\n# other MOP no-op names as user methods\nclass Widget {\n    method publish_method_cache { 'published' }\n    method set_rw($x) { \"rw:$x\" }\n    method compose_attributes { 'composed-attrs' }\n}\n@fail.push('publish_method_cache') unless Widget.publish_method_cache eq 'published';\n@fail.push('set_rw') unless Widget.set_rw(5) eq 'rw:5';\n@fail.push('compose_attributes') unless Widget.compose_attributes eq 'composed-attrs';\n\n# instance too\nclass C2 { method compose { 'inst-compose' } }\n@fail.push('instance-compose') unless C2.new.compose eq 'inst-compose';\n\n# .^compose stays a no-op returning the type (metamodel finalize)\n@fail.push('meta-compose') unless Widget.^compose === Widget;\n\nif @fail { note \"FAILED: @fail[]\"; say 'FAIL' } else { say 'PASS' }","output PASS","a",["PASS","PASS"],0,[["budget","20s"]]]]}