Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

re-calling called functions

by opensourcer (Monk)
on Oct 28, 2006 at 17:25 UTC ( #581097=perlquestion: print w/replies, xml ) Need Help??
opensourcer has asked for the wisdom of the Perl Monks concerning the following question:

i have a package like this
package Tools; sub new { my ($caller, %args) = @_; my $caller_is_obj = ref($caller); my $class = $caller_is_obj || $caller; my $self = bless [], $class; return $self; } sub DIRUtil { my $self = shift; my ($path, $dirname, $option) = @_; if ($option eq "-c") { print $path."\n"; chdir($path) or die "$!"; mkdir ("xxx") or die "$!"; } }
here is the another package
package Agent my $Utils = new Tools; sub new { my ($caller, %args) = @_; my $caller_is_obj = ref($caller); my $class = $caller_is_obj || $caller; my $self = bless [], $class; return $self; } sub checkPackage { my $this = shift; my $package = "SB"; opendir(DIR, "D:/\box/\/\somthing/\SB") or $Utils->DIRUtil( "D:\/b +ox\/something", "SB", "-c"); }
here is the pl
ok, what i'm doing here, if there'nt a folder called SB, then the DIRUtil will create one, what i want to know is after creating the folder, i want the DIRUtil to callback the invoking function, here it is checkPackage, i don't want to hard code the checkPackage inside the DIRUtil, is there any way to call back the invoking function ?, there may be other functions calling the DIRUtil. note: im aware of typo error or any mis-spelled words/sentence, and well any lexicals, plz ingore those errors. thanks.

Replies are listed 'Best First'.
Re: re-calling called functions
by brian_d_foy (Abbot) on Oct 28, 2006 at 19:40 UTC

    Do you want to recall checkPackage so you get another chance to call opendir? Instead of gymnastics, just change checkPackage to check for the directory before it tries to open it. That way you don't have to re-dispatch to the calling method.

    $Utils->DIRUtil( ... ) unless -d $dir; opendir( ... );
    brian d foy <>
    Subscribe to The Perl Review
Re: re-calling called functions
by tsee (Curate) on Oct 28, 2006 at 18:42 UTC

    Now, I suggest you never, ever, ever do this. A subroutine should not knwo about its calling context aside from what wantarray or the Want module provide. It's good for some fun hacking, but it boils down to being an evil hack. Rethink your algorithm.

    That being said, it is possible in Perl. (No surprise, right?) It's just that it doesn't make any sense. Additionally, there are various corner cases which will break this.

    The following code kind of does what you want. I suggest you read up on the caller() function. Also, you can't call the calling subroutine with its original arguments.

    #!/usr/bin/perl use strict; use warnings; sub _gotocaller { my $i = 2; while (1) { my ($pkg, $file, $line, $sub) = caller($i); if (not defined $pkg) { # no caller return; } elsif ($sub =~ /::__ANON__$/ or $sub eq '(eval)') { $i++; } else { no strict; goto &{"$sub"}; die; } } } my $x = 1; sub foo { print "foo: $x\n"; if ($x < 10) { print join("|", caller(1)), "\n"; _gotocaller() or die "shouldn't be reached if there was an enc +losing subroutine!"; } } sub bar { print "bar: $x\n"; foo($x++); } bar();

    Note that there are many things wrong with this code and I even thought about discarding the post when I looked at it again. To name just a few: symbolic references, goto &sub (which wouldn't be so bad if it wasn't used in conjunction with symbolic references and caller()), breaks for anonymous subs and eval's (or rather: calls the named sub that called the anonymous sub or eval block), etc.

    Please, promise to not use this code. :/


Re: re-calling called functions
by GrandFather (Sage) on Oct 28, 2006 at 19:34 UTC

    how about:

    sub DIRUtil { my $self = shift; my $caller; $caller = shift if ref $_[0]; my ($path, $dirname, $option) = @_; while ($option eq "-c") { print $path."\n"; chdir($path) or next; mkdir ("xxx") or next; return; } continue { # failure handling $caller->() if $caller; return; } }


    sub caller { $other->DIRUtil (&caller, ...); }

    Of course the failure handling in DIRUtil needs to exit early if directory creation failed.

    BTW, $Utils = new Tools; is an error and the quoting in "D:/\box/\/\somthing/\SB" is bogus. /'s don't need to be quoted and as written it is the following letter that is needlessly quoted in any case. Using strictures (use strict; use warnings;) would pick up at least some of these problems for you.

    DWIM is Perl's answer to Gödel

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://581097]
Approved by ww
Front-paged by andyford
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2018-02-21 21:37 GMT
Find Nodes?
    Voting Booth?
    When it is dark outside I am happiest to see ...

    Results (288 votes). Check out past polls.