jhh@sprite.Berkeley.EDU (John H. Hartman) (10/30/90)
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. John ----------------------------------------------------------------------- John H. Hartman Graduate Student, UCB Sprite project jhh@sprite.berkeley.edu
merlyn@iwarp.intel.com (Randal Schwartz) (10/31/90)
In article <29351@pasteur.Berkeley.EDU>, jhh@sprite (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. Does this help? ################################################## sub apply { local($function) = shift; do $function(@_); # call $function, passing remaining args } sub testit { print "args are <@_>\n"; } &apply("testit","arg","argg","arggh"); ################################################## print "Just another applied Perl hacker," -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Intel put the 'backward' in 'backward compatible'..."=========/
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (10/31/90)
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