jepri has asked for the wisdom of the Perl Monks concerning the following question:

Actually the title isn't quite accurate. I'm passing coderefs into other packages and they run fine. But any other functions called from the coderefs are called in the 'wrong' (the destination) package, not the package that the coderefs come from. Here's my example:

use webdav; my %callback = ( get_properties => \&get_properties_callb +ack, get_content => \&get_content, get_options => \&get_options, put_content => \&put_content, move_member => \&move_member, copy_member => \&copy_member, make_collection => \&make_collection, delete_member => \&delete_member, ); webdavlisten(%callback); package webdav; #Exports, etc etc sub webdavlisten { my %callback = @_; ... &{$callback{get_content}}(data...);

The callbacks work, but when any of the callback code calls another fuction, it calls it in the webdav package. Naturally the user is going to want to add a few support routines for his callbacks. The only thing I can think of to do is to use the caller function to see where webdavlisten is being called from, but even that is inelegant because there is no compulsion to call webdavlisten from the same package that the callbacks are defined in.

I'm happy to jettison the coderef callback and go OO if neccessary, but it seemed to me that this provided the most convenient way to pass the functions.

____________________
Jeremy
I didn't believe in evil until I dated it.

  • Comment on Passing coderefs across packages and calling them in the wrong package
  • Download Code

Replies are listed 'Best First'.
Re: Passing coderefs across packages and calling them in the wrong package
by dmmiller2k (Chaplain) on Feb 23, 2002 at 04:06 UTC

    Instead of exporting the callbacks unconditionally, why not use EXPORT_OK? Then you would have to explicitly name then in the use declaration, but I believe it may solve your problem of calling package local subroutines from the callbacks.

    I.e., instead of this:

    package main; use webdav; # ... package webdav; require Exporter; @ISA = qw(Exporter); @EXPORT = qw( get_content ...); # replace this

    use this:

    # same as above @EXPORT_OK = qw( get_content ...); # with this

    And then use this in your using code:

    use webdav qw( get_content ...);

    Perhaps a better solution is to explicitly prefix your coderefs with the package name they live in.

    dmm

    If you GIVE a man a fish you feed him for a day
    But,
    TEACH him to fish and you feed him for a lifetime
      I wasn't exporting the functions, since I was expecting the user to create them in main (or whatever package he is in). However that is an interesting idea. I'll see what happens if I create stub functions and let the user override them...

      ____________________
      Jeremy
      I didn't believe in evil until I dated it.