Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!swrinde!elroy.jpl.nasa.gov!jpl-devvax!lwall From: lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) Newsgroups: comp.lang.perl Subject: Re: package switching Message-ID: <1991May1.215509.18346@jpl-devvax.jpl.nasa.gov> Date: 1 May 91 21:55:09 GMT References: <1991May1.200904.3640@iwarp.intel.com> Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Distribution: comp Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 65 In article <1991May1.200904.3640@iwarp.intel.com> merlyn@iwarp.intel.com (Randal L. Schwartz) writes: : In article , dnb@meshugge (David N. Blank) writes: : | How do I do it? I have seen Randall use this idiom: : ======= s/l// # :-) No, the first l is the correct one, so you want to delete the second one: s/(l)l/$1/ # :-) : | > $ret = eval "package main; $action" : | : | but I would prefer not to stick the entire contents of a subroutine : | into one scalar variable. Is there some magic way to expand the : | scope of the package commands? Thanks. : : You could do something like: : : package smurf; : : sub whatIreallywannado { : foo; : foo; : foo; : } : : sub user_calls { : eval "package $bar; &smurf'whatIreallywannado;"; die $@ if $@; : } : : That way, what you are evalling is only a little piece of text instead : of the whole thing. Does that make you happier? I don't think that's going to help, since what he really wants (I think) is to write generic routines that work for the variables in multiple packages. The variables of smurf'whatIreallywannado are going to be in package smurf, not package $bar. The package phrase is one of the few real compile-time declarations in Perl, and there is no automatic mechanism currently in place for doing package resolution of variables at runtime. There are currently only three ways to do generics that I know of: 1) pass in the scalar variables you want to tinker with via $_[0], 2) pass in the names you want to tinker with via *foo, or 3) use eval. However, there nothing that says you have to use a scalar variable: eval "package $whatever; " . <<'END'; foo; foo; foo; END Actually, method 2 doesn't really need to have the variables passed in, if you mix in a bit of method 3. You could say: sub swap_a_b { package swap_a_b; ($pack) = caller; eval "*a = *${pack}'a; *b = *${pack}'b"; ($a,$b) = ($b,$a); } Larry Wall lwall@netlabs.com