Re: handler($$) unreliability

2003-06-16 Thread Matthew Pressly
On Sun, Jun 15, 2003 at 02:44:02PM +0800, Philippe M. Chiasson wrote:
[...]
 This could be related to a recently discovered bug in
 mp_preload_module(), see
 http://marc.theaimsgroup.com/?t=10553271073r=1w=2
 for the original report.
 

That is a possiblity.  I am preloading Project::Control,
but I am not preloading other modules that inherit from
it.  I am also using Apache::Reload, if that matters.  

Below is how Project::Control is setup, which
is the module/handler that most commonly exhibits the
problem.  Project::Control is a dispatcher that loads 
(require-s) a module based on a URI to module name 
mapping hash, then calls the run method in that 
package.  The require-d module is always a subclass 
of Project::Control.pm.  The failure becomes apparent
when the $apache-status call is made because 
$apache is not an object in the failing case.

Again, this module almost always works.  It usually
only begins failing after apache has been running
for several hours, and seems to be more common under
heavy load.

*** http.conf ***:

  Files *.pcm
SetHandler perl-script
PerlModule Project::Control
PerlHandler Project::Control
  /Files

*** library/Project/Control.pm ***:

  package Project::Control;
  use Apache();
  use Apache::Constants qw(:common :response REDIRECT SERVER_ERROR);
  use Apache::Reload;
  use Class::MethodMaker
get_set = [ qw( apache ... ) ], 
new_hash_init = '_create';


  ...

  use vars qw/%URI_MAP/;
  %URI_MAP = (
'/uri/one' = 'Project::Control::HandleUriOne',
... for different URIs 
  );
  sub handler ($$) = {
my ($class, $apache) = @_;
Apache::request($apache);
$apache-status(200); # sets default *** Failure occurs here
...
my $self = $class-_create(apache = $apache, ...);
(my $uri = $apache-uri) =~ s/\.[^\.]+$//;
my $module = $URI_MAP{$uri} or Carp::confess(Page [$uri] not installed);
(my $path = $module) =~ s!::!/!g;
$path .= .pm;
bless $self, $module;
  
eval {
  require $path;
  $self-run( $apache );
};

...

return OK;
  }
  
  1;

*** library/Project/HandleUriOne ***:

  package Project::HandleUriOne;
  ...
  use Apache::Reload;
  use base qw( Project::Control );

  sub run {
my $self = shift;
... code to generate output goes here ...
  }

  1;


  [Fri Jun 13 06:00:06 2003] [error] Can't call method status on an undefin=
  ed
  +value at Project/Control.pm line 116.
 
 Does this happen only once per child, or does the affected child behaves
 like that for each and every request to that handler?

It seems to happen for every request that the affected
child handles.  I don't have a test case that exercises
the problem, so I don't have real solid data on the behavior,
but it seems like once a child begins exhibiting this
erroneous behavior, it continues to do so for the rest of
its lifetime.  I am not sure whether it exhibits this
behavior from the time it is created or starts doing that
later after having successfully served other requests.

Any suggestions as to how to contruct a test case so that
I can make this problem be repeatable would be greatly
appreciated.

 One thing that can fix this problem, if it's indeed caused by
 mp_preload_module, would be to make sure to preload that module
 with a PerlModule My::Class in your httpd.conf
 

I am preloading Project::Control, which I think would be
sufficient, but am not preloading the subclass modules that
it uses. I am not sure whether that matters or not.  
sub handler is never overridden in the subclasses. 

Thanks for your help.

--
Matthew Pressly

 




handler($$) unreliability

2003-06-13 Thread Matthew Pressly
I have handler that looks like this:

sub handler ($$) {
  my ($class, $apache) =3D @_;
  Apache::request($apache);
  $apache-status(200); # Default

  #.
}

The vast majority of the time, this works fine.  Every now
and then, usually after the apache server has been up
for a while, and usually under substantial load,
it appears that the handler in one child process starts
being called as if it did not have the prototype.
That is, $apache ($r) is in $_[0] instead of $_[1],
and I get messages like this:

[Fri Jun 13 06:00:06 2003] [error] Can't call method status on an undefin=
ed
+value at Project/Control.pm line 116.

And things quit working because $apache is not set properly.

A server restart clears this up.  This is a perl5.6.0
DSO build of mod_perl/apache (1.27), but I am fairly certain I
have also seen this occur on a static mod_perl/apache.

Any ideas on what causes this or a good way to track it down?

--
Matthew Pressly




[SOT] Strange browser behavior

2002-11-21 Thread Matthew Pressly
I am using a mod_perl content handler to implement
a series of forms.  The first request from a particular browser 
is always a GET that provides some required parameters in the
URL.  From then on, all parameters are passed as hidden form
variables, and only POSTs should occur.

If the browser accepts cookies, a unique session ID is stored
in a long lived cookie and is also logged in the access log,
strictly for tracking (no session data associated with it).
This is not 100% reliable because not everyone accepts cookies,
but it works enough of the time that I can track most of the
requests by this ID.

99.9% (roughly) of the time, everything works fine and the 
correct sequence is followed:
GET /formseries?a=123b=234
POST /formseries   (a=123, b=234 passed in post vars)
POST /formseries   (a=123, b=234 passed in post vars)
POST /formseries   (a=123, b=234 passed in post vars)
POST /formseries   (a=123, b=234 passed in post vars)
POST /formseries   (a=123, b=234 passed in post vars)

The problem is that there are a few request trails per day,
where the following sequence is followed instead:
GET /formseries?a=123b=234
POST /formseries(a=123, b=234 passed in post vars)
POST /formseries(a=123, b=234 passed in post vars)
POST /formseries(a=123, b=234 passed in post vars)
GET /formseries (required parameters not passed on this request)

The GET fails because the handler does not have the required
parameters it needs to pull info from the database.

An incomplete of user agents that the problem occurs with are:
  Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt)
  Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
  Mozilla/4.0 (compatible; MSIE 5.5; Windows 98; Win 9x 4.90)

One other piece of evidence is that the Referer is empty
on the erroneous GET request.

I have tried but been unable to reproduce the failing
request sequence using IE, even using back, forward, and reload
button in a number of sequences.

My questions are, is there some IE anomaly or some anomalous way
of configuring or using IE that can cause it to all of a sudden
do a GET instead of a POST (anything short of manually entering
the url)?  Could a proxy be causing the problem (a small subset
of the failing requests to seem to be coming through proxies)?
  
Also, is there anything more I could track that would give
more insight into the problem?  Currently the content handler
does detect that the required parms are missing and then dumps
the complete request and timestamp into the error log.

Also, please let me know if there is a more appropriate forum
to ask this question.

--
Matthew Pressly






Re: [SOT] Strange browser behavior

2002-11-21 Thread Matthew Pressly
On Thu, Nov 21, 2002 at 02:32:41PM -0500, Perrin Harkins wrote:
 Nick Challoner wrote:
 
 My questions are, is there some IE anomaly or some anomalous way
 of configuring or using IE that can cause it to all of a sudden
 do a GET instead of a POST (anything short of manually entering
 the url)?
 
 
 User bookmarking the page (well, adding to favourites considering we're
 talking about IE) and then returning to it via the bookmark?
 
 
 It may also no longer send POST data or give the option of no longer 
 sending it if you go back to a page resulting from a POST after a 
 certain amount of time.
 
 - Perrin

In looking at these replies and going back through the logs 
more, I think there are multiple failure mechanisms rather than
a single one.  Both the cases above may be ocurring to some degree.
A segment looks like it may also be caused by proxies.  Browser
caching may also be causing some of it, and there may be other
causes as well.  Setting $r-no_cache(1) did not solve the problem,
though there is a chance it may have alleviated it somewhat..

Since there is a session id generated for browsers that have
cookies enabled, I'm planning to stow away the parameters 
in either the database or File::Cache on the first GET
request when parameters are available, then fall back to
looking there on subsequent requests if and only if the
parameters are missing (not in query string and not in POST
data).  This should fix most of the currently
failing cases without much more code.

Thank you all for your help.

--
Matthew Pressly





Module dependency testing question

2002-08-20 Thread Matthew Pressly

If module A depends on module B (uses methods or subroutines from module 
B), is there a good way to test that module A loads module B (i.e. has a 
use statement)?  I frequently run into the following scenario:

1. Write one or more new modules plus a handler that uses them.
2. One or more of those modules is dependent on other existing modules.
3. One of those modules is missing a use statement for one of the 
existing modules that it makes method/sub calls to.
4. The handler works in the development environment because some other 
handler loaded that module previously in response to a previous http 
request. (The brunt of the handler code is require-ed on demand currently).
5. Promote code from development server to production server.
6. Restart apache on production server.
7. Handler fails on production server in response to an access that 
exercises the section of code where the missing use was needed 
(i.e.subroutine or method call to module that wasn't loaded).

--
Matthew Pressly




DBI handle management in modules

2002-07-25 Thread Matthew Pressly

I have a number of perl modules that manage their own persistence
to a SQL database via DBI.  I discovered a flaw in my current
approach which was to use an Apache::Singleton::Process
object to create a connection and in modules that needed a
connection, store the connection in a lexically scoped variable
near the top of the module.  The problem I found with this approach
is that I am essentially caching the database connections at module
load time, so if the database connection goes away (which it does
from time to time because of things like the database server getting
restarted), the now broken connection continues to be used.

The code (after quite a bit of distillation) looks basically like:

package MyPersistentObject;
use strict; use warnings;
use MyProject::Dbh;
my $dbh = MyProject::Dbh-instance-dbh;  ###

sub method1 {
   my ($self, $id) = @_;
   $dbh-do(qq[delete from table1 where id=?], undef, $id);
}
#...

package MyProject::Dbh;
use strict; use warnings;
use Apache::Singleton::Process;
use base (Apache::Singleton::Process);
sub _new_instance {
   return DBI-connect($dsn, $user, $pass, {RaiseError = 1});
}

-
httpd.conf has:
Perlrequire /pathgoeshere/startup.perl

and starutp.perl has:
use Apache::DBI;


What I'm basically trying to accomplish is:
1) Make database connection in one place in the code.
2) Not have to pass $dbh all over the place, but instead have modules
that need a database connection get it themselves.
3) Connection only needs to happen once per request.  If the connection
dies during a request, the next query using that request should fail, and
the next request serviced by that child process should get a new connection.
4) I don't want to call 'connect' before every query because the overhead
is too high, even when Apache::DBI returns a pooled connection.
5) For one request, only one connection should be used (i.e, the
connection should be a request singleton).
6) Modules that require DBI connections should not be dependent on
a mod_perl environment.  I.e. they should also be usable in command line
scripts.

What I have come up with so far is to rewrite the connection handling as 
follows,
which also seems to remove the need for Apache::DBI:

package MyProject::DbhSingleton;
use Apache::Singleton::Request;
use base (qw Apache::Singleton::Request);
sub _new_instance {
my $dbh = DBI-connect($dsn, $user, $pass, $attr) or die DBI-errstr;
}

The thing I'm not sure about is when should I be calling this to
get a local copy of $dbh in a module.  I know that calling it only
at module use time is not frequent enough, and calling it before
every query is too frequent (too expensive), but I'm not sure of a
happy medium.  For some objects, calling
MyProject::DbhSingleton-instance to
store a dbh as a instance data would suffice, but not in all cases.

I've looked through the guide and done a number of web searches
but have not found anything that directly addresses this.  Any help
would be greatly appreciated

--
[EMAIL PROTECTED]




Storable and Class::MethodMaker under mod_perl

2002-04-11 Thread Matthew Pressly

I ran into a strange inconsistency in interaction between Storable and 
Class::MethodMaker between a development and production server that are both running 
builds of perl, mod_perl, and apache from the same source files.  On the development 
server, the following code executes without error, on the production server it gives a 
fatal error because the Class::MethodMaker list accessor sees itself being called in 
array context and returns an array rather than an array reference.  The scalar appears 
to be called in scalar context on the working system.  Has anyone else seen this type 
of anomaly?

I think the correct behavior is actually the failing case that I get on the production 
server.  If I run the code from the command line on the development machine (using the 
perl interpreter from the same build), I get a fatal error with the 'not a reference' 
method on the Storable::freeze line.

I am using Class::MethodMaker version 1.05 and Storable version 1.014 on both machines.

package PackageName;
 use Class::MethodMaker
 list = [ qw( panel_list ) ], ...,
;

#-
sub _insert {
...
use Storable;
my $s = Storable::freeze( $self-panel_list );  # Fails on this line, saying 'not a 
reference'
}

The development box (on which the code works) has the following configuration:

Summary of my perl5 (revision 5.0 version 6 subversion 1) configuration:
  Platform:
osname=linux, osvers=2.4.10-4gb, archname=i686-linux
uname='linux garnet 2.4.10-4gb #1 fri sep 28 17:20:21 gmt 2001 i686 unknown '
config_args=''
hint=recommended, useposix=true, d_sigaction=define
usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
useperlio=undef d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
  Compiler:
cc='cc', ccflags ='-fno-strict-aliasing -D_LARGEFILE_SOURCE 
-D_FILE_OFFSET_BITS=64',
optimize='-O2',
cppflags='-fno-strict-aliasing'
ccversion='', gccversion='2.95.3 20010315 (SuSE)', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=4, usemymalloc=n, prototype=define
  Linker and Libraries:
ld='cc', ldflags =''
libpth=/lib /usr/lib
libs=-lnsl -lndbm -lgdbm -ldb -ldl -lm -lc -lcrypt -lutil
perllibs=-lnsl -ldl -lm -lc -lcrypt -lutil
libc=, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
cccdlflags='-fpic', lddlflags='-shared'

The production server has the following configuration:
Summary of my perl5 (revision 5.0 version 6 subversion 1) configuration:
  Platform:
osname=linux, osvers=2.4.0-64gb-smp, archname=i686-linux
uname='linux eqr002 2.4.0-64gb-smp #1 smp wed jan 24 15:52:30 gmt 2001 i686 
unknown '
config_args=''
hint=recommended, useposix=true, d_sigaction=define
usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
useperlio=undef d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
  Compiler:
cc='cc', ccflags ='-fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE 
-D_FILE_OFFSET_BITS=64',
optimize='-O2',
cppflags='-fno-strict-aliasing -I/usr/local/include'
ccversion='', gccversion='2.95.2 19991024 (release)', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=4, usemymalloc=n, prototype=define
  Linker and Libraries:
ld='cc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lnsl -lndbm -lgdbm -ldb -ldl -lm -lc -lcrypt -lutil
perllibs=-lnsl -ldl -lm -lc -lcrypt -lutil
libc=, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'




Matthew Pressly




Re: mod_perl framework + code reuse question

2002-01-11 Thread Matthew Pressly

At 01:48 PM 1/10/2002 -0500, Perrin Harkins wrote:

You can actually use subroutines without fear!  Also, reducing the amount of
magic (i.e. all of that package generation and eval stuff that Registry
does) can help clear up confusion.  And you can use __END__ and __DATA__.

Good point.

I started writing a handler and have something basically working.  It's still pretty 
barebones, but I'm happy with it so far, and performance is good.  It require-s the 
appropriate page module based on $r-filename, $r-path_info, and $r-document_root 
then calls that module's run method as a class method (both steps wrapped in 
separate evals).  Apache::Reload is reloading both handler module and page module as 
needed.

For file organization, I'm thinking of making all page modules start with a common 
namespace substring (e.g. Projectname::Page) to distinguish them from the support 
(model) modules for that site and moving them into the same directory tree that 
contains those support modules, then moving templates (currently in ./tt/*.tpl files 
relative to *.par scripts) into either that directory tree alongside the modules they 
are used by or into an entirely separate tree that only contains templates.  The 
latter is probably better for sites that have some division of labor between coders 
and HTML designers, but that's not the case on this one.

Thank you for all the help.

Matthew Pressly




Apache::Reload question

2002-01-10 Thread Matthew Pressly

Can Apache::Reload be used to reload modules that are use-d by httpd PerlModule, 
PerlRequire, or PerlHandler directives, or do they have to be explicitly use-d in 
code that is inside a handler? I think the answer is yes - these are no different 
than anything else except that memory sharing is lost because reload occurs in the 
children but wanted to check before I go down that path.

Matthew Pressly




Re: mod_perl framework + code reuse question

2002-01-10 Thread Matthew Pressly

At 09:09 PM 1/9/2002 -0500, Perrin Harkins wrote:

Normal Perl rules apply.  Modules are good for sharing code.  You could
stuff the shared parts into a sub in a module that every script would
call.  Or you could use an OO approach, with a base class that holds all
of the boiler-plate stuff.

The question I'm having a hard time answering without going down both paths is:

What are the basic advantages, disadvantages, and limitations of:
(a) stuffing all this setup/framework code into a module (either a new module or 
subclassing Apache::RegistryNG as you mention below),
versus, 
 (b) stuffing it into a handler that all requests for a large subset of the pages on 
this site have to go?

Both approaches achieve the same result of funnelling all requests through a common 
set of code, which is mainly what I'm trying to achieve, but other than being 
different implementations, I'm not real clear on how they differ.  

It would seem like the  put framework in a module approach might be more flexible 
(esp. subclassing Apache::RegistryNG) because different scripts could 
take-it-or-leave-it or even modify it through further subclassing.

On the other hand, then common framwork in a handler approach might be faster 
because it could do just what is needed by all pages but nothing more, and as long as 
there is not too much code wasted by differences in the needs of different scripts, it 
could be that less code is being loaded and executed.

Am I missing other things here?

 One idea I had was to write a handler that acts as a sort of minimal
 application framework that contains the code below and determines what
perl
 module should be required and executed based on $apache-path_info
and
 $apache-uri.

That's a good way to go too.  Moving from Apache::Registry to handlers
can be empowering.


Other than the speedup from reduced overhead, what are the primary advantages to using 
handlers rather than Apache::Registry for content handlers?  The primary disadvantage 
seems to be that I have to restart httpd an awful lot, but maybe Apache::Reload can 
help here.  Can it be used to reload modules that implement handlers?

 This sounds like a substantial effort

Only if your code currently depends on the CGI emulation features of
Apache::Registry.  If it's clean code, you should be able to convert it
without much trouble.  You could also try subclassing Apache::RegistryNG
and adding your setup code to the beginning of each request there.

I will look into subclassing Apache::RegistryNG.  This could be useful for other 
things as well.

Maybe this is easier than what I'm picturing.  I was thinking that writing the handler 
would be most of the effort, but it may be that it is mostly just designing an 
appropriate interface between the handler and the page code, re-partitioning the 
common code out of the pages and into the handler, and writing a simple dispatcher.  
Probably the biggest piece is the careful interface design so that future framework 
enhancements don't require changing old page code.

 I'd appreciate any input on how other people are structuring similar
type
 applications in mod_perl, where the output is generated by Template
Toolkit
 based on data obtained via SQL queries using parameters received
mostly in
 the URL.

I use handlers, with a model-view-controller design.  The approach is
documented in my Perl.com article about the eToys design.  I keep all
the common setup stuff in a base class that the other controllers
inherit from.

This is a very helpful article.  I have read it several times and still keep coming 
back to it.  I would also like to learn more about the model-view-controller 
approach in general.


- Perrin

Matthew Pressly




mod_perl framework + code reuse question

2002-01-09 Thread Matthew Pressly

Background: 
I'm working on a site that is a mix of php (which I'm gradually converting to 
mod_perl) and mod_perl (running under Apache::Registry and using Template Toolkit 
(TT2)) using an apache configuration like this:

Directory /
[...]
Files *.par
  SetHandler  perl-script
  PerlHandler Apache::Registry
  Options ExecCGI
  PerlSendHeader On
/Files
/Directory

I took the Files approach because, at the time, it seemed like the easiest way to 
have *.php and *.par files coexist during the conversion.

Problem:
There are many *.par pages (estimate: 70-100 when conversion is complete), and they 
all contain the following code with minor variations that could be made consistent 
(like what constants are imported, what modules are used, etc.).  I'd like to find a 
way to prevent having that code (below) show up over and over again so I can eliminate 
a potential maintenance headache, but I'm not sure of what's a good way to bundle it 
up for reuse.  

One idea I had was to write a handler that acts as a sort of minimal application 
framework that contains the code below and determines what perl module should be 
required and executed based on $apache-path_info and $apache-uri.  This sounds 
like a substantial effort, but would provide a centralized framework where I could add 
features that apply to all pages by only editing code in one place.  Is this a 
reasonable approach?  Are there other simpler approaches?

I'd appreciate any input on how other people are structuring similar type applications 
in mod_perl, where the output is generated by Template Toolkit based on data obtained 
via SQL queries using parameters received mostly in the URL.

#--- BEGIN SAMPLE PAGE testpage.par ---

#!/usr/local/bin/perl -wT
#
BEGIN {
  require $MyCompany::Basepath-{sitename}/MyCompany/ProjectName/Config/Startup.pl;
}

use Apache ();
use Apache::Constants qw(:common SERVER_ERROR REDIRECT);
use Apache::DBI;
use strict;

our $apache = Apache-request;
### I realize that I should be handling header_only requests a little differently, but 
code not updated yet.
$apache-content_type('text/html');
if ($apache-header_only) {
  $apache-send_http_header;
  return OK;
};
my $parm = {$apache-args, $apache-content};
my $dbi = $MyCompany::ProjectName::Config::dbi;
my $dbh = DBI-connect($dbi-{dsn}, $dbi-{user}, $dbi-{password},
   {RaiseError = 1});

# template object is built in apache startup.perl file (before fork)
my $out = dispatch($apache, $parm, $dbh, $MyCompany::ProjectName::template);
$apache-send_http_header;
print $out;
return OK;

sub dispatch {
my ($apache, $parm, $dbh, $tpl) = @_;
my $template_data;
 ### [... fill $template_data with something meaningful here ...] ###

  my $output = ;
  $tpl-process('viewsurveyusers.tpl', $template_data, \$output)
or die Error processing template: .$tpl-error;
  return $output;

}
#--- END SAMPLE PAGE testpage.par ---

Relevant piece of startup.perl:
# BEGIN ---
use Template;
$MyCompany::ProjectName::template = Template-new(INCLUDE_PATH = tt,
  PRE_PROCESS = config.tpl,
  PRE_CHOMP = 1,
  );
#--- END ---


Matthew Pressly




[OT] Re: Form Reading

2002-01-08 Thread Matthew Pressly


At 12:55 PM 1/8/2002 +0100, C.Hauser - IT assistance GmbH wrote:
Hello


This is off topic, thanks for a direct hint to a module or an
appropriate mailing list.

I want to read an HTML form into an hash. But I don't want to use
HTML::Tree or similar DOM Object trees. I need simply all form relevant
information as an hash which is human readable. Example: [... example deleted ...]


There's a thread that looks like the same as what you're asking going on currently on 
the Template Toolkit mailing list under the subject [Templates] Sticky forms with 
hierarchical template vars.  

A list of submissions is available (by subject) at:

http://www.template-toolkit.org/pipermail/templates/2002-January/subject.html

a few of these posts have sample code that transforms the result of a form post back 
into a hierarchical data structure that looks similar to your example.



Matthew Pressly




Problem with exception handler in guide?

2002-01-08 Thread Matthew Pressly

I am trying to get the exception class described in the guide to work, but am having 
trouble with die returning the class incorrectly.

The example in the guide was:
  die My::Exception-RetCode(code = 204);

The module code is at:
http://thingy.kcilink.com/modperlguide/perl/The_My_Exception_class_in_its_e.html
with two modifications (the last die in sub AUTOLOAD was changed to CORE::die to 
prevent a perl warning message about it being ambiguous, and the missing semicolon at 
the end of the first line package ... was added).

The following script code does not work
#-
use My::Exception;
eval {
die My::Exception-Return(code = abc);
};
if ($@) {
use Data::Dumper;
print Dumper($@);
}
#-

It generates the output:
#-
$VAR1 = bless( {
 'text' = 'My::Exception',
 'caller' = {
   'line' = 19,
   'filename' = 'My/Exception.pm',
   'package' = 'My::Exception'
 }
   }, 'My::Exception::UnCaught' );
#-
with the class indicating that the exception was not caught.  Tracing it in the 
debugger shows that it executes My::Exception::die using My::Exception as the first 
argument.

If I put parens around the argument to die, as follows, it works (calls AUTOLOAD first 
then returns result of that as first argument to My::Exception::die), returning the 
correctly classed object.
Code:
#-
use My::Exception;
eval {
die (My::Exception-Return(code = abc));
};
if ($@) {
use Data::Dumper;
print Dumper($@);
}
#-

Output:
#-
$VAR1 = bless( {
 'caller' = {
   'line' = 5,
   'filename' = './exceptions2',
   'package' = 'main'
 },
 'code' = 'abc'
   }, 'My::Exception::Return' );
#-


It appears that - is too low a precedence.  Is there a way around this without 
requiring that parentheses be used around die's arguments? I'm running this under 
perl5.6.0.  Here is output of perl -V:

Summary of my perl5 (revision 5.0 version 6 subversion 0) configuration:
  Platform:
osname=linux, osvers=2.4.0, archname=i586-linux
uname='linux manson 2.4.0 #1 wed aug 2 20:22:26 gmt 2000 i686 unknown '
config_args='-ds -e -Dprefix=/usr -Di_db -Di_dbm -Di_ndbm -Di_gdbm'
hint=recommended, useposix=true, d_sigaction=define
usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
useperlio=undef d_sfio=undef uselargefiles=define 
use64bitint=undef use64bitall=undef uselongdouble=undef usesocks=undef
  Compiler:
cc='cc', optimize='-O2 -pipe', gccversion=2.95.2 19991024 (release)
cppflags='-fno-strict-aliasing -I/usr/local/include'
ccflags ='-fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE 
-D_FILE_OFFSET_BITS=64'
stdchar='char', d_stdstdio=define, usevfork=false
intsize=4, longsize=4, ptrsize=4, doublesize=8
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=4, usemymalloc=n, prototype=define
  Linker and Libraries:
ld='cc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lnsl -ldl -lm -lc -lcrypt
libc=, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'


Characteristics of this binary (from libperl): 
  Compile-time options: USE_LARGE_FILES
  Built under linux
  Compiled at Jan 19 2001 05:42:10
  %ENV:
PERL5LIB=/home/mpressly/development/library
  @INC:
/home/mpressly/development/library
/usr/lib/perl5/5.6.0/i586-linux
/usr/lib/perl5/5.6.0
/usr/lib/perl5/site_perl/5.6.0/i586-linux
/usr/lib/perl5/site_perl/5.6.0
/usr/lib/perl5/site_perl
.


Matthew Pressly