There's more than one way to do things | |
PerlMonks |
comment on |
( [id://3333]=superdoc: print w/replies, xml ) | Need Help?? |
You could, of course, define the function yourself, except that you would have to patch the module code, hardly "easy". Attribute::Handlers stores all of its attribute definitions in a private-to-package my variable @aDeclarations. There is no way to get at this data except by working within the package itself, i.e. patching it. You could explicitly push the attributes into your own array each time you define a routine, as shmem suggests, but then you have to define to your team (or the coder that comes after you) that this is the "pattern" for how we define these functions and either write it down somewhere (will anyone read it?) or make it part of team memory (how?). That isn't always reliable - someone is bound to forget, leading to hard to track down bugs. So it is difficult in a different way. There is another important reason for encapsulating your handling of attributes in a module rather than explicitly defining a FETCH routine in each package. The interface for attribute handling, including the FETCH method is, to quote the perldocs: WARNING: the mechanisms described here are still experimental. Do not rely on the current implementation. Personally, I prefer solutions where the structure itself prevents human error and minimizes the impact of interface change, so I would go for a solution that encapsulates how Perl comes to understand your handlers exist and lets you define nothing other than attribute functionality in your attribute handlers. It turns out it is pretty easy and short (about 20-25 lines), if you make use of the current interface. That interface did not exist when Attribute::Handlers was first written in 2001, which is part of the reason it is so much longer. First I would define a small module, let's call it Monks::AttributeDispatcher, to replace mod:://Attribute::Handlers. This module's use statement would accept a dispatch table as the parameters for its use clause and would manufacture the calling package's FETCH_CODE_ATTRIBUTES and MODIFY_CODE ATTRIBUTES methods. The code that used the module would look like this:
The Monks::AttributeDispatcher module would look like this:
Note 1:Your handler gets three parameters: the name of the package where the subroutine is defined, the code reference of the subroutine, and the name of the attribute. This permits you to write context aware handlers, should you wish. Note 2: If your subroutines are too complex to define in-line (or you want two attributes to share the same handler) you can always define the handler subroutines in a BEGIN {} block before your use Monks::Dispatcher statement. The following code illustrates both notes 1&2:
Caveat 1: This version assumes you only care about subroutine attributes handlers since that was all you mentioned in your post. It would be relatively easy to modify it to have it emulate Attribute::Handlers's ability to selectively apply handlers to more than one type of object (SCALAR, CODE, etc). I would (a) replace the value of each hash element with a 2-element array reference indicate type and code reference. (b) revise the module to make use of that information. There are separate FETCH and MODIFY methods for each type of reference. Caveat 2: I've been playing around with this some more and the one thing I can't seem to make Monks::AttributeDispatcher do is replace definition of function foo(...) with something else (I can,however, generate new functions that call foo(...).). Attribute::Handlers can do this easily because it gets the *name* of the subroutine rather than a code reference. MODIFY_CODE_ATTRIBUTES only gets the code reference. If there is a Perl trick to work around this, it is missing from my bag-o-tricks. If this is important to you and there is no work around, it looks to me like your only "non-intrusive" choice would be to patch Attribute::Handlers so that it generates the FETCH method. Best, beth Update: posted at the same time as shmem, added discussion of shmem's post. Update 2: Added question about why using Attribute::Handlers. Update 2:posted alternate to Attribute::Handlers - it is not nice to suggest one should make a patch without showing how. Update 3:added second caveat. In reply to Re: Support for attributes:get in Attribute::Handlers?
by ELISHEVA
|
|