Re: cpan name spaces (was: Re: Re3: Re: How about class Foo {...} definition for Perl? )

2004-01-21 Thread Terrence Brannon
david nicol wrote:

Here's a controversial assertion:

Just because Damian Conway does something that doesn't make it right.

I reccommend changing the name of the module when the interface
changes, for instance I published Net::SMTP::Server::Client2
instead of hijacking Net::SMTP::Server::Client and producing
incompatible higher-numbred versions. (internally I've got a Client3
as well, but it's not going to get published)
In my opinion as soon as he broke compatability with something that
people were actually using, he should have changed the name. 

http://search.cpan.org/~tbone/Parse-RecDescent-FAQ-3.25/FAQ.pm
does not contain a section on version compatibility, maybe you could
submit one?
 

I am author maintainer of the Parse::RecDescent::FAQ - what happened 
vis-a-vis version compatibility? I have been far away from the mechanics 
of Parse::RecDescent for quite awhile.

And yes, please email me something that you want put in there.




Re: cpan name spaces (was: Re: Re3: Re: How about class Foo {...} definition for Perl? )

2004-01-21 Thread Fergal Daly
On Wed, Jan 21, 2004 at 03:53:34AM -0500, Terrence Brannon wrote:
 I am author maintainer of the Parse::RecDescent::FAQ - what happened 
 vis-a-vis version compatibility? I have been far away from the mechanics 
 of Parse::RecDescent for quite awhile.
 
 And yes, please email me something that you want put in there.

From the Changes file:

1.90Tue Mar 25 01:17:38 2003


- BACKWARDS INCOMPATIBLE CHANGE: The key of an %item entry for
  a repeated subrule now includes the repetition specifier.
  For example, in:

sentence: subject verb word(s)

  the various matched items will be stored in $item{'subject'},
  $item{'verb'}, and $item{'word(s)'} (i.e. *not* in $item{'word'},
  as it would have been in previous versions of the module).
  (thanks Anthony)

F


Re: cpan name spaces (was: Re: Re3: Re: How about class Foo {...} definition for Perl? )

2004-01-21 Thread Fergal Daly
On Tue, Jan 20, 2004 at 11:12:25PM -0600, david nicol wrote:
 Here's a controversial assertion:
 
 Just because Damian Conway does something that doesn't make it right.

It certainly doesn't but he's not alone in doing it.

Just to come clean, I was never really bitten by the Parse::RecDescent
change, it actually hit me very early on in development of my module so I
just switched to using 1.9x style without any hassle but it was over 2 years
between 1.80 and 1.90 so I could have been and I'd guess a lot of people
were bitten.

 I reccommend changing the name of the module when the interface
 changes, for instance I published Net::SMTP::Server::Client2
 instead of hijacking Net::SMTP::Server::Client and producing
 incompatible higher-numbred versions. (internally I've got a Client3
 as well, but it's not going to get published)
 
 In my opinion as soon as he broke compatability with something that
 people were actually using, he should have changed the name. 

That's what's necessary in the current scheme but good names are in short
supply so you end up with Client2, Client3, Client3_5 etc which is not so
nice and especially for things like Net::POP3.

Again, the result of gluing 2 strings together without a delimiter. This
also makes it hard for say search.cpan.org to make you aware that there is a
Client3 when you're looking at the Client2 page.

A better (IMHO) alternative is to make the interface part of the version
number as important as the name. This is equivalent to including it in the
name except you don't lose information like you do when you just glue a
number on the end of the name. You also get to use '.'s in the version
number because you're not try to make a valid Perl module name. Then CPAN
and other tools could understand the relationship between different versions
of modules.

Unfortunately, this is the bit I think will never happen, I don't think it
would be possible to convince people that this is worthwhile, possibly
because it's not worthwhile at this late stage.

So in the absence of the full solution perhaps we should urge people
towards sticking interface version numbers in the names of the modules. I've
done it privately too but I'm not convinced that CPAN should be littered
with My::Module, My::Module2, My::Module3 etc,

F


Re: cpan name spaces

2004-01-21 Thread Fergal Daly
On Tue, Jan 20, 2004 at 10:07:43PM -0500, David Manura wrote:
 In consideration of what Fergal said, should every public method or 
 function in a module be individually versioned?  So, when I do
 
   use Text::Balanced qw(extract_multiple extract_codeblock), 1.95;
 
 this could (under new semantics) assert only that those two functions have 
 the same interface and expected behavior as the corresponding functions in 
 module version 1.95.  If a future version of Text::Balanced (e.g. 1.96) 
 adds or changes the interface/behavior of other functions, my code will 
 still accept the new module.  Only when extract_multiple or 
 extract_codeblock themselves change interface/behavior would my code reject 
 a new module version.  There is no need for my code to provide an 
 acceptable version range; that is the module's responsibility to deduce.  
 (OO-like modules must be handled by a different mechanism.)

It may be worth it in some cases but perhaps if the functions are so
unrelated that they can change independently they should not be in the same
module. Making Text::Balanced::Multiple::extract() and
Text::Balanced::Codeblock::extract() would then allow you version them with
the module. There's nothing to stop you still making them available to
export from Text::Balanced.

 Consider further that another author comes out with a module named 
 Text::Balanced::Python having the same interface as Text::Balanced 1.95 but 
 whose extract_quotelike extracts Pythonic quotes rather than Perl-like 
 quotes (i.e. differing behavior).  I haven't considered how useful it would 
 be to express this relationship in the versioning metadata, but that might 
 be a further direction.  This resembles (OO) interfaces, but I believe the 
 versioning considerations make it different.

That is exactly what Java's etc interfaces do. So interfaces are what you
want rather than versions however it might be useful to be able to specify
the version of the interface.

This is getting very far away from anything that might realistically
happen...

F



Re: [Class::MultiList] Need feedback for first distribution

2004-01-21 Thread Ruslan U. Zakirov
David Manura wrote:
Hi Ruslan,

Do you have a link?  or some POD documentation?

-davidm
I realy realy sorry, I've forgot to attach file :(
Was tired a lot.
Ruslan U. Zakirov wrote:

Hello.
I'm planning to do my first CPAN upload.
I realy need some feedback.
Reasons:
1) Module is very simple, but I like it and use it.
2) I didn't find any similar on CPAN.
Questions:
1) I'm not native English speaker, so I want some feedback about 
Name.
2) Code, coding style, and so.
3) Something like: fo..., useless, suxxx is OK, but with 
reasons :)

My ideas:
1) May be it's better to prefix with _ all funcs which have 
AUTOLOAD magic? There is many such methods in module so it's hard to 
inherit this object.

Best regards. Ruslan.

Beforehead thanks.




package Class::MultiList;

use 5.006;
use strict;
use warnings;

our $VERSION = '0.1';

our $AUTOLOAD;


sub new
{
my $proto = shift;
my $class = ref($proto) || $proto;
my $self  = {};
bless ($self, $class);
return $self;
}

sub InitList
{
my $self = shift;
my $args = {
Name = undef,
@_,
};
die 'Where Name?' unless ($args-{'Name'});
$self-{'Lists'}-{ $args-{'Name'} } = {
List = [],
Current = undef,
Counter = 0,
Hash = {},
};
}

sub AUTOLOAD
{
my $self = shift;

my @avail = qw(Count First Current Last Next Prev Push Pop Unshift Shift);
my $re = join('|', @avail);

my ($func, $list) = ($AUTOLOAD =~ /^.*::($re)(.*)$/);

unless ( $func ) {
my ($package, $filename, $line) = caller;
die $AUTOLOAD Unimplemented in $package. ($filename line $line) \n;
}

unless ( $self-Exists( List = $list ) ) {
die List $list not exists;
}

no strict qw(refs);

*{$AUTOLOAD} = sub { return ( $self-$func( List = $list, @_ ) ) };
return ( $self-$func( List = $list, @_ ) );
}

sub Exists
{
my $self = shift;
my $args = {
List = undef,
@_,
};
return exists($self-{'Lists'}-{ $args-{'List'} });
}

sub Names
{
my $self = shift;
return keys %{$self-{'Lists'}};
}

sub First
{
my $self = shift;
my $args = {
List = undef,
@_,
};
my $list = $self-__GetList( $args-{'List'} );

$list-{'Current'} = 0;
return $self-Current( List = $args-{'List'} );
}

sub Current
{
my $self = shift;
my $args = {
List = undef,
@_,
};
my $list = $self-__GetList( $args-{'List'} );

return $list-{'List'}-{ $list-{'Current'} };
}

sub Last
{
my $self = shift;
my $args = {
List = undef,
@_,
};
my $list = $self-__GetList( $args-{'List'} );

$list-{'Current'} = $self-Count( List = $args-{'List'} );
return $self-Current( List = $args-{'List'} );
}

sub Next
{
my $self = shift;
my $args = {
List = undef,
@_,
};
my $list = $self-__GetList( $args-{'List'} );

$list-{'Counter'}++;

return $self-Current( List = $args-{'List'} )
if( $list-{'Counter'}  $self-Count( List = $args-{'List'} ) );

$list-{'Counter'} = undef;
return undef;
}

sub Prev
{
my $self = shift;
my $args = {
List = undef,
@_,
};
my $list = $self-__GetList( $args-{'List'} );

$list-{'Counter'}--;

return $self-Current( List = $args-{'List'} )
if( $list-{'Counter'} = 0 );

$list-{'Counter'} = undef;
return undef;
}

sub Count
{
my $self = shift;
my $args = {
List = undef,
@_,
};
my $list = $self-__GetList( $args-{'List'} );

return $list-{'Counter'};
}

sub Push
{
my $self = shift;
my $args = {
List = undef,
Element = undef,
Mark = undef,
@_,
};
my $list = $self-__GetList( $args-{'List'} );

if ( $args-{'Mark'} ) {
die 'Mark already exists' if (exists $list-{'Hash'}-{ 
$args-{'Mark'} });
$list-{'Hash'}-{ $args-{'Mark'} } = $list-{'Counter'};
}

$list-{'Counter'}++;
push( @{$list-{'List'}}, $args-{'Element'} );

return;
}

sub Pop
{
my $self = shift;
my $args = {
List = undef,
@_,
};
my $list = $self-__GetList( $args-{'List'} );

$list-{'Counter'}--;

$list-{'Current'} = undef if ( $list-{'Current'} == $list-{'Counter'} );

# check for mark, 

Re: [Class::MultiList] Need feedback for first distribution

2004-01-21 Thread Martyn J. Pearce
Hello Ruslan,

On Wed, Jan 21, 2004 at 01:59:35PM +0300, Ruslan U. Zakirov wrote:
 I realy realy sorry, I've forgot to attach file :(
 Was tired a lot.

A quick glance over prompts my first question: what does this module provide
that other Class generating modules, e.g., Class::MethodMaker,
Class::MakeMethods, Class::Struct, do not?

Mx.


Re: [Class::MultiList] Need feedback for first distribution

2004-01-21 Thread A. Pagaltzis
* david nicol [EMAIL PROTECTED] [2004-01-21 13:09]:
 I think its that as soon as you have AUTOLOAD defined, you
 can't inherit past that point, at least by the ISA mechanism:
 the AUTOLOAD function needs to know how to punt.

You think wrong.

$ perl -l
package Foo;
sub bar { print oy vey };

package Baz;
our @ISA = qw(Foo);
sub AUTOLOAD {};
  
package main;
Baz-bar;
  
^D
oy vey

Cf. perldoc perlobj:

If neither the current class, its named base classes, nor the
UNIVERSAL class contains the requested method, these three
places are searched all over again, this time looking for a
method named AUTOLOAD().

-- 
Regards,
Aristotle
 
If you can't laugh at yourself, you don't take life seriously enough.


Mail::Outlook module

2004-01-21 Thread Barbie
Dear Module Authors,

Since my initial attempts to send mail via Outlook attached to an Exchange server, I 
now have a set of modules that can also read email items within Outlook Mail Folders. 
Initially this was a module for me to learn how to use the Win32 API via Perl, but 
wondered whether it might be useful to anyone else.

My current name for the distribution is

Mail-Outlook

which includes the following modules:

Mail::Outlook
Mail::Outlook::Folder
Mail::Outlook::Message

Each uses an OO style interface, with the Mail::Outlook module being the master module 
that should be used to interface to the outside world.

I have two questions 

1) Is this a distribution worth uploading to CPAN?
2) Is Mail::Outlook a suitable namespace or are there better suggestions?

The current version is available online [1] if anyone wanted to have a look at it.

[1] http://birmingham.pm.org/modules/Mail-Outlook-0.05.tar.gz

From studying the MailBox distribution, there are distributions on CPAN, which read 
the Outlook Express folders and email messages (although badly named IMO as they only 
refer to the DBX extension, but that's another story), but nothing that refers to 
Outlook specifically.

All thoughts and suggestions gratefully accepted.

Additional:

DESCRIPTION

This module was written to overcome the problem of sending mail messages, 
where Microsoft (R) Outlook (R) is the only mail application available.
However, since it's inception the module has expanded to handle a range of 
Outlook mail functionality.

Note that when sending messages, the module uses the named owner of the 
Outbox MAPI Folder in order to access the correct objects. Thus the From 
field of a new message is predetermined, and a read only property.

If using the 'Win32::OLE::Const' constants, only the following are currently 
supported:

  olFolderInbox
  olFolderOutbox
  olFolderSentMail

DEPENDENCIES

The distribution requires the following modules:

  Win32::OLE
  Win32::OLE::Const

For testing purposes, the following modules are desirable, but not essential:

  Test::Pod


Barbie.
-- 
Barbie (@missbarbell.co.uk) | Birmingham Perl Mongers | http://birmingham.pm.org/



Re: Mail::Outlook module

2004-01-21 Thread Ed Summers
On Wed, Jan 21, 2004 at 02:00:40PM +, Barbie wrote:
 1) Is this a distribution worth uploading to CPAN?

Yes! There was a recent discussion at chicago.pm [1] at how to get at .pst 
files. 

 2) Is Mail::Outlook a suitable namespace or are there better suggestions?

In an ideal world your module would plug into the Mail::Box framework somehow. 
But I'm not even sure if Outlook Express files are functionally different 
from vanilla Outlook files...exit stage left.

//Ed

[1] http://mail.pm.org/pipermail/chicago-talk/2004-January/000800.html 


optional mix-in classes

2004-01-21 Thread Eric Wilhelm
Hi,

I'm trying to find a good way for CAD::Drawing::IO to determine which of the 
CAD::Drawing::IO::* modules are available.

Basically, there are save() and load() functions in IO.pm which allow an 
explicit type argument or the type can be derived from the file extension.

Right now, the beginning of IO.pm is just like:

  use CAD::Drawing::IO::OpenDWG;
  use CAD::Drawing::IO::PostScript;
  use CAD::Drawing::IO::Image;
  use CAD::Drawing::IO::PgDB;
  use CAD::Drawing::IO::Circ;
  use CAD::Drawing::IO::Tk;

  our @ISA = qw(
CAD::Drawing::IO::OpenDWG
CAD::Drawing::IO::PostScript
CAD::Drawing::IO::Image
CAD::Drawing::IO::PgDB
CAD::Drawing::IO::Circ
CAD::Drawing::IO::Tk
);

The main reason that I'd like to be able to make each module optional is that 
OpenDWG.pm requires DWGI.pm (a wrapper on a non-gpl toolkit which I cannot 
distribute with the module.)

From looking at DBI.pm, available drivers are found by searching @INC when 
connect() is called, and then there is a require().  I don't think that I 
need anything as elaborate as the DBI setup, and I'd rather that this just be 
done at compile time (plus, searching @INC seems like a waste and IO.pm needs 
to know which save_type() and load_type() functions are available in 
order to redirect to the backend.)

Since adding a backend requires changes to IO.pm, maybe it should just be part 
of the IO.pm install procedure?  Or, I could look at entirely removing the 
type determination and redirects from IO.pm (allowing the backends to 
install themselves (and then looping through the list of available 
backends, calling an is_this_yours() function to allow the implicit filetype 
determination to come from the backend itself?)), but I'm not sure how to go 
about that.

Currently, the redirection is like so:
  # (stripped from the middle of a longer function in IO.pm)
  elsif($type eq postscript) {
($action eq save)  return($self-saveps($filename, $opt));
($action eq load)  return($self-loadps($filename, $opt));
  }
  elsif($type eq image) {
($action eq save)  return($self-saveimg($filename, $opt) );
($action eq load)  return($self-loadimg($filename, $opt) );
  }


Thanks in advance for any suggestions,
Eric



Re: optional mix-in classes

2004-01-21 Thread darren chamberlain
* Eric Wilhelm ewilhelm at sbcglobal.net [2004/01/21 10:58]:
 I'm trying to find a good way for CAD::Drawing::IO to determine which
 of the CAD::Drawing::IO::* modules are available.

It sounds like what you want is to ensure that the IO::* modules are
polymorphic, i.e., to ensure that they all adhere to the same interface.
Then, like DBI, CAD::Drawing::IO can be setup to load the appropriate
implementation module (no groveling in @INC, that's what require is
for), instantiate an object, and then call the appropriate methods on
that object.  Your main module (IO.pm) shouldn't need to have knowledge
of the various IO::* modules.

 Basically, there are save() and load() functions in IO.pm which allow
 an explicit type argument or the type can be derived from the file
 extension.

At this point, IO.pm should load the right module with require, and then
defer to that module's methods to do the right thing for loading,
saving, etc.

(darren)

-- 
You win again, gravity!


pgp0.pgp
Description: PGP signature


Re: [Class::MultiList] Need feedback for first distribution

2004-01-21 Thread Ruslan U. Zakirov
Martyn J. Pearce wrote:
Hello Ruslan,

On Wed, Jan 21, 2004 at 01:59:35PM +0300, Ruslan U. Zakirov wrote:

I realy realy sorry, I've forgot to attach file :(
Was tired a lot.


A quick glance over prompts my first question: what does this module provide
that other Class generating modules, e.g., Class::MethodMaker,
Class::MakeMethods, Class::Struct, do not?
	Hello, Martyn and other.

Class::Struct - it's implementation of C like structs. Looking in source 
said that it does not like ISA at all so It's not OO style at all.
This module has no similarity in reasons and goals of mine.

I didn't find any similarity with Class::MakeMethods.
I'm going in another direction.
This module(distro) do much on get/set methods, but not iteration.
I want next features:
1) Ordered container of any elements in its cells.
2) Support for many such containers in one object.
For example:
One Object have next lists:
Attribute
Child
Sibling
3) It's something like 'bidirect lists' in C which have next and prev 
refs, but I want abstract this class from data in cells.
Very good schem:
my $attr = $Obj-Attrs-First;
while ($attr-Next) {
...
}
but force me to change Attr object, so I've decided to use next style:
$Obj-InitList(Name = 'Attr');
$Obj-PushAttr($attr); #or
$Obj-Push(List = 'Attr', Element = $attr);

while (my $attr = $Obj-NextAttr) {
...
}
4) Main goal is walking through list(Next, Prev, First, Last)

5) I don't want to give public interface to internal array what other 
modules do.

6) I consider using of this module in OO enviorment so support for join 
method is something not normal.

I hope I've spot more light with this letter.

		Best regards. Ruslan.
Mx.




Re: optional mix-in (er, add-on?) classes

2004-01-21 Thread Eric Wilhelm
 The following was supposedly scribed by
 darren chamberlain
 on Wednesday 21 January 2004 11:10 am:

* Eric Wilhelm ewilhelm at sbcglobal.net [2004/01/21 10:58]:
 I'm trying to find a good way for CAD::Drawing::IO to determine which
 of the CAD::Drawing::IO::* modules are available.

It sounds like what you want is to ensure that the IO::* modules are
polymorphic, i.e., to ensure that they all adhere to the same interface.
Then, like DBI, CAD::Drawing::IO can be setup to load the appropriate
implementation module (no groveling in @INC, that's what require is
for), instantiate an object, and then call the appropriate methods on
that object.  

Not exactly.  The IO::* modules do not have constructors, and neither does 
IO.pm.  Maybe mix-in is the wrong term.  Essentially, every function is 
inherited *by* CAD::Drawing, so basically, the entire set could simply be in 
the one package and file, but that's a lot of code.  Maybe they are more like 
add-on packages?  Functions from IO::* modules are inherited by IO.pm, 
which is inherited by Drawing.pm, so with $d = CAD::Drawing-new(), you could 
call $d-loaddwg(file.dwg, {}), but you are better served by 
$d-load(file.dwg) where load() is actually CAD::Drawing::IO::load() and 
loaddwg() is CAD::Drawing::IO::OpenDWG::loaddwg().

Your main module (IO.pm) shouldn't need to have knowledge
of the various IO::* modules.

It needs to have some knowledge of them in order to redirect the action 
request to handle the particular filetype.  Also, I'm not sure that 
polymorphism is really helpful, since IO.pm is always getting a CAD::Drawing 
object, it is not like it has a classed object which will automagically go to 
the correct class for its method.  With the current setup, the IO::* modules 
are really just packages.  

So,  I guess my challenge is how to make IO.pm find all of the qualified, 
installed packages under CAD/Drawing/IO/*.pm and call the correct function 
based on either the explicit filetype or extension which is received by 
load() or save().  I can see doing this with a foreach() / require() / eval() 
setup or something where the packages contain code refs, but that doesn't 
seem very tidy, and with some Inline-based modules as backends, I'd like to 
have as much as possible happen at compile time so that C/XS errors are 
thrown at the beginning instead of the end.

The primary goal is to make the module more easily installable (and possibly 
to eventually pass the CPAN autotesting), but I'd also like other authors to 
be able to write IO::* modules (for other geometric formats) without having 
to add code to IO.pm or make changes to your main program (e.g. if you give 
the program an argument of output.igs and an iges format save function is 
available, it just does the right thing.)  With this model, your main 
program would not have use CAD::Drawing::IO::IGES;, but simply use 
CAD::Drawing;.

Thanks,
Eric




Re: optional mix-in (er, add-on?) classes

2004-01-21 Thread Eric Wilhelm
 The following was supposedly scribed by
 darren chamberlain
 on Wednesday 21 January 2004 02:11 pm:

* Eric Wilhelm ewilhelm at sbcglobal.net [2004/01/21 13:58]:
  The following was supposedly scribed by
  darren chamberlain
  on Wednesday 21 January 2004 11:10 am:

Supposedly?  Aren't you verifying signatures?  ;)

:) no.  That's just the quote line.

Well, if polymorphism isn't what you're after, couldn't you have
CAD::Drawing::IO not define a load function, and have
CAD::Drawing::IO::Foo declare package CAD::Drawing::IO and define a
load?  Then, the user need simply do:

  use CAD::Drawing::IO;
  use CAD::Drawing::IO::OpenDWG;

And calling load(file.dwg) uses the load defined in ::IO::OpenDWG?

But this still (essentially) leaves the user with hard-coded information about 
which format to use (making it impossible to do $drw-save($ARGV[0])).  My 
goal is to make all of the file formats (smile floormats) transparent in the 
hope that they eventually go away completely.

Without any knowledge of the implementation, however, it sounds like
what you want is polymorphism, and you're jumping through hoops to avoid
using it.

What I'm going for is more like a big chain of elsif statements which is put 
together out of multiple packages.  If the user were to use an object from 
CAD::Drawing::IO::OpenDWG to call the save() function, that would be 
polymorphism.  I might be jumping through hoops at the module level, but I 
think this beats making the user jump through hoops at the main program 
level.

 With this model, your main program would not have use
 CAD::Drawing::IO::IGES;, but simply use CAD::Drawing;.

This sounds exactly like DBI, which relies on DBDs being polymorphic.
*shrug*

It is a lot like the DBI::connect() function, but load() does not return an 
object the way connect() does.  With DBI, once it gets hold of a classed 
object, DBI.pm is home-free and just has to return the blessed object, 
leaving the rest up to the polymorphism.  

My problem is more like DBI turned on its head.  e.g. with DBI::connect() you 
are at the beginning of the program and you get your $dbh which is used to 
call $dbh-select*foo() and such.

With CAD::Drawing, you get your $drw from CAD::Drawing-new() and from there 
you can either $drw-load(whatever.dwg|dxf) or just start adding entities 
to the drawing.  At the end (or the middle, or as many times as you like), 
you can $drw-save(file.ps)  $drw-save(file.dxf)  
$drw-save(file.png, {size = [640,480]})  $drw-save(file.dwg.gz).

Now, if I could just get the string file.ps to kindly bless itself into 
CAD::Drawing::IO::PostScript, I'd be in the free and clear;-)

Seriously, though.  That is basically what I'm trying to do.  Consider this, 
where you have a list of available packages in @found, and a $filename with 
(or without) an extension, and possibly an explicit $options{type} argument, 
and the following is part of the IO::save() function:

  foreach my $package (@found) {
if(eval(\$ . $package . ::can_save(\$filename, \$options{type})) ) {
  my $r = eval($package . ::save_file(\$self, \$filename, \\%options))
  return($r);
}
  }

Thanks,
Eric

-- 
A counterintuitive sansevieria trifasciata was once literalized guiltily.
--Product of Artificial Intelligence



VERSION as (interface,revision) pair and CPAN++

2004-01-21 Thread david nicol
On Wed, 2004-01-21 at 04:32, Fergal Daly wrote:

 A better (IMHO) alternative is to make the interface part of the version
 number as important as the name. This is equivalent to including it in the
 name except you don't lose information like you do when you just glue a
 number on the end of the name. You also get to use '.'s in the version
 number because you're not try to make a valid Perl module name. Then CPAN
 and other tools could understand the relationship between different versions
 of modules.
 
 Unfortunately, this is the bit I think will never happen, I don't think it
 would be possible to convince people that this is worthwhile, possibly
 because it's not worthwhile at this late stage.


Q: was this suggestion made as a perl6 RFC and if so what did Larry
   think of it?

Q2: Do you have a really clear idea of what split interface/version
numbers would look like and is it light enough to try to get it
into perl 5.9.1 ? (act fast) 


Could the situation be resolved by insisting that the first number
in a version string is the interface version and following numbers
are revision numbers, and rewriting Crequire in some way to
respect that?  For instance, require could take a regex as an argument
and when that happens the version would have to match the regex,
and the same with the VERSION element of Cuse


   If the VERSION argument is present between Module
   and LIST, then the use will call the VERSION
   method in class Module with the given version as
   an argument.  The default VERSION method, inher
   ited from the UNIVERSAL class, croaks if the given
   version is larger than the value of the variable
   $Module::VERSION.


So we're talking about altering the default VERSION method to
recognize something other than a version string, that would trigger
a different case.  Such as, the major number has to match and the
minor number has to be greater, or a PROVIDES method which defaults to
the @{$Module::PROVIDES} array must include a version number with
the same major number as the one we want.

Or maybe we're talking about enlightened new versions of modules
that present old interfaces when provided an old version number. This
is IMO a non-starter, since it would require a lot of work that
will not seem necessary by the people who would have to do the work.

Or maybe we're talking about adding a bureaucratic layer to CPAN so
it won't accept new versions of modules under the same name unless
the new version passes the test suite from the old version, for modules
on a restricted list that your module gets on once enough people rely on
your module.

The last suggestion would enforce interface compatability, after a
fashion.

It would need to be documented thoroughly so people don't go including
test cases for things known to be broken in their modules, that verify
that the modules are broken in the way that the modules are broken. (I
have done this; DirDB 0.0.6 fails tests in DirDB 0.0.5 concerning
croaking on unhandleable data types)

Compliance might be part of a standard quality check before a module
with a positive major version number is accepted; or CPAN might enforce
quality ratings, which would be enforced to be nondecreasing, for a
given module name.

So if a module has a PRODUCTION quality rating, that means that the
interface is guaranteed to remain stable into the future, under the
given name.

And that tests for things that are broken and you mean to fix in the
future would have to be marked as such in the tests.pl.


:)
David Nicol




-- 
david nicol
In order to understand what another person is saying, you must assume that it
is true and try to imagine what it could be true of. (George Miller; 1980.)