From simon.morris at cmtww.com Mon Jul 3 04:36:12 2006 From: simon.morris at cmtww.com (Simon Morris) Date: Mon, 03 Jul 2006 12:36:12 +0100 Subject: [Fwd: [Gllug] [ANNOUNCE] July Meeting - Trip to Bletchley Park] Message-ID: <1151926573.4266.69.camel@cmt02smorris01.cmtww.com> Hello Milton Keynes M[ou]ngers It is only polite to let you know that 20-odd members of GLLUG are "up your way" this weekend on a trip to Bletchley Park! We would love your company if you are free - mail me offlist for my mobile number if you would like to meet up. Thanks chaps ~sm -------- Forwarded Message -------- > From: Simon Morris > Reply-To: Greater London Linux User Group > To: gllug at gllug.org.uk > Subject: [Gllug] [ANNOUNCE] July Meeting - Trip to Bletchley Park > Date: Mon, 3 Jul 2006 10:48:45 +0100 > > > > Hello, > > This Sunday 9th July there will be a GLLUG expedition to Bletchley > Park. > > Bletchley Park was the centre of the Allied cryptanalysis and code > breaking efforts during the Second World War. The most notable > achievement was the breaking of the German Enigma cipher which is said > to have brought the war to an end 2 years early. > > It was home to a number of famous mathematicians and cryptanalysts > including Alan Turing - the father of modern computer science. > > The GLLUG trip is going to take in the Computer museum from its > origins > with the Colossus, invented during the Second World War to break > Lorenz > codes through the mainframes of the 1960's, mini computers, homebuilt > micros to the PC's of today. There is also a host of wartime exhibits > including vehicles, machinery and a Churchill exhibition to take in. > > On 9th July there is also a Vintage car and motorbike exhibition in > the > park. > > The plan at the moment is for GLLUG members to make their own way to > Bletchley Park, meet for a picnic and visit the attractions. July 9th > is > also the World Cup Final day so it is predicted those who care may > slope > off to a local pub, or race back to London for the 7pm kickoff. > > The cost of the trip will be your travel to the park from Euston > station > plus the entry fee to the park which could be ?8.50 (Internet > booking), > ?10 (on the day) or ?8 (if you register your name with me ASAP) > > We are meeting "under the big tree" at 1230 for a picnic and then > splitting into smaller groups to look at the exhibits, vintage cars, > walk around the park etc. > > So far we have one set of parents, 2 sets of wives and 2 children > attending as well so feel free to bring people along for the day. > > More details from the website http://gllug.org.uk/summer and if you > want > to attend please subscribe to the GLLUG Social mailing list. > > http://lists.gllug.org.uk/mailman/listinfo/social > > Thanks > > ~sm > > -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: This is a digitally signed message part Url : http://mail.pm.org/pipermail/miltonkeynes-pm/attachments/20060703/77947bbe/attachment.bin From tom at eborcom.com Mon Jul 3 14:15:43 2006 From: tom at eborcom.com (Tom Hukins) Date: Mon, 3 Jul 2006 22:15:43 +0100 Subject: Optional Subclass Loading Problem Message-ID: <20060703211543.GA58594@eborcom.com> I'm looking after a large, semi-OOish module that load objects and does things with them. For example: my $thing = Thing->load(id => 7); # Load the thing with ID 7 Code that uses this module then does various actions on the things: $thing->eat; The action varies on the type of thing: sub eat { if ($thing->name eq 'pie') { print "Yummy\n"; } elsif ($thing->name eq 'poison') { die "That tastes funny\n"; } } My first thought on seeing code like this was to break these things out into subclasses for the most common types of thing. So I did that. The code that uses this module often only has an ID: it doesn't know whether that ID represents poison or pie. So it has to call load() on the Thing class, which then needs to rebless the object into the correct subclass. If no subclass exists, the object remains a Thing. I modified the load() method a little: sub load { # all the old code to load the object into $self from its ID my $subclass = 'Thing::'. $self->name; eval "use $subclass"; unless ($@) { bless $self, $subclass; } # old code that does things with $self } I can now add subclasses like Thing::pie and Thing::poison as I get round to it. This works fine until a subclass fails to compile due to the programmer (me) making a mistake while adding new code. The "eval use ..." fails so it seems like methods have suddenly vanished. If the method exists in the Thing superclass, the methods get called with incomplete functionality which confuses the poor programmer. So, can anyone think of a good way I could distinguish between different types of failure I might encounter and an elegant way of dealing with them? I want to ignore "subclass not found errors", as not all types of thing currently (or will ever) have their own subclass. So far, the only other type of error I have encountered is a compilation error, but might I encounter others (eg. file unreadable due to permissions)? As an aside, MiltonKeynes.pm doesn't show up too highly on the YAPC::Europe attendees list yet: http://www.birmingham2006.com/cgi-bin/yapc.pl?act=user-stats Let's get more of us registered, rise up the list and errrm, show everyone how mindlessly competitive we are. Or something. Tom From nik at ngo.org.uk Tue Jul 4 02:53:51 2006 From: nik at ngo.org.uk (Nik Clayton) Date: Tue, 04 Jul 2006 10:53:51 +0100 Subject: Optional Subclass Loading Problem Message-ID: <44AA3AAF.7090107@ngo.org.uk> Tom Hukins wrote: [...] > This works fine until a subclass fails to compile due to the > programmer (me) making a mistake while adding new code. The "eval use > ..." fails so it seems like methods have suddenly vanished. If the > method exists in the Thing superclass, the methods get called with > incomplete functionality which confuses the poor programmer. > > So, can anyone think of a good way I could distinguish between > different types of failure I might encounter and an elegant way of > dealing with them? I want to ignore "subclass not found errors", as > not all types of thing currently (or will ever) have their own > subclass. So far, the only other type of error I have encountered is > a compilation error, but might I encounter others (eg. file unreadable > due to permissions)? It doesn't solve the problem you pose, but could you work around it by having a test that does the equivalent of find . -name \*.pm | xargs perl -c to make sure that all the .pm files compile correctly? That way you could be reasonably certain that if the eval fails it's because there was a problem with the load. Alternatively, create subclasses for everything, even if some of them are no more than: package Thing::foo; use base qw(Thing); 1; Taking a look at "perldoc require" it's got Perl code that claims to be equivalent to require in it, complete with calls to die(). It may be the case that that code also shows all the ways in which require() might fail, in which case you could use that. That's still quite fragile though. Ah, here's a thought. You can check %INC after the use. I've just done a quick test. === t.pl === #!/usr/bin/perl use strict; use warnings; use Data::Dumper; use lib '.'; eval "use Works;"; eval "use Syntax;"; eval "use doesNotExist;"; print Dumper \%INC; === end === === Works.pm === package Works; 1; === end === === Syntax.pm === package Syntax; sob { print "boo hoo\n"; } # Syntax error on this line 1; === end === If you run t.pl you'll see that there are entries for Works.pm and Syntax.pm, indicating that both of those were found (even though Syntax.pm has a syntax error). There's no entry for "doesNotExist.pm", indicating that the file couldn't be found. So workable logic is probably: eval "use $subclass"; if($@) { # Rethrow the error if the module was found but couldn't # be compiled die $@ if exists $INC{$self->name() . 'pm'}; } N From peter at dragonstaff.com Tue Jul 4 04:23:39 2006 From: peter at dragonstaff.com (Peter Edwards) Date: Tue, 4 Jul 2006 12:23:39 +0100 Subject: Optional Subclass Loading Problem In-Reply-To: <44AA3AAF.7090107@ngo.org.uk> Message-ID: <006701c69f5c$4de3f330$6401a8c0@metis> The perl -c and eval or die approaches work quite well for me in development, although if you don't set up the subclass in a BEGIN block you won't know until you try and run the program whether the subclass fails. I have a paged screen list base class that does similar stuff, using a definition file to specify plugin sub-classes, that add extended methods (within the same namespace) loaded on demand, or to specify named coderefs to simple functions. In my init method I do: # load any helper base classes if ( my $hc = $this->{listdef}->{'helperclasses'} ) { for my $module (@$hc) { # check if loaded first? eval "require $module" or sm_Confess "list $this->{listdef_name}: error loading helper class $module: $@"; unshift @ISA, $module; } } Then in call time code: # calculated search using helper functions, may add joins and where clauses if ( my $fn = $listdef->{searchcalc}->{$field} ) { my @arg = ( iv => $this->{iv}, field => $field, value => $val, wherestrptr => \$where, whereptr => \@where, dbptr => $db, dbdef => $dbdef, fromptr => \$from ); if ( $this->can($fn) ) # method name { $this->$fn(@arg); } elsif ( defined &{$fn} ) # function pointer { no strict 'refs'; &{$fn}($this, @arg); use strict 'refs'; } else { sm_Confess "list $this->{listdef_name}: unknown searchcalc function $fn for field $field"; } next; } Thinking about it, I suppose you could write a verify routine that "knows" how to do all the requiring and then inspect @ISA and the respective package hashes to see where method functions are defined and which ones will be called. You could inspect a package for functions with code like this: my $hp = inspect_package("main"); do something with $hp... sub inspect_package { my $package = shift || sm_Confess; my %h = ( functions => [], hashes => [], arrays => [], scalars => [], filehandles => [], packages => [], systemscalars => [], packagescalars => [], objectscalars => [] ); no strict 'refs'; my $tab = \%{$package.'::'}; for (keys %$tab) { my $fullname = join '::', $package, $_; push (@{$h{hashes}}, "\%$fullname") if %$fullname && !($fullname =~ m/::$/); push (@{$h{packages}}, "\%$fullname") if %$fullname && ($fullname =~ m/::$/); push (@{$h{arrays}}, "\@$fullname") if @$fullname; if ( $$fullname ) # scalar pointer { if ( $_ =~ m/^\_\ This works fine until a subclass fails to compile due to the > programmer (me) making a mistake while adding new code. The "eval use > ..." fails so it seems like methods have suddenly vanished. If the > method exists in the Thing superclass, the methods get called with > incomplete functionality which confuses the poor programmer. > > So, can anyone think of a good way I could distinguish between > different types of failure I might encounter and an elegant way of > dealing with them? I want to ignore "subclass not found errors", as > not all types of thing currently (or will ever) have their own > subclass. So far, the only other type of error I have encountered is > a compilation error, but might I encounter others (eg. file unreadable > due to permissions)? It doesn't solve the problem you pose, but could you work around it by having a test that does the equivalent of find . -name \*.pm | xargs perl -c to make sure that all the .pm files compile correctly? That way you could be reasonably certain that if the eval fails it's because there was a problem with the load. Alternatively, create subclasses for everything, even if some of them are no more than: package Thing::foo; use base qw(Thing); 1; Taking a look at "perldoc require" it's got Perl code that claims to be equivalent to require in it, complete with calls to die(). It may be the case that that code also shows all the ways in which require() might fail, in which case you could use that. That's still quite fragile though. Ah, here's a thought. You can check %INC after the use. I've just done a quick test. === t.pl === #!/usr/bin/perl use strict; use warnings; use Data::Dumper; use lib '.'; eval "use Works;"; eval "use Syntax;"; eval "use doesNotExist;"; print Dumper \%INC; === end === === Works.pm === package Works; 1; === end === === Syntax.pm === package Syntax; sob { print "boo hoo\n"; } # Syntax error on this line 1; === end === If you run t.pl you'll see that there are entries for Works.pm and Syntax.pm, indicating that both of those were found (even though Syntax.pm has a syntax error). There's no entry for "doesNotExist.pm", indicating that the file couldn't be found. So workable logic is probably: eval "use $subclass"; if($@) { # Rethrow the error if the module was found but couldn't # be compiled die $@ if exists $INC{$self->name() . 'pm'}; } N _______________________________________________ MiltonKeynes-pm mailing list MiltonKeynes-pm at pm.org http://mail.pm.org/mailman/listinfo/miltonkeynes-pm From peter at dragonstaff.com Tue Jul 4 04:23:39 2006 From: peter at dragonstaff.com (Peter Edwards) Date: Tue, 4 Jul 2006 12:23:39 +0100 Subject: Optional Subclass Loading Problem In-Reply-To: <44AA3AAF.7090107@ngo.org.uk> Message-ID: <006701c69f5c$4de3f330$6401a8c0@metis> The perl -c and eval or die approaches work quite well for me in development, although if you don't set up the subclass in a BEGIN block you won't know until you try and run the program whether the subclass fails. I have a paged screen list base class that does similar stuff, using a definition file to specify plugin sub-classes, that add extended methods (within the same namespace) loaded on demand, or to specify named coderefs to simple functions. In my init method I do: # load any helper base classes if ( my $hc = $this->{listdef}->{'helperclasses'} ) { for my $module (@$hc) { # check if loaded first? eval "require $module" or sm_Confess "list $this->{listdef_name}: error loading helper class $module: $@"; unshift @ISA, $module; } } Then in call time code: # calculated search using helper functions, may add joins and where clauses if ( my $fn = $listdef->{searchcalc}->{$field} ) { my @arg = ( iv => $this->{iv}, field => $field, value => $val, wherestrptr => \$where, whereptr => \@where, dbptr => $db, dbdef => $dbdef, fromptr => \$from ); if ( $this->can($fn) ) # method name { $this->$fn(@arg); } elsif ( defined &{$fn} ) # function pointer { no strict 'refs'; &{$fn}($this, @arg); use strict 'refs'; } else { sm_Confess "list $this->{listdef_name}: unknown searchcalc function $fn for field $field"; } next; } Thinking about it, I suppose you could write a verify routine that "knows" how to do all the requiring and then inspect @ISA and the respective package hashes to see where method functions are defined and which ones will be called. You could inspect a package for functions with code like this: my $hp = inspect_package("main"); do something with $hp... sub inspect_package { my $package = shift || sm_Confess; my %h = ( functions => [], hashes => [], arrays => [], scalars => [], filehandles => [], packages => [], systemscalars => [], packagescalars => [], objectscalars => [] ); no strict 'refs'; my $tab = \%{$package.'::'}; for (keys %$tab) { my $fullname = join '::', $package, $_; push (@{$h{hashes}}, "\%$fullname") if %$fullname && !($fullname =~ m/::$/); push (@{$h{packages}}, "\%$fullname") if %$fullname && ($fullname =~ m/::$/); push (@{$h{arrays}}, "\@$fullname") if @$fullname; if ( $$fullname ) # scalar pointer { if ( $_ =~ m/^\_\ This works fine until a subclass fails to compile due to the > programmer (me) making a mistake while adding new code. The "eval use > ..." fails so it seems like methods have suddenly vanished. If the > method exists in the Thing superclass, the methods get called with > incomplete functionality which confuses the poor programmer. > > So, can anyone think of a good way I could distinguish between > different types of failure I might encounter and an elegant way of > dealing with them? I want to ignore "subclass not found errors", as > not all types of thing currently (or will ever) have their own > subclass. So far, the only other type of error I have encountered is > a compilation error, but might I encounter others (eg. file unreadable > due to permissions)? It doesn't solve the problem you pose, but could you work around it by having a test that does the equivalent of find . -name \*.pm | xargs perl -c to make sure that all the .pm files compile correctly? That way you could be reasonably certain that if the eval fails it's because there was a problem with the load. Alternatively, create subclasses for everything, even if some of them are no more than: package Thing::foo; use base qw(Thing); 1; Taking a look at "perldoc require" it's got Perl code that claims to be equivalent to require in it, complete with calls to die(). It may be the case that that code also shows all the ways in which require() might fail, in which case you could use that. That's still quite fragile though. Ah, here's a thought. You can check %INC after the use. I've just done a quick test. === t.pl === #!/usr/bin/perl use strict; use warnings; use Data::Dumper; use lib '.'; eval "use Works;"; eval "use Syntax;"; eval "use doesNotExist;"; print Dumper \%INC; === end === === Works.pm === package Works; 1; === end === === Syntax.pm === package Syntax; sob { print "boo hoo\n"; } # Syntax error on this line 1; === end === If you run t.pl you'll see that there are entries for Works.pm and Syntax.pm, indicating that both of those were found (even though Syntax.pm has a syntax error). There's no entry for "doesNotExist.pm", indicating that the file couldn't be found. So workable logic is probably: eval "use $subclass"; if($@) { # Rethrow the error if the module was found but couldn't # be compiled die $@ if exists $INC{$self->name() . 'pm'}; } N _______________________________________________ MiltonKeynes-pm mailing list MiltonKeynes-pm at pm.org http://mail.pm.org/mailman/listinfo/miltonkeynes-pm From peter at dragonstaff.com Tue Jul 4 07:09:38 2006 From: peter at dragonstaff.com (Peter Edwards) Date: Tue, 4 Jul 2006 15:09:38 +0100 Subject: YAPC::EU In-Reply-To: <20060703211543.GA58594@eborcom.com> Message-ID: <009c01c69f73$7de31f90$6401a8c0@metis> >As an aside, MiltonKeynes.pm doesn't show up too highly on the >YAPC::Europe attendees list yet: >http://www.birmingham2006.com/cgi-bin/yapc.pl?act=user-stats > >Let's get more of us registered, rise up the list and errrm, show >everyone how mindlessly competitive we are. Or something. I decided I had to go when I saw that one of the talks is about writing an IRC server bot to annoy conference attendees who spend all their time IRCing during talks. There's a kind of referential beauty to that. A 3 day working holiday appeals as well :) See ya there, Peter http://dragonstaff.com From tom at eborcom.com Tue Jul 4 14:24:05 2006 From: tom at eborcom.com (Tom Hukins) Date: Tue, 4 Jul 2006 22:24:05 +0100 Subject: Optional Subclass Loading Problem In-Reply-To: <44AA3AAF.7090107@ngo.org.uk> References: <44AA3AAF.7090107@ngo.org.uk> Message-ID: <20060704212404.GA88403@eborcom.com> On Tue, Jul 04, 2006 at 10:53:51AM +0100, Nik Clayton wrote: > It doesn't solve the problem you pose, but could you work around it > by having a test that does the equivalent of > > find . -name \*.pm | xargs perl -c That's definitely a useful fallback, and something I've been thinking about adding to our test suite along with Test::Strict some time. Eventually. > Ah, here's a thought. You can check %INC after the use. I've just > done a quick test. Those are definitely the droids I'm looking for. Thanks. I suspected that thinking too much about $@ had caused me to miss out on other ideas. Of course, use() just wraps require() and import(). The documentation for require() explains how it populates %INC: http://perldoc.perl.org/functions/require.html So, compilation errors shove undef in $INC{$filename}, whereas non-existent files do "delete $INC{$filename}". The documentation for do() also helped me understand this: http://perldoc.perl.org/functions/do.html Cheers, Happy Tom From tom at eborcom.com Sun Jul 23 01:50:42 2006 From: tom at eborcom.com (Tom Hukins) Date: Sun, 23 Jul 2006 09:50:42 +0100 Subject: Meeting: Tuesday 25th July 2006 Message-ID: <20060723085041.GA19265@eborcom.com> With our current heatwave, what could be better than a nice cool drink with discussion about Perl and other interesting things? How about all of that, with a few visitors from Birmingham.pm and one from Belfast.pm? If that sounds good, join us on Tuesday in Wetherspoon's near the railway station (not the one in the snow dome). I'll show up some time between 7 and 7.30, but feel free to arrive whenever suits you. If you've not been along before and you would like my mobile number to help find us please ask off list. See the Web site for more details: http://miltonkeynes.pm.org/ Finally, don't forget to register for YAPC::Europe in Birmingham: http://www.birmingham2006.com/ As YAPC::Europe coincides with the date for our next meeting (August), we will hold it there. See you soon, Tom