You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@perl.apache.org by Stas Bekman <st...@stason.org> on 2004/03/24 03:51:12 UTC
[mp2] ModPerl::Util::parse_version
Any objects to this new util function? If you follow the discussion on p5p, we
have no way but to provide our own function for multiple reasons. Besides,
it's does exactly what most mp2 module authors will want, i.e.:
if (ModPerl::Util::parse_version("Apache::Request") > 2 &&
eval { require Apache::Request }) {
# use Apache::Request
}
else {
# use something else
}
you don't need to check for defined, nor to force numerical context for cases
like '2.03-dev'. it gives you a good number to use.
notice that 'use Apache::Request 2.0' doesn't work, because it may load an old
mp1 version which is not binary compatible. and as it's in case of
Apache::Status, we don't want to die if Apache::Request version wasn't
satisfied, and CGI.pm is available.
Unless you have better ideas, I'll go ahead and commit this new function and
use it in Apache::Status which is currently somewhat broken because of that.
--- /dev/null 1969-12-31 16:00:00.000000000 -0800
+++ xs/ModPerl/Util/Util_pm 2004-03-23 18:32:48.797050343 -0800
@@ -0,0 +1,62 @@
+use File::Spec ();
+
+# mp2 modules have to deal with situations where a binary incompatible
+# mp1 version of the same module is installed in the same
+# tree. therefore when checking for a certain version, one wants to
+# check the version of the module 'require()' will find without
+# loading that module. this function partially adopted from
+# ExtUtils::MM_Unix does just that. it returns the version number of
+
+# the first module that it finds, forcing numerical context, making
+# the return value suitable for immediate numerical comparison
+# operation. (i.e. 2.03-dev will be returned as 2.03, 0 will be
+# returned when the parsing has failed or a module wasn't found).
+sub parse_version {
+ my $name = shift;
+ die "no module name passed" unless $name;
+ my $file = File::Spec->catfile(split /::/, $name) . '.pm';
+ for my $dir (@INC) {
+ next if ref $dir; # skip code refs
+
+ my $pmfile = File::Spec->catfile($dir, $file);
+ next unless -r $pmfile;
+
+ open my $fh, $pmfile or die "can't open $pmfile: $!";
+
+ my $inpod = 0;
+ my $version;
+ while (<$fh>) {
+ $inpod = /^=(?!cut)/ ? 1 : /^=cut/ ? 0 : $inpod;
+ next if $inpod || /^\s*#/;
+
+ chomp;
+ next unless /([\$*])(([\w\:\']*)\bVERSION)\b.*\=/;
+ { local($1, $2); ($_ = $_) = /(.*)/; } # untaint
+ my $eval = qq{
+ package ModPerl::Util::_version;
+ no strict;
+
+ local $1$2;
+ \$$2=undef; do {
+ $_
+ }; \$$2
+ };
+ no warnings;
+ $version = eval $eval;
+ warn "Could not eval '$eval' in $parsefile: $@" if $@;
+ last;
+ }
+
+ close $fh;
+
+ # avoid situations like "2.03-dev" and return a numerical
+ # version
+ if (defined $version) {
+ no warnings;
+ $version += 0; # force number
+ return $version;
+ }
+ }
+
+ return 0; # didn't find the file or the version number
+}
--
__________________________________________________________________
Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org http://ticketmaster.com
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org
Re: [mp2] ModPerl::Util::parse_version
Posted by Stas Bekman <st...@stason.org>.
Geoffrey Young wrote:
>
> Stas Bekman wrote:
>
>>Any objects to this new util function?
>
>
> not really. but...
>
>
>>If you follow the discussion on
>>p5p, we have no way but to provide our own function for multiple
>>reasons. Besides, it's does exactly what most mp2 module authors will
>>want, i.e.:
>>
>>if (ModPerl::Util::parse_version("Apache::Request") > 2 &&
>> eval { require Apache::Request }) {
>> # use Apache::Request
>>}
>>else {
>> # use something else
>>}
>>
>>you don't need to check for defined, nor to force numerical context for
>>cases like '2.03-dev'. it gives you a good number to use.
>>
>>notice that 'use Apache::Request 2.0' doesn't work, because it may load
>>an old mp1 version which is not binary compatible.
>
>
> I think that a simple 'use' will suffice for the vast majority of users. if
> you try to 'use Apache::Request 2.0;' and you get the wrong version then
> something is wrong with your application setup - you've forgotten to load
> Apache2.pm or somesuch. most people will indeed want it to fail, so
> requiring a the module and having it die when compared to the required
> version is DWIMmy.
This is almost 99% correct. The remaining problem is that when this wrong
library gets loaded (and a particular request that triggered it aborts) and a
user doesn't restart the server, he will see all kind of broken things.
>>and as it's in case
>>of Apache::Status, we don't want to die if Apache::Request version
>>wasn't satisfied, and CGI.pm is available.
>
>
> yes, I see that. but it's probably a very rare case, substituting one
> module for another - you generally can't just do that in production code (at
> least you can't if you really value "production"). so, outside of
> substituting one module for another, I don't see this function being all
> that useful.
>
>
>>Unless you have better ideas, I'll go ahead and commit this new function
>>and use it in Apache::Status which is currently somewhat broken because
>>of that.
>
>
> p5p seemed to be interested in adding the functionality to version.pm or
> somesuch, so maybe wait and see how it plays out there before we end up
> maintaining our own version?
Yes, but p5p seems to be reluctant to make it working under -T (I'm not
disagreeing with Hugo, just trying to find a solution that will work).
So, I agree that Apache::Status is unique. So what I'm going to do is to
inline that function in Apache::Status, because I see no other solution at the
moment - we get the test suite broken, when only mp1 version is installed (it
fails to do the version check, but it's loaded nevertheless and this breaks
other modules, e.g. Apache::compat). If we find other places where it's going
to be useful, we can always expose it.
Thanks for the comments, Geoff!
__________________________________________________________________
Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org http://ticketmaster.com
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org
Re: [mp2] ModPerl::Util::parse_version
Posted by Geoffrey Young <ge...@modperlcookbook.org>.
Stas Bekman wrote:
> Any objects to this new util function?
not really. but...
> If you follow the discussion on
> p5p, we have no way but to provide our own function for multiple
> reasons. Besides, it's does exactly what most mp2 module authors will
> want, i.e.:
>
> if (ModPerl::Util::parse_version("Apache::Request") > 2 &&
> eval { require Apache::Request }) {
> # use Apache::Request
> }
> else {
> # use something else
> }
>
> you don't need to check for defined, nor to force numerical context for
> cases like '2.03-dev'. it gives you a good number to use.
>
> notice that 'use Apache::Request 2.0' doesn't work, because it may load
> an old mp1 version which is not binary compatible.
I think that a simple 'use' will suffice for the vast majority of users. if
you try to 'use Apache::Request 2.0;' and you get the wrong version then
something is wrong with your application setup - you've forgotten to load
Apache2.pm or somesuch. most people will indeed want it to fail, so
requiring a the module and having it die when compared to the required
version is DWIMmy.
> and as it's in case
> of Apache::Status, we don't want to die if Apache::Request version
> wasn't satisfied, and CGI.pm is available.
yes, I see that. but it's probably a very rare case, substituting one
module for another - you generally can't just do that in production code (at
least you can't if you really value "production"). so, outside of
substituting one module for another, I don't see this function being all
that useful.
>
> Unless you have better ideas, I'll go ahead and commit this new function
> and use it in Apache::Status which is currently somewhat broken because
> of that.
p5p seemed to be interested in adding the functionality to version.pm or
somesuch, so maybe wait and see how it plays out there before we end up
maintaining our own version?
--Geoff
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org