Re: Detecting an imported function
by diotalevi (Canon) on Nov 17, 2005 at 02:44 UTC
|
Try checking the sub's compilation package. I'm using eval to cover just in case the value that was given to sub_package() isn't a code reference or whatever.
use B 'svref_2object';
sub sub_package { eval { svref_2object( shift )->STASH->NAME } }
| [reply] [d/l] |
|
|
| [reply] |
|
|
By placing this at the end of my file, it runs after all use() and ->import has occurred. Any imported methods will be visible now. Because my caller called me with a use() call, this code is run during the BEGIN-time of my caller. This is what I imagined tye was suggesting.
package Example;
use vars qw( @Methods );
use Anything::You::Like;
...
no strict 'refs';
@Methods = grep *{__PACKAGE__ . "::$_"}{CODE}, $keys %{__PACKAGE__ . "
+::"};
1;
| [reply] [d/l] |
Re: Detecting an imported function
by dragonchild (Archbishop) on Nov 17, 2005 at 03:46 UTC
|
Have you tried Perl6::Roles? I wrote it for Tim for the DBI2 rewrite and he hasn't complained yet ...
My criteria for good software:
- Does it work?
- Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
| [reply] |
|
|
No, I haven't. Class::Trait is appealing because I am intimately familiar with it and it's a very complete trait implementation including conflict resolution, proper trait composition, enforcement of requirements, method aliasing, reflection, etc. In short, it has everything we need.
Just glancing at your code suggests you might have the same problem that Class::Trait has:
push @methods, map { [ $r, $_ ] } grep {
*{"${r}::${_}"}{CODE}
} keys %{"${r}::"};
Where do those methods come from? Is there any chance a role might import a function (even as a constant) and have it exported?
| [reply] [d/l] |
|
|
Where do those methods come from?
From the role's package. The current specification, as I understand it, is that anything a role can do, the class doing the role can do.
Is there any chance a role might import a function (even as a constant) and have it exported?
If Role->can('foo'), then Class->does('Role') implies Class->can('foo') for all foo in Role. If this isn't the spec, then I can provide a mechanism in Perl6::Roles that will account for that. Let say you define a "@ROLE_METH" or somesuch. But, the current P6 spec, as I understand it, says that the class will get everything.
There is some discussion on p6l about whether or not the role will be able to reserve methods that are labelled private/protected/other, but, AFAIK, @Larry hasn't made a decision one way or the other.
My criteria for good software:
- Does it work?
- Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
| [reply] [d/l] [select] |
|
|
|
|
|
Re: Detecting an imported function (exclude time)
by tye (Sage) on Nov 17, 2005 at 06:19 UTC
|
For the heck of it, I'll suggest the low-tech approach of building a list of routines at BEGIN time and excluding these from the list of traits built at run time.
It isn't obvious from a quick glance when / how the post-compilation moving of all subroutines happens (I guess when the trait-implementing package gets imported), but that must already be happening. So all you need to add is code to cache the list of to-exclude subroutines when Class::Trait::import is called (and then exclude them, of course).
Of course, this means that the user needs to 'use' modules that import non-traits before 'use'ing Class::Trait. But it also means that the user can do creative things that 'import' subroutines that are meant to be traits... Which I find rather appealing.
| [reply] |
|
|
For what its worth, I'd prefer the flexibility tye's proposing than something as inlexible as I originally brought up (though it does answer the question very succinctly).
| [reply] |
|
|
package Foo;
BEGIN {
# &routine is not yet defined and therefore
# can't be added to any list
}
sub routine { ... }
Or am I missing something obvious?
| [reply] [d/l] |
|
|
Since BEGIN-phase processing is when subs get defined, and the processing goes top-to-bottom, put your BEGIN block after the subs.
use warnings;
use strict;
BEGIN {
print "Before: $_\n" for grep /f/, keys %{main::};
}
sub foo {
print "I am defined\n";
}
BEGIN {
print "After: $_\n" for grep /f/, keys %{main::};
}
Caution: Contents may have been coded under pressure.
| [reply] [d/l] |
|
|
|
|
package Limit::Traits;
use POSIX ':limits_h';
use Class::Traits ...; # Fetching now will give you "USHRT_MAX" etc.
# but not "foo" nor "bar"
sub foo { ... }
sub bar { ... }
Later, when Limit::Traits is used, you'll want to export a bunch of subroutines so you fetch the list of all code references in that package again but don't export the ones that were already there when you fetched that same list the first time (in Class::Traits::import).
| [reply] [d/l] |
|
|
|
|