Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

Defining a subroutine in another package

by jmay (Sexton)
on Jan 26, 2002 at 12:01 UTC ( #141745=perlquestion: print w/replies, xml ) Need Help??
jmay has asked for the wisdom of the Perl Monks concerning the following question:

perldoc perlmod sez:

Subroutine definitions (and declarations, for that matter) need not necessarily be situated in the package whose symbol table they occupy. You can define a subroutine outside its package by explicitly qualifying the name of the subroutine:

package main; sub Some_package::foo { ... } # &foo defined in Some_package

This is just a shorthand for a typeglob assignment at compile time:

BEGIN { *Some_package::foo = sub { ... } }

OK, my question: Is there a clean way to add a subroutine to another package, where the "other" package name is not known at compile time?

The best I can do is:

eval "*${package}::foo = sub { ... }";

but I'd rather not use eval if I don't have to.


Replies are listed 'Best First'.
Re: Defining a subroutine in another package
by japhy (Canon) on Jan 26, 2002 at 12:53 UTC
    Just leave eval() out of it. You can write: *{$package . "::foo"} = sub { ... };

    Jeff[japhy]Pinyan: Perl, regex, and perl hacker.
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

      I believe this only works in perl 5.6.0 and above though.

        It works for me on 5.004_5 and (I presume) even earlier, though you'll have to disable strict 'refs'.

        It's just a symbolic access to a typeglob, nothing special. :)

Re: Defining a subroutine in another package
by Aristotle (Chancellor) on Jan 27, 2002 at 00:13 UTC
    I think there's a way without circumventing strict, however I only have a vague recollection of something I read in the Camel book about this, way back when. I revolves around the %main:: hash.. I'm not sure how one would go about it though. I spent a while examining the output of perl -MData::Dumper -e'print Dumper(\%main::);' but can't seem to reach a useful conclusion. What I was looking for is a way to go through a hash lookup via $main::{$package}. Anyone up to fill the void?

    Makeshifts last the longest.

      Thank you for jogging my memory:
      use strict; my $sub = sub { print "Hello!\n"; }; my $var = 'Bar'; my $pak = 'Foo::'; my $ref = \%main::; $ref->{'Foo::'}{bar} = $sub; $main::{'Foo::'}{$var} = $sub; $ref->{$pak}{baz} = $sub; $main::{$pak}{boo} = $sub; Foo::bar(); Foo::Bar(); Foo::baz(); Foo::boo()
      Update: added variable package name examples
        Ah so I can use them that way. Data::Dumper produces entries like 'UNIVERSAL::' => *{'::UNIVERSAL::'} for keys denoting a package name, which confused me - can you explain what that is? Is that a symbolic typeglob reference, or something completely different? (Incidentally, typeglobs are the only part of Perl I never even came close to grokking. I understand what they are supposed to be, but the concept is still very alien.)

        Makeshifts last the longest.

        Is there a benefit to using this method over assigning the subref to a glob?

        Being right, does not endow the right to be rude; politeness costs nothing.
        Being unknowing, is not the same as being stupid.
        Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
        Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re: Defining a subroutine in another package
by perrin (Chancellor) on Jan 27, 2002 at 00:59 UTC
    You would probably be better off using callbacks or OO with inheritance for this.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://141745]
Approved by root
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2017-09-23 02:30 GMT
Find Nodes?
    Voting Booth?
    During the recent solar eclipse, I:

    Results (270 votes). Check out past polls.