Path: utzoo!attcan!uunet!wuarchive!sdd.hp.com!elroy.jpl.nasa.gov!jpl-devvax!lwall From: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Newsgroups: comp.lang.perl Subject: Re: knowing your current context Message-ID: <9958@jpl-devvax.JPL.NASA.GOV> Date: 13 Oct 90 20:42:41 GMT References: <107126@convex.convex.com> Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 66 In article <107126@convex.convex.com> tchrist@convex.com (Tom Christiansen) writes: : If I 'do' a file to get some subroutines defined, later call one of the : subroutines, and that routine uses a warn or die with out a trailing : \n, it is wrong claims that I was in my original calling file (the one : who 'did' the library file) not the library file. This is perhaps : arguably correct, but I wouldn't argue that way. Of course, the best : of all worlds would somehow tell me both. It also botches the line : number. I can't figure out where it's pulling that one from. This has been fixed already as part of implementing the caller function and making the debugger work for packages and evals. : Anybody know how to pull out the current file, line, package, and : subroutine from within a perl script? As you pointed out in your followup, __FILE__ and __LINE__ are available. But everything you want is available from the new caller function. It comes in two forms: ($package,$filename,$line) = caller; This just gives you where the current subroutine was called from. The other form is used in the debugger to print stack traces, more or less like this: local($p,$f,$l,$s,$h,$a,@a,@sub); for ($i = 1; ($p,$f,$l,$s,$h,$w) = caller($i); $i++) { @a = @args; for (@a) { if (/^StB\000/ && length($_) == length($_main{'_main'})) { $_ = sprintf("%s",$_); } else { s/'/\\'/g; s/([^\0]*)/'$1'/ unless /^-?[\d.]+$/; s/([\200-\377])/sprintf("M-%c",ord($1)&0177)/eg; s/([\0-\37\177])/sprintf("^%c",ord($1)^64)/eg; } } $w = $w ? '@ = ' : '$ = '; $a = $h ? '(' . join(', ', @a) . ')' : ''; print OUT "$w&$s$a from file $f line $l\n"; } The parameter to caller specifies how many stack frames to go back, and it returns the package, filename, line, subroutine name, whether the subroutine has arguments, and the value of wantarray for that subroutine. (It also magically sets @DB'args to be references to the arguments for that function. This form of the function is primarily for the debugger. Don't try this at home, kids.) : Also, are there any hazards from saying: : eval "package $some_package"; 'Tis a fancy no-op. Remember that packages are lexically scoped, so your new package name extends only to the end of the eval. Saying eval "package $some_package;" . '$foo = $bar'; makes better sense, and in fact the new debugger uses that sort of construct to make sure it references the variables in the package you're currently debugging. So you see how it all ties in. Larry