Stas Bekman wrote:
Last night I have done the mod_perl 1.0 to 2.0 porting presentation at the Melbourne mongers meeting, and I have raised the issue with Apache::compat, asking for input from my audience. Here is the problem that we have:

Apache::compat provides mod_perl 1.0 backward compatibility implementation. And everything works just fine as long as the API has a different name. However there is a problem if a certain method has the same name but a totally different functionality. Here is an example:

As explained here:
http://perl.apache.org/docs/2.0/user/porting/compat.html#C__connection_E_gt_remote_addr_



in mod_perl 1.0 you'd say:


  use Socket 'sockaddr_in';
  my ($port, $ip) = sockaddr_in($r->connection->remote_addr);

i.e. $r->connection->remote_addr was returned a packed socket information.

However in mod_perl 2.0 lingo (read: Apache 2.0 lingo), $r->connection->remote_addr returns an APR::SockAddr object (read: an opaque object, to which you need to use methods to access its values). So to accomplish the above you need to do:
require APR::SockAddr;
my $sock_addr = $c->remote_addr;
my ($port, $ip) = ($sock_addr->port_get, $sock_addr->ip_get);


this is a 1:1 mapping to the Apache 2.0 C API.

So if we provide a back-compat implementation in Apache::compat and it gets loaded the real 2.0 API can no longer be used.

What I suggested is that we need some sort of scoped pragmata, so we can say:

{
  use mod_perl::compat;
  my ($port, $ip) = sockaddr_in($r->connection->remote_addr);
}
  my $sock_addr = $c->remote_addr;
  my ($port, $ip) = ($sock_addr->port_get, $sock_addr->ip_get);

so I can use both APIs and enable the back-compatibility functionality only in the needed scope. Of course this doesn't make the porting as simple as enabling Apache::compat, but it solves the API breaking problem. If it was only possible to make the scoping work.

And Scott Penrose, of the melbourne pm's fame sent me these suggestions (posted here with Scott's permission):


-------- Original Message --------
Subject: Two solutions to Apache::compat
Date: Thu, 12 Jun 2003 12:47:28 +1000
From: Scott Penrose <[EMAIL PROTECTED]>
To: Stas Bekman <[EMAIL PROTECTED]>

I have two solutions for your problem you presented yesterday.
Both have side effects but I can work them at least in part (I don't
know all the gotchas with ModPerl though).

1) Filter::Simple

use Apache::compat::uber;

        # or what ever it actually is...
        print STDERR sockdaddr_in($r->localaddr);

no Apache::compat::uber;

print STDERR $r->localaddr->ipnumber;

will get converted to this

print STDERR sockaddr_in($r->localaddr_compat);

print STDERR $r->localaddr->ipnumber;

This has the side effect of having to do a Filter stage which is slower
start up (but not much) and you have to get the regular expression
right, but that won't be hard.

2) Operator Overload

use Apache::compat;

        # or what ever it actually is...
        print STDERR sockdaddr_in($r->localaddr);

print STDERR $r->localaddr->ipnumber;

$r->localaddr returns an operator overloaded object which can then
check if we are returning a scalar (return the packed local address) or
are we returning a blessed reference (return the normal blessed
reference). I use this approach for code like this.

        print $md->DC->Title . "\n";
        print $md->DC->Title->Short . "\n";


Scooter - -- Scott Penrose Open source developer http://linux.dd.com.au/ [EMAIL PROTECTED]




Reply via email to