http://qs1969.pair.com?node_id=304279


in reply to Re: Re: Re: hijacking a module constructor
in thread hijacking a module constructor

This does not seem to work.

The GD:: namespace is not copying over... The Hackmare::GD namespace is getting pointed to the GD::Image namespace when the GD::Image copy takes place. I tried both:

*Hackmare::GD::Image::new = \&GD::Image::new; and *Hackmare::GD::Image:: = GD::Image::;
. Here is the debug output if it helps at all...
*Hackmare::GD::Image::new = \&GD::Image::new; *GD::Image:: = *SVG::GD::Image::; package SVG::GD::Image; #constructor sub SVG::GD::Image::new { my $class = shift; my $self = {}; bless $self, $class; $self->{_GD_} = new Hackmare::GD::Image(@_) || print STDERR "Quitting. Unable to construct new GD::Image object using GD: $!\n"; ....stuff.... return $self }
Here is the debugging info: Notice the infinite loop for the constructor:
main::(test/18-loadsvggd.pl:6): print "Creating an SVG::GD Image\n"; DB<0> Creating an SVG::GD Image main::(test/18-loadsvggd.pl:7): my ($width,$height) = (200,200); DB<0> main::(test/18-loadsvggd.pl:8): my $dwg = new GD::Image($width,$height +); DB<0> s SVG::GD::Image::new(SVG/GD.pm:79): my $class = shift; DB<0> s SVG::GD::Image::new(SVG/GD.pm:80): my $self = {}; DB<0> SVG::GD::Image::new(SVG/GD.pm:81): bless $self, $class; DB<0> SVG::GD::Image::new(SVG/GD.pm:82): $self->{_GD_} = new Hackma +re::GD::Image(@_) SVG::GD::Image::new(SVG/GD.pm:83): || print STDERR " +Quitting. Unable to construct new GD::Image SVG::GD::Image::new(SVG/GD.pm:84): object using GD: $!\n" +; DB<0> s GD::Image::new(SVG/GD.pm:79): my $class = shift; DB<0> GD::Image::new(SVG/GD.pm:80): my $self = {}; DB<0> GD::Image::new(SVG/GD.pm:81): bless $self, $class; DB<0> GD::Image::new(SVG/GD.pm:82): $self->{_GD_} = new Hackmare:: +GD::Image(@_) GD::Image::new(SVG/GD.pm:83): || print STDERR "Quitt +ing. Unable to construct new GD::Image GD::Image::new(SVG/GD.pm:84): object using GD: $!\n"; DB<0> GD::Image::new(SVG/GD.pm:79): my $class = shift; DB<0> GD::Image::new(SVG/GD.pm:80): my $self = {}; DB<0> GD::Image::new(SVG/GD.pm:81): bless $self, $class;
Is anything glaringly obvious here?

hackmare.

Replies are listed 'Best First'.
Re: Re: Re: Re: Re: hijacking a module constructor
by tilly (Archbishop) on Nov 04, 2003 at 03:15 UTC
    Untested idea.

    I have had much confusion about typeglob games in the past because I missed the simple fact that when Perl sees Foo::Bar it resolves what that will mean at compile time. Therefore rewriting what that should be at any other time is not going to cut it.

    Try rewriting the contents of the typeglob in a BEGIN block and see if that makes a difference. If you run into trouble, do lots of thinking about what things look like during compilation, and what they look like at runtime. (Keeping in mind how loading other things might overwrite stuff, and what operations happen when.)

    Good luck!

      Thanks for the help and insight, Tilly.

      Sorry about the slow reply. I was up to my ears trying to figure this out.

      I also got your idea passed on at the London Perl Mongers mailing list, and it partly works: I can re-map the GD::Image to use SVG::Image.

      And yes, you're absolutely right about the re-writing at load time. This is what makes this work *at all*. But only if it is loaded *after* GD is loaded.

      BEGIN { *GD::Image:: = *SVG::GD::Image::; }

      However, I'm now in an all-new kind of problem...

      I would have thought that the following:

      BEGIN { *SVG::H:: = *GD:: *GD::Image:: = *SVG::GD::Image::; }

      would have also given me a working access to the GD module so that my constructor could do this:

      SVG::GD::Image::new { ....create object and bless... as $self $self->{_GD_} = SVG::H::Image::new() }

      Unfortunately this does not seem to be the case, though.

      It looks like when I do this then the SVG::H:: namespace *also* gets reassigned to the SVG::GD::Image namespace. Most wierd. So I tried a second alternative... I mapped every method in GD.pm to SVG::H::GD like this:

      *SVG::H::GD::Image::new = \&GD::Image::new; *SVG::H::GD::Image::meths = \&GD::Image::meths;
      And this time, things get even worse. The module fails to bring in the xs module _new of (apparently correct) invocation. Apparently xs I need to manipulate the xs calls as well? Here, I'm lost. Maybe I need to re-map the xs methods too...:
      *SVG::H::GD::_new = \&GD::_new; ...etc for every xs subroutine...

      If you are interested in the actual code to take a look at it, it's the SVG::GD module on CPAN (0.7). I'm trying to implement a GD from within the constructor and failed + had to give up.

      Thanks for the help... Couldn't have gotten this far without outside help. I'm hoping that SVG::GD module will breathe some new life into GD if I can get the wrinkles out.

      If you have any interest at seeing the result of the first cut of my attempt to highjack GD, here's a test page with some output from GD.pm, GD::Graph.*, and some bioperl GD output:

      GD Test output to SVG all the GD examples I could compile with SVG::GD

      bioperl output test to SVG via GD A test of a bioperl graphic trying to see how bioperl can handle it (they were looking for GD support a while back). bioperl is a real stress test because it handles the GD constructor wayyyy down the module dependency tree.

      Ronan.


      hackmare.
      roasp.com Serverside SVG