in reply to This can't happen, can it?

Spiffy does weird things like source filtering and adding magic re-exporting to your code, which firstly makes your Perl look like Perl but behave really different, and secondly doesn't seem to work correctly. My guess is that the source filtering does not kick in for package two or is still active, even though you only "requested" it for package one. Try putting the two packages into separate files, or better, stay away from Spiffy.

I just now realized that you're using Class::Spiffy, which supposedly does not do source filtering, so I guess that just the exporting in Class::Spiffy messes up things. Try putting your packages into separate files to see if that improves things.

A third update: blokhead was initially correct. Setting @ISA does not import the stuff, or shouldn't. So you only get inheritance, but you don't get the magic Spiffy auto-exporting of functions.

Replies are listed 'Best First'.
Re^2: This can't happen, can it?
by henrylaxen (Novice) on Feb 20, 2006 at 23:12 UTC
    Well, what makes me think it might be a perl bug is the fact that two->can('function') returns true, in other words, package two DOES know how to 'function', yet on the very next line, after calling function(), we get:
    Undefined subroutine &two::function called at /home/henry/dev/spiffy_bug.pl line 12.

    So how can a package return true to -->can('function') and yet it can't execute function? It seems to me that that can't happen?

    Best wishes,
    Henry Laxen

      So how can a package return true to -->can('function') and yet it can't execute function? It seems to me that that can't happen?
      The same way that you can call 411 and get Joe Blow's phone number, and it automatically put you through, only to get "This number is no longer in service". That is, the can lookup doesn't jive with the execution mechanism.

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of

      Because can (in class form) does respect inheritance, while a fully specified function name (like foo::bar) does not respect inheritance. Look at the following reduced code:

      package Parent; sub foo { print "foo in parent(@_)\n"; }; sub bar { print "bar in parent(@_)\n"; }; package Child; @ISA = qw(Parent); sub foo { print "foo in child(@_)\n"; }; package main; eval { Child::foo(); }; warn $@ if $@; eval { Child->foo(); }; warn $@ if $@; eval { Child::bar(); }; warn $@ if $@; eval { Child->bar(); }; warn $@ if $@;
        Thank you Corion, that was very helpful. In the meantime I have also discovered the source of my confusion. I made the (wrong) assumption that simply saying
        our @EXPORT = qw(function);
        means that Spiffy would export function into package two. Actually what I need to do is declare that package one is the base class package two, like this:
        use one -base;
        The problem is that package two lives in the same file as package one, and this causes a compiler error. The whole thing can be resolved by adding:
        import one;
        after the
        @two::ISA = qw(one);
        Thus the final program, and its output is:
        #!/usr/bin/perl package one; use Class::Spiffy -base; our @EXPORT = qw(function); sub function { print "Function in package one\n" } package two; @two::ISA = qw(one); import one; print STDERR "Class::Spiffy version is ", $Class::Spiffy::VERSION, "\n +"; print STDERR "Can two function? ",two->can('function'), "\n"; function(); __END__ cd /home/henry/dev/ /usr/bin/perl -w /home/henry/dev/spiffy_bug.pl Class::Spiffy version is 0.15 Can two function? CODE(0x814b738) Function in package one Compilation finished at Tue Feb 21 10:37:35

        Thanks to all who have tried to be helpful in solving this mystery.
        Best wishes,
        Henry Laxen