From paul.w.bennett at gmail.com Tue Dec 1 13:53:00 2009 From: paul.w.bennett at gmail.com (Paul Bennett) Date: Tue, 01 Dec 2009 16:53:00 -0500 Subject: [Raleigh-talk] Messing around with symbol tables Message-ID: Suppose I have a module. That module takes objects with a cmp() method (which behaves like the cmp or <=> operators), and deals with objects in a sort order based on the results of $object1->cmp($object2). The objects that it deals with also have a clone() method, which creates another object with the same contents. I do not have, nor can I have, any other assumptions about the objects being dealt with. Of course, to add to the fun, the sorting is done piecemeal and on-demand rather than with the "sort" keyword, and more to the point, also by somebody else's code (whose API requires the method be named exactly "cmp()"). Suppose I have the following utility module, which is supposed to help me handle those objects in both forward-sorting and reverse-sorting orders. The idea is that the "antiobject" of $foo is identical in all respects to $foo (with a reversible transformation of the class name), except a list of antiobjects sorts in reverse order ... package Antiobject; use strict; use warnings; use Carp qw( confess ); use Export qw( import ); use Scalar::Util qw( blessed ); our @EXPORT = qw( antiobject ); sub antiobject { my $object = shift; my $orig = blessed($object) or confess('Not a blessed object'); confess('Object cannot cmp()') unless UNIVERSAL::can($orig, 'cmp'); confess('Object cannot clone()') unless UNIVERSAL::can($orig, 'clone'); my $new = $orig . '::anticlass'; { no strict qw( refs ); if (!keys %{$new.'::'}) { %{$new.'::'} = %{$orig.'::'}; ${$new.'::'}->{'cmp'} = sub { -(${$orig.'::'}->{'cmp'}->(@_)) }; } } return bless $object->clone() => $new; } 1; __END__ This is 100% untested, but I fear in advance that it may be breaking a few laws of Perl and/or nature, or at the very least be working on a dangerously wrong understanding of the nature and temperament of the Perl symbol table. I just don't have enough of the rest of the code together to be able to write meaningful test cases for it yet -- I'm kinda writing the rest of it on the assumption that I'll end up with *some* kind of antiobject or similar construct that I can plug in to my algorithms as needed. Anything I should be aware of (aside from "DON'T PLAY AROUND IN OTHER PEOPLE'S SYMBOL TABLES, YA DUMMY!!!") before I start trying to test & debug it? Most importantly: is there a safer and saner way to go about this that does not rely on foreknowledge of the callers intent or the structure of their objects? Thanks, -- Paul From mpeters at plusthree.com Tue Dec 1 14:04:40 2009 From: mpeters at plusthree.com (Michael Peters) Date: Tue, 01 Dec 2009 17:04:40 -0500 Subject: [Raleigh-talk] Messing around with symbol tables In-Reply-To: References: Message-ID: <4B1592F8.1090204@plusthree.com> On 12/01/2009 04:53 PM, Paul Bennett wrote: > package Antiobject; > > use strict; > use warnings; > > use Carp qw( confess ); > use Export qw( import ); > use Scalar::Util qw( blessed ); > > our @EXPORT = qw( antiobject ); Why export this method? > sub antiobject { > my $object = shift; > my $orig = blessed($object) or confess('Not a blessed object'); > confess('Object cannot cmp()') unless UNIVERSAL::can($orig, 'cmp'); > confess('Object cannot clone()') unless UNIVERSAL::can($orig, 'clone'); You should be calling can() as $orig->can() instead of UNIVERSAL::can(). > my $new = $orig . '::anticlass'; The intent of this isn't perfectly clear. You're creating a new class (or blessing the object into a new class) so I'd probably do something like: my $new_class = ref $orig . '::anticlass'; > { > no strict qw( refs ); > if (!keys %{$new.'::'}) { > %{$new.'::'} = %{$orig.'::'}; > ${$new.'::'}->{'cmp'} = sub { -(${$orig.'::'}->{'cmp'}->(@_)) }; > } > } > return bless $object->clone() => $new; > } I can't see anything immediately wrong with this as long as you document what you're trying to do and wrap it up in a class it should be fine. > Anything I should be aware of (aside from "DON'T PLAY AROUND IN OTHER > PEOPLE'S SYMBOL TABLES, YA DUMMY!!!") before I start trying to test & > debug it? You're not really playing around with some other symbol table (monkey patching), you're messing around with your own. Perl symbol tables are mutable for a reason, just don't abuse it. But a different (and perhaps cleaner) strategy would be too look at something like Moose and Roles. So you clone an object and then apply the "ReverseCmp" role to it - http://search.cpan.org/~flora/Moose-0.93/lib/Moose/Manual/Roles.pod#APPLYING_ROLES > Most importantly: is there a safer and saner way to go about this that > does not rely on foreknowledge of the callers intent or the structure of > their objects? I don't think you're assuming too much about the objects. The only assumptions I can see are that they are blessed objects that have a cmp() and clone() method. That's pretty simple IMO. But a different (and perhaps cleaner) strategy would be too look at something like Moose and Roles. So you clone an object and then apply the "ReverseCmp" role to it - http://search.cpan.org/~flora/Moose-0.93/lib/Moose/Manual/Roles.pod#APPLYING_ROLES I don't know if this approach would work though with objects that aren't Moose based and it seems you can't really modify the code of the objects that you're using. But maybe you can get some ideas from their code. -- Michael Peters Plus Three, LP From paul.w.bennett at gmail.com Wed Dec 2 09:05:54 2009 From: paul.w.bennett at gmail.com (Paul Bennett) Date: Wed, 02 Dec 2009 12:05:54 -0500 Subject: [Raleigh-talk] Messing around with symbol tables In-Reply-To: <4B1592F8.1090204@plusthree.com> References: <4B1592F8.1090204@plusthree.com> Message-ID: On Tue, 01 Dec 2009 17:04:40 -0500, Michael Peters wrote: > On 12/01/2009 04:53 PM, Paul Bennett wrote: > >> our @EXPORT = qw( antiobject ); > > Why export this method? For my own convenience. Maybe it should go in @EXPORT_OK, but I tend to feel that if you've got a package Foo that exists solely to provide foo(), it ought to export foo() by default. I'm not inflexible on this, though -- it's more of a gut thing (I suppose largely inspired by IO::All, among others). >> confess('Object cannot cmp()') unless UNIVERSAL::can($orig, 'cmp'); >> confess('Object cannot clone()') unless UNIVERSAL::can($orig, 'clone'); > > You should be calling can() as $orig->can() instead of UNIVERSAL::can(). I disagree. What if "$orig"::can() is overriden with something utterly unlike capability testing? It would be outside what I consider safe, sane, and consensual, but not implausible. >> my $new = $orig . '::anticlass'; > > The intent of this isn't perfectly clear. You're creating a new class > (or blessing the object into a new class) so I'd probably do something > like: > > my $new_class = ref $orig . '::anticlass'; I agree. I could have used a better variable name, and probably will. I could and should also check for /::anticlass$/ and get rid of it instead of building a potentially infinite chain of the things. On a side note, blessed($object) returns the blessed class name as a string (or undef if not blessed), so ref(blessed($object)) would be wrong. > But a different (and perhaps cleaner) strategy would be too look at > something like Moose and Roles. So you clone an object and then apply > the "ReverseCmp" role to it - > http://search.cpan.org/~flora/Moose-0.93/lib/Moose/Manual/Roles.pod#APPLYING_ROLES > > I don't know if this approach would work though with objects that aren't > Moose based and it seems you can't really modify the code of the objects > that you're using. But maybe you can get some ideas from their code. In my experience, Moose plays well with others right up until you want to do something too deeply Moosey. I'll see if I can give it a whirl, though. It could definitely add clarity. Thanks for your help, -- Paul From mpeters at plusthree.com Wed Dec 2 09:13:28 2009 From: mpeters at plusthree.com (Michael Peters) Date: Wed, 02 Dec 2009 12:13:28 -0500 Subject: [Raleigh-talk] Messing around with symbol tables In-Reply-To: References: <4B1592F8.1090204@plusthree.com> Message-ID: <4B16A038.4060705@plusthree.com> On 12/02/2009 12:05 PM, Paul Bennett wrote: >>> confess('Object cannot cmp()') unless UNIVERSAL::can($orig, 'cmp'); >>> confess('Object cannot clone()') unless UNIVERSAL::can($orig, 'clone'); >> >> You should be calling can() as $orig->can() instead of UNIVERSAL::can(). > > I disagree. What if "$orig"::can() is overriden with something utterly > unlike capability testing? It would be outside what I consider safe, > sane, and consensual, but not implausible. The alternative is that if a module purposefully overrides can() so that it behaves well (like for instance it has an AUTOLOAD method that can dispatch cmp and clone) then your usage would fail. So the module author tried to do the right thing but now it won't work because you ignored it. -- Michael Peters Plus Three, LP From paul.w.bennett at gmail.com Thu Dec 3 07:00:34 2009 From: paul.w.bennett at gmail.com (Paul Bennett) Date: Thu, 03 Dec 2009 10:00:34 -0500 Subject: [Raleigh-talk] Messing around with symbol tables In-Reply-To: <4B16A038.4060705@plusthree.com> References: <4B1592F8.1090204@plusthree.com> <4B16A038.4060705@plusthree.com> Message-ID: On Wed, 02 Dec 2009 12:13:28 -0500, Michael Peters wrote: > On 12/02/2009 12:05 PM, Paul Bennett wrote: >> I disagree. What if "$orig"::can() is overriden with something utterly >> unlike capability testing? It would be outside what I consider safe, >> sane, and consensual, but not implausible. > > The alternative is that if a module purposefully overrides can() so that > it behaves well (like for instance it has an AUTOLOAD method that can > dispatch cmp and clone) then your usage would fail. So the module author > tried to do the right thing but now it won't work because you ignored it. You make a(n infuriatingly ;-) good point. I thought UNIVERSAL::can() was smart enough to check AUTOLOAD(), but it's certainly not going to check AUTOMETHOD() in Class::Std classes (for just one particularly close-to-home trivial example). I don't see a PBP for capability checking (maybe I'm just not looking hard enough), so if anyone's got any ideas about what recommendations are out there, I'd love to hear about them. For now, I'm checking (UNIVERSAL::can() || $orig->can()), but that makes me uneasy on some hard-to-define gut level. Thanks, -- Paul From bradoaks at gmail.com Fri Dec 11 13:41:16 2009 From: bradoaks at gmail.com (Brad Oaks) Date: Fri, 11 Dec 2009 16:41:16 -0500 Subject: [Raleigh-talk] issue with one of Smolder's dependencies Message-ID: This tid bit went across the irc channel yesterday. I'm passing this along mostly so that I'll remember it later. 18:07 <@qqx> So, I think I've got all of the dependencies for Smolder installed, but the build script isn't finding the version for Net::Server::PreFork. 18:08 <@mpeters> yeah, that's a problem with the way N::S::PF reports it's version 18:08 <@mpeters> you can try force installing smolder 18:08 <@mpeters> or removing the version specific part in Build.PL From bradoaks at gmail.com Fri Dec 11 15:30:02 2009 From: bradoaks at gmail.com (Brad Oaks) Date: Fri, 11 Dec 2009 18:30:02 -0500 Subject: [Raleigh-talk] issue with one of Smolder's dependencies In-Reply-To: References: Message-ID: This change has been made to the Build.PL file: http://github.com/mpeters/smolder/commit/f1a0f9dff834d27d23d48f455ad1376532e8305f On Fri, Dec 11, 2009 at 4:41 PM, Brad Oaks wrote: > This tid bit went across the irc channel yesterday. ?I'm passing this > along mostly so that I'll remember it later. > > 18:07 <@qqx> So, I think I've got all of the dependencies for Smolder > installed, but the build script isn't finding the version for > Net::Server::PreFork. > 18:08 <@mpeters> yeah, that's a problem with the way N::S::PF reports > it's version > 18:08 <@mpeters> you can try force installing smolder > 18:08 <@mpeters> or removing the version specific part in Build.PL > From robertfwest at gmail.com Wed Dec 16 08:47:30 2009 From: robertfwest at gmail.com (Rob West) Date: Wed, 16 Dec 2009 11:47:30 -0500 Subject: [Raleigh-talk] Bill Cowan's talk about Exceptions Message-ID: Does anyone have the slides from Bill's talk last August? Thanks, Rob -------------- next part -------------- An HTML attachment was scrubbed... URL: From cowanb at mindspring.com Wed Dec 16 09:05:32 2009 From: cowanb at mindspring.com (Bill Cowan) Date: Wed, 16 Dec 2009 12:05:32 -0500 Subject: [Raleigh-talk] Bill Cowan's talk about Exceptions In-Reply-To: References: Message-ID: <4B29135C.8030000@mindspring.com> An HTML attachment was scrubbed... URL: From robertfwest at gmail.com Wed Dec 16 10:57:37 2009 From: robertfwest at gmail.com (Rob West) Date: Wed, 16 Dec 2009 13:57:37 -0500 Subject: [Raleigh-talk] Bill Cowan's talk about Exceptions In-Reply-To: <4B29135C.8030000@mindspring.com> References: <4B29135C.8030000@mindspring.com> Message-ID: Cool, thanks Bill! On Wed, Dec 16, 2009 at 12:05 PM, Bill Cowan wrote: > Let me dig around to see what I still have. > > Bill > > Rob West wrote: > > Does anyone have the slides from Bill's talk last August? > > Thanks, > Rob > > ------------------------------ > > _______________________________________________ > Raleigh-talk mailing listRaleigh-talk at pm.orghttp://mail.pm.org/mailman/listinfo/raleigh-talk > > > -- > -- Bill > ----------------------------------------------------------------------- > Bill Cowan > Email: cowanb at mindspring.com > Phone: 919.210.4910 > > > _______________________________________________ > Raleigh-talk mailing list > Raleigh-talk at pm.org > http://mail.pm.org/mailman/listinfo/raleigh-talk > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cowanb at mindspring.com Wed Dec 16 09:42:43 2009 From: cowanb at mindspring.com (Bill Cowan) Date: Wed, 16 Dec 2009 12:42:43 -0500 Subject: [Raleigh-talk] Bill Cowan's talk about Exceptions In-Reply-To: <4B29135C.8030000@mindspring.com> References: <4B29135C.8030000@mindspring.com> Message-ID: <4B291C13.3060305@mindspring.com> An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: Perl Monger Aug 2008.zip Type: application/x-zip-compressed Size: 43520 bytes Desc: not available URL: