RFC strict::can
strict::can is a module which, if used, imports a can method into your namespace. This version of can() will not report imported helper functions or private methods. Full docs below. Comments and suggestions welcome. Cheers, Ovid -- NAME strict::can - Make can() ignore private methods and imported subroutines VERSION Version 0.01 SYNOPSIS package Foo; use strict::can; use HTML::Entities qw(encode_entities); # imported into Foo:: sub new { bless {}, shift } sub _private { 'some private function' } # later Foo-can('new'); # true Foo-can('encode_entities'); # false (because it's an imported function) Foo-can('_private'); # false (because it's a private function, even #though we can still call it) EXPORT This module exports a can() method into your namespace. DESCRIPTION This module gives your classes a can() method which overrides (not replaces) UNIVERSAL::can. In most respects it behaves like you expect it should, but does not report private methods (see below) or imported functions. Imported functions Frequently we import helper functions into our namespace. Ordinarily can() will return the code reference for these functions even though this is probably not what we want. strict::can will return false for any imported functions/methods. If you want to expose them, write wrapper methods for them. { package Foo; use strict::can; use HTML::Entities qw/encode_entities/; # import into Foo:: ... sub encode { my ($self, @args) = @_; return encode_entities(@args); } } # later if (Foo-can('encode_entities')) { # never gets to here } Private methods Methods which begin with an underscore are, by convention, considered private and should not be relied on. Unfortunately, can() succeeds with those, too. strict::can will return false for private methods unless the class checking can() is a *subclass* of the class or instance it is checking. This is because we're allowing a little more trust for subclasses as private methods are often protected methods which subclasses should be allowed to use. { package Foo; use strict::can; ... sub _private { return 'Top Sekret!'; } } # later { package main; if (Foo-can('_private')) { # never gets to here } } { package Foo::Bar; our @ISA = qw(Foo); if (Foo-can('_private')) { # success at last! } } AUTHOR Curtis Ovid Poe, [EMAIL PROTECTED] BUGS Please report any bugs or feature requests to [EMAIL PROTECTED], or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=strict-can. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. SEE ALSO The B::svref_2object function. COPYRIGHT LICENSE Copyright 2005 Curtis Ovid Poe, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. -- If this message is a response to a question on a mailing list, please send follow up questions to the list. Web Programming with Perl -- http://users.easystreet.com/ovid/cgi_course/
Re: Perl editing support in Vim (was: FF:: namespace)
A. Pagaltzis writes: * Smylers [EMAIL PROTECTED] [2005-12-04 03:35]: That's because the default ftplugin/perl.vim sets iskeyword to include the colon, so that all gets treated as a single word. Until now I hadn't seen a disadvantage of removing that colon, but now you've pointed that out I'm going to have to choose between putting up with that bug in syntax highlighting or making namespaces more awkward to complete ... Another disadvantage, and a reason I could never live without that colon: move the cursor on top of a module name, then hit [Ctrl-W][f] or [g][f]. That's the colon in isfname (which I do have), rather than the one in iskeyword (which I don't, but perhaps I should). Neat, no? Indeed (though there's an irritating bug where if I have something like ~/lib/perl/ early in my path and CGI::Lite is installed there then when Perl searches for CGI will find the _directory_ ~/lib/perl/CGI/ (necessary for CGI::Lite), rather than CGI.pm (which is later in the path). There's some magic which says also check for this filename with '.pm' on the end, but we really want that to be only rather than also. The last time I looked at that I couldn't see a way of fixing it. It could be smarter yet (it only works relative to @INC or the current directory; hmm, now that I think about it I may have an idea for to fix that?) I have this in ~/.vim/after/ftplugin/perl.vim: let l:path = system('perl -I, -Ilib -I../lib -e print join q[,], @INC') That adds in ./lib/ and ../lib/. But it'd be good to look for use lib statements and similar in the code and add those in too. Smylers -- May God bless us with enough foolishness to believe that we can make a difference in this world, so that we can do what others claim cannot be done.
Re: RFC strict::can
On 12/4/05, Ovid [EMAIL PROTECTED] wrote: strict::can is a module which, if used, imports a can method into your namespace. This version of can() will not report imported helper functions or private methods. Full docs below. Comments and suggestions welcome. I think that the ignore private feature is less than useful. If one agrees with the convention of prepending private methods with an underscore (which I personally do find useful), then one won't *call* can() on such a method. But since that convention is not enforced by the language, what is the value of codifying it in a module? As to the imported-subroutines feature, that could break a lot of code. Here's a simple example: package Foo; use Exporter; use strict::can; if (Foo-can('import')); # BOOM I can provide other examples from my own code, but I think you get the point. The module is clever, but it's not clear to me that it's practically useful. Could you provide a real-world example where this would help to prevent or detect a programming error? - Kurt Cheers, Ovid -- NAME strict::can - Make can() ignore private methods and imported subroutines VERSION Version 0.01 SYNOPSIS package Foo; use strict::can; use HTML::Entities qw(encode_entities); # imported into Foo:: sub new { bless {}, shift } sub _private { 'some private function' } # later Foo-can('new'); # true Foo-can('encode_entities'); # false (because it's an imported function) Foo-can('_private'); # false (because it's a private function, even #though we can still call it) EXPORT This module exports a can() method into your namespace. DESCRIPTION This module gives your classes a can() method which overrides (not replaces) UNIVERSAL::can. In most respects it behaves like you expect it should, but does not report private methods (see below) or imported functions. Imported functions Frequently we import helper functions into our namespace. Ordinarily can() will return the code reference for these functions even though this is probably not what we want. strict::can will return false for any imported functions/methods. If you want to expose them, write wrapper methods for them. { package Foo; use strict::can; use HTML::Entities qw/encode_entities/; # import into Foo:: ... sub encode { my ($self, @args) = @_; return encode_entities(@args); } } # later if (Foo-can('encode_entities')) { # never gets to here } Private methods Methods which begin with an underscore are, by convention, considered private and should not be relied on. Unfortunately, can() succeeds with those, too. strict::can will return false for private methods unless the class checking can() is a *subclass* of the class or instance it is checking. This is because we're allowing a little more trust for subclasses as private methods are often protected methods which subclasses should be allowed to use. { package Foo; use strict::can; ... sub _private { return 'Top Sekret!'; } } # later { package main; if (Foo-can('_private')) { # never gets to here } } { package Foo::Bar; our @ISA = qw(Foo); if (Foo-can('_private')) { # success at last! } } AUTHOR Curtis Ovid Poe, [EMAIL PROTECTED] BUGS Please report any bugs or feature requests to [EMAIL PROTECTED], or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=strict-can. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. SEE ALSO The B::svref_2object function. COPYRIGHT LICENSE Copyright 2005 Curtis Ovid Poe, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. -- If this message is a response to a question on a mailing list, please send follow up questions to the list. Web Programming with Perl -- http://users.easystreet.com/ovid/cgi_course/
Re: RFC strict::can
--- Kurt Starsinic [EMAIL PROTECTED] wrote: package Foo; use Exporter; use strict::can; if (Foo-can('import')); # BOOM I can provide other examples from my own code, but I think you get the point. The current version on my hard drive allows for import. The module is clever, but it's not clear to me that it's practically useful. Could you provide a real-world example where this would help to prevent or detect a programming error? Your world and my world can be considerably different. Using code very similar to this solved a problem I had with Class::Trait whereby I was exporting methods which should not have been exported. Also, if one is routinely in the habit of checking class capabilities rather than class types, this can be quite useful. Cheers, Ovid -- If this message is a response to a question on a mailing list, please send follow up questions to the list. Web Programming with Perl -- http://users.easystreet.com/ovid/cgi_course/
Re: RFC strict::can
Kurt Starsinic [EMAIL PROTECTED] writes: The module is clever, but it's not clear to me that it's practically useful. I think it could be useful if the new 'can' would only succeed on public methods (note: not private ones, and also not on non-methods). This would require a way to tag subroutines as being private a/o methods. -- Johan
Re: RFC strict::can
On 12/4/05, Ovid [EMAIL PROTECTED] wrote: --- Kurt Starsinic [EMAIL PROTECTED] wrote: package Foo; use Exporter; use strict::can; if (Foo-can('import')); # BOOM I can provide other examples from my own code, but I think you get the point. The current version on my hard drive allows for import. The module is clever, but it's not clear to me that it's practically useful. Could you provide a real-world example where this would help to prevent or detect a programming error? Your world and my world can be considerably different. Using code very similar to this solved a problem I had with Class::Trait whereby I was exporting methods which should not have been exported. Do you mean calling methods which should not have been called? It's not clear to me what, exactly, exporting methods means. Also, if one is routinely in the habit of checking class capabilities rather than class types, this can be quite useful. It's clear that you're interested in addressing issues with checking class capabilities. What I'm not quite following is the basis of your premise, as I understand it: that imported functions are, in general, not meant to called as methods (with an undocumented exception made for import). What I'm asking for, if you're interested in feedback, is an example of a situation where youvre imported a function into a class, from other code you've called can() on said class before invoking a method call, it did The Wrong Thing, and you posit that all of the above doesn't reflect a bug in the class that did the importing. You *are* suggesting making this a pragma under the very well-known strict namespace and putting it on CPAN, so I'm expressing my personal concern that it may not be as generally useful and safe as the nomenclature might suggest. - Kurt