[Gdal-dev] Changes to and upgrade of the Perl bindings

Mark Overmeer mark at overmeer.net
Wed Jun 14 09:28:30 EDT 2006


* Ari Jolma (ari.jolma at tkk.fi) [060614 12:12]:
> Is the naming practice written down somewhere? I know some modules use
> finderClean naming but I've thought that's more Java's naming practise.

not AFAIK  But have a look at the large modules, like XML::LibXML

> I thought finder_clean was used more in Perl.

For functions.

> Here I'm trying to stick
> to the naming and names that are in GDAL/OGR itself. My thinking is that
> it should be easy to port GDAL scripts written in Python or Ruby to Perl
> and vice versa.

That will result in the same quality of code as the language translations
of Google's babel.  Don't!

> My hands are also tied up a bit because of the Swig interface, where the
> names are mostly defined and they are shared among all languages.

No, your hands are not tied.  Swig creates the interface between the
library and Perl, but NO-ONE forces you to publish the library interface
directly to module users.  Please do not burdon the users with Swigs
limits!!!

> > Things like this:
> >     $driver->{LongName}
> > are a crime against OO.  It should be:
> >     $driver->longName;
> >     sub GDAL::Driver::longName() {shift->{LongName}}
> 
> Swig does some magic to tie things like $driver->{LongName} to getter
> and setter functions.

Well, so... you see that the tie is still used: but only inside the
object.

> Things like these are partly due to my poor knowledge of Swig. Current
> versions of Swig support adding Perl code to the modules it generates,
> so Perlifying things this way are more easy to do now.

That is not a problem.  You let Swig create a module  GDAL::Image::Dataset,
in file GDAL/Image/Dataset.pm   User's have in their scripts "use GDAL::Image"  
In GDAL/Image.pm, you simply say:

  use GDAL::Image::Dataset;
  package GDAL::Image::Dataset;
  sub myNewOwnMethod()....

In ANY file, you can add methods and variables to ANY namespace, with the
package command.  You can put the wrapper code simply in GDAL/Image.pm
but also in some other module:

  GDAL/Image/DatasetWrapper.pm:
      use GDAL::Image::Dataset;
      package GDAL::Image::Dataset;
      sub myNewOwnMethod()....

> >   $dataset->SetGeoTransform(\@transform);
> > should become
> >   $dataset->SetGeoTransform(@transform);
> > or
> >   $dataset->SetGeoTransform($minX, $dx, 0, $maxY, 0, $dy);
> 
> I have to admit this is because I did not know how to achieve the
> latter, which is better also IMHO, in Swig :-(

Very simple... SWIG produces a function:
   SetGeoTransform($dataset, \@transform);
and you create a method
   sub setGeoTransform(@)
   {   my $self = shift;
       SetGeoTransform($self, \@_);
   }

> >  GetGCPs:
> >   my $gcps = $dataset->GetGCPs();
> >   for (0..$#$gcps) {
> >     $x[$_] = $gcps->[$_]->{GCPX};
> >     $y[$_] = $gcps->[$_]->{GCPY};
> >   }
> > 
> > should become
> > 
> >   foreach my $point ($image->GCPpoints) ...
> 
> ah, but that's just an example in the docs...

I surely hope you implement as you plan, so examples should work.  It
is silly to write examples that are ugly.

If you start writing the docs and tests from a "best usage" for the
average user, then you will end-up with a nice module.

> I wrote the constructor functions into the Geo::GDAL module, which are
> probably yet another OO sin, because I did not know how to get from
> having classes like Geo::GDAL::gdal::Band (or
> Geo::GDAL::something::Band) that I get from Swig to Geo::GDAL::Band,
> which would be desirable. I mean without having to change the shared
> swig files too much -- i.e. write #ifdef SWIGPERL ...

 *My::Favorit::Package::Name::new = \&Geo::GDAL::gdal::Band::new;

> I'm also a bit worried about performance penalty if I introduce yet
> another layer by inheriting from Geo::GDAL::gdal::Band to Geo::GDAL::Band

non-argument.  The application will run inside the library for 99.99% of
its time.  Besides, we have a software crisis, not a hardware limitation.

> There is also the problem that the GDAL library has to be used through
> the swig wrappers with care, things like $image->band(3)->name are
> usually dangerous, since the reference counting systems in high level
> languages and in GDAL itself are disconnected.

No, you will not get into these problems (when SWIG is working as it
should).

> The current path in implementing the Perl interface to GDAL/OGR is
> 1) get a working interface
> 2) make it CPAN compatible (namespace mostly)
> 3) make it more Perl / fix the reference counting

Please start with (2) to safe yourself a lot of work.  I would refrase
(1) into: design a workable interface.

> Geo::GDAL::Database::Driver
> Geo::GDAL::Layer
> Geo::GDAL::Feature
> Geo::GDAL::FeatureDefn
> Geo::GDAL::FieldDefn
> Geo::GDAL::Geometry
> Should the last ones be Geo::GDAL::Database::Layer etc?

I don't know enough about the meaning of the names.  Are all these
objects really necessary to publish to the users?  Can't you hide them?

> So, instead of a function GetGDALDriverCount we'd have a static function
> Geo::GDAL::Image::Driver::Count that returns the number of available
> raster drivers. And instead of CreateLayer we'd call Geo::GDAL::Layer->new.

In "real" Perl, you should implement it like this:

  # Returns the driver details as LIST of objects, count in SCALAR.
  package GDAL;
  sub drivers()
  {   my $count = GetGDALDriverCount;
      return $count unless wantarray;
      map {GDAL::Driver->new(number => $_)} 0..$count-1;
  }

  package GDAL::Driver;
  sub new(@)
  {   my ($class, %args) = @_;
      my $self   = bless {}, $class;
      my $number = $args{number} || 0;
      my $data   = Swig::GetDriverDataByNumber($number);
      copyDriverData($self, $data);    # to be implemented
      $self;
  }

  package main;   # the main program
  use GDAL;
  foreach my $driver (GDAL->drivers)
  {   print $driver->longName, "\n";
  }
  print scalar(GDAL->drivers), " drivers defined\n";

> It would be good to have as closely matching names as possible in all
> wrapper languages.

No. mistake.
Strive for the smallest and easiest user interface, then for the
practices used by the programming language at hand, and only on the
last place... when you have a few names to choose, then try to use
names which indicate the relation.   It is silly to give the user
access to 50 library methods where he/she could do with only three.
-- 
CU,
               MarkOv



More information about the Gdal-dev mailing list