John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

In my Exporter::VA I planned on allowing a hashref parameter be passed as a parameter to import, instead of found as a package global. Everyone liked the idea. I even went out of my way to allow it to be last in the list. See Module Design strawman - Exporter::VA for the original writeup, or John M. Dlugosz's scratchpad for the latest.

However, when I tested it, I was told "import parameter is not a string..." which is true enough, but not what I wanted to hear!

It looks like the implicit call to import() from a use will check the parameters in ways that a normal call does not.

Why?

Update: tye points out that it is the implementation of import that's doing it! I'm presuming that this parameter didn't get removed earlier as it should, but the point is I'll have to look some place totally different than I was. And as bbfu found out, having the exporter export itself has a strange way of messing with your mind.

Update2: The problem was in passing the wrong value to the function that was supposed to extract the hashref from the parameter list.

I think it's unnecessary to constrain the implementor of import. After all, it's supposed to be "wide open", so why get in my way?

Can anyone give a good reason why it should do this kind of checking? After all, the function itself can check the parameters, if necessary or to coddle the user.

—John

Edit by tye to fix pad link

Replies are listed 'Best First'.
(tye)Re: Import parameter not a string - grrr
by tye (Sage) on Dec 04, 2002 at 06:40 UTC

    To quote your own code: '.&unknown_type' => sub { Err "import parameter is not a string" }, So I think you have yourself to blame. (:

    I have used non-strings in import routines with no such problems.

            - tye
      Thanks. I'll have to figure out why it's still in there instead of being stripped earlier.

      I think I'll also prefix my error messages with something unique to avoid such confusion. The line number info on the error isn't always helpful I guess especially in the wee hours of the morning!

      Thanks for looking it over.

      —John

(bbfu) Re: Import parameter not a string - grrr
by bbfu (Curate) on Dec 04, 2002 at 06:30 UTC

    Eh? I ran this test and it seems to allow hashrefs just fine. I haven't looked at your scratchpad yet, though.

    [johnsca@CORY tmp]$ cat tst.pm #!/usr/bin/perl package tst; use warnings; use strict; sub import { my $self = shift; my $hr = shift; print "foo: `$hr->{foo}'\n"; } 1; [johnsca@CORY tmp]$ cat tst #!/usr/bin/perl use warnings; use lib '.'; use tst { foo => 'bar' }; [johnsca@CORY tmp]$ ./tst foo: `bar'

    P.S. The link to your scratchpad doesn't work with the underscores.

    Update: Yes, as tye points out, the error message is coming from your Exporter::VA module. I can't seem to find, in the code on your scratchpad, where you define the handler for the hashref to your module's (Exporter::VA's) import.

    Update2: I found it, in find_export_def(). A lot of indirection going on in that module. I'm still working out where find_export_def() is called from.

    Update3:Well, it looks like the whole problem is that find_export_def() isn't called, because export_import() is never called. It looks like you're exporting &export_import as the import routine that the user of the module will get, when you should be using it as your import routine and exporting the results of generate_import() (which is what you're actually using as your import routine). Um, or something?

    bbfu
    Black flowers blossum
    Fearless on my breath

      re update 3: I think if Module were importing &export_import instead of the result of generate_import, then nothing would work. The notation in the %EXPORT definition triggers this as a callback, not a hard link. So when Module imports import, it will call export_import and take the result of that call as the symbol to put in &Module::import.

      A lot of indirection: Yea, this module provides an import function to your module, which is then used by the client. Importing from Exporter::VA to Module is the same process as exporting from Module to Client. It's easy to get meta-levels confused. But I think it's wonderfully elegant.

      Thanks for looking it over. Any other critical comments on the code or POD?

      —John

      Found it: The line
      my $client_export_def= bless find_export_def ($caller, $param_list_ta +il), "Exporter::VA";
      was passing @_ instead of $param_list_tail to the find_export_def function. So it never found and removed it in the first place, and the error came later on as tye points out.

      That's what testing is for, especially in a language that doesn't find much at "compile time" like some others.