sartak/Class-Method-Modifiers — pull request #4 by arc (2012-12-29 16:13:14+00:00)
Title: New "supplementary" modifier

Hi, Shawn. We spoke at YAPC::EU in Frankfurt about an idea I had for a new modifier type in `Class::Method::Modifiers`. Sorry it's taken me so long to follow up on that.

As a reminder, I'm proposing a modifier that ordinarily just installs a coderef in the appropriate class; but if a method of the relevant name already exists in the class's inheritance graph, an exception gets thrown. This allows you to ensure that, if you derive from a class controlled by someone else, you can't get surprised if a future version of the base class adds a new method whose name conflicts with one you were using in the subclass. Combining these semantics with `install_modifier` also provides for the same sort of safety when locally monkey-patching an existing class. My YAPC::EU 2011 talk goes into more detail on the idea: http://aaroncrane.co.uk/talks/monkey_patching_subclassing/

This pull request implements this feature with the name `supplementary`. I'm not entirely happy with the naming, though using an adjective does at least mean it's reasonable to talk about "supplementary methods" and the like. Other possibilities I've considered include `fresh`, `inject`, `nonoverride`, and even (for my sins) `monkey`. If you have any alternative suggestions, I'm all ears, and I'd be happy to rework this patch series to use your preferred name.

There's also an aspect of the implementation I'm not delighted with: I'd like to be able to use `Sub::Name` to set the coderef's internal name appropriately, so that it could be directly installed into the relevant stash without falling foul of `namespace::autoclean` and the like. But that would introduce a runtime dependency on an XS module, which I've assumed probably isn't the right tradeoff for CMM. Instead, I use string `eval` to define a subroutine in the target package; that named subroutine wraps the coderef passed to `supplementary`. (This matches the approach taken for the other modifiers, too.) As an optimisation, the wrapper subroutine is avoided when the coderef was compiled in the target package; in practice, that means that callers are likely to get the wrapper iff they use `install_modifier` rather than `supplementary`.

I've sent this pull request to your Github repo, but I'm not sure if I should be using @karenetheridge's instead. I have used Karen's master branch as my starting point, though.

Let me know if there's anything else you'd like me to change or tweak before accepting this.