Path: utzoo!attcan!uunet!zaphod.mps.ohio-state.edu!sol.ctr.columbia.edu!lll-winken!elroy.jpl.nasa.gov!jpl-devvax!lwall From: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Newsgroups: comp.lang.perl Subject: Re: subroutine as a parameter Message-ID: <10170@jpl-devvax.JPL.NASA.GOV> Date: 30 Oct 90 17:38:08 GMT References: <29351@pasteur.Berkeley.EDU> Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 48 In article <29351@pasteur.Berkeley.EDU> jhh@sprite.Berkeley.EDU (John H. Hartman) writes: : I'm trying to write my own sort routine that does a stable sort. : I can't figure out how to pass a subroutine as an argument. : Ideally my stable sort routine would take two parameters, the : comparison subroutine and the array to be sorted. Thanks. There's more than one way to skin this carp. Since you can call a subroutine indirectly through a scalar variable, you could just pass the subroutine name in as a string: &mysort('bynum', @array); sub mysort { local($by) = shift; sort $by @_; } sub bynum { $a <=> $b; } The chief difficulty with this is that it might get mixed up about package names unless you passed in a sort name like "package'bynum", if the sort is in a different package than the call to &mysort. One possible way around this is to use the caller function to figure out what package &mysort was called from, and qualify the subroutine name if necessary: $by = (caller)[0] . "'" . $by unless $by =~ /'/; Another way around this is to use the type glob to pass in the symbol table entry for the sort subroutine. You can also use it to pass the array more efficiently: &mysort(*bynum, *array); sub mysort { local(*by, *ar) = @_; sort by @ar; } sub bynum { $a <=> $b; } This doesn't get confused by differing packages (at least it won't after patch 38) because the symbol table entries you're passing in know which package they came from. Larry