2014-03-04 3 views
5

Ich lerne immer noch Perl und ich wurde beauftragt, caller zu verwenden, um festzustellen, ob ein Unterprogramm von einem eval auf einer höheren Ebene aufgerufen wird. Ich soll mit etwas Code kommen, um dieses zu prüfen und Yes zu drucken, wenn es von einem eval oder No ist, wenn es nicht ist. Ich kann keine guten Beispiele finden, wie man caller im Internet benutzt und fragte mich, ob jemand irgendwelche Ideen oder Vorschläge hatte, wie man das macht.Wie kann ich feststellen, ob ein Unterprogramm innerhalb von eval mit Aufrufer aufgerufen wird?

+1

Haben Sie sich zuerst die [perldoc 'caller'-Referenzseite] (http://perldoc.perl.org/functions/caller.html) angesehen? Insbesondere scheint es, dass diese Funktion innerhalb einer Funktion von Interesse genannt würde; der '(eval)' - Marker würde nur in 'caller (1) [3]' (oder vielleicht 'caller (0) [3]') erscheinen, wenn diese interessierende Funktion "eval" war ... – abiessu

Antwort

2

Mit dem Code:

#!/usr/bin/perl -w 

eval "test_eval();"; 

test_eval(); 

sub test_eval { 
    my ($e,$v,$a,$l,) = caller(0); 

    print "[$e], [$v], [$a], [$l]\n"; 
} 

ich Ausgang

[main], [(eval 1)], [1], [main::test_eval] 
[main], [test.pl], [21], [main::test_eval] 

Aber wenn ich es ändern verwenden caller(1) dann bekomme ich

[main], [test.pl], [19], [(eval)] 
[], [], [], [] 

und mehrere Warnungen über nicht initialisierte Werte.

Dies sollte Ihnen einen Ausgangspunkt für die Arbeit geben. Beachten Sie, dass die Werte im Array nach Index 3 in diesem Programm ignoriert wurden, da sie sich nicht auf das vorliegende Problem beziehen, sondern auf the caller documentation zurückgehen, um herauszufinden, ob einer dieser Werte nützlich wäre.

Edit:

die Diskussion über und den Inhalt einer anderen Antwort, könnten Sie eine freche Lösung wie diese liefern:

sub func_under_eval { 
    if (0) { # change this to 1 when the time is right 
    return (defined($^S) and $^S>0)?"Yes":"No"; 
    } 
    else { 
    my @calls = caller(0); 
    my $back = 1; 
    while (defined($caller[0])) { 
     if (index("(eval", $caller[1] . $caller[3])>-1) 
     return "Yes"; 
     @calls = caller($back++); 
    } 
    return "No"; 
    } 
} 
5

Sie sollten hierfür nicht Anrufer werden. Siehe perlvar:

$EXCEPTIONS_BEING_CAUGHT 
$^S 
Current state of the interpreter. 

    $^S   State 
    --------- ------------------------------------- 
    undef  Parsing module, eval, or main program 
    true (1) Executing an eval 
    false (0) Otherwise 

The first state may happen in $SIG{__DIE__} and $SIG{__WARN__} handlers. 
The English name $EXCEPTIONS_BEING_CAUGHT is slightly misleading, because the 
undef value does not indicate whether exceptions are being caught, since 
compilation of the main program does not catch exceptions. 

This variable was added in Perl 5.004. 

Wie, warum:

C:\Users\user>perl -MBenchmark -E "timethese(20000000, {'caller' => sub {caller()}, '$^S' => sub {$^S}})" 
Benchmark: timing 20000000 iterations of $^S, caller... 
     $^S: 0 wallclock secs (0.11 usr + 0.00 sys = 0.11 CPU) @ 183486238.53/s (n=20000000) 
      (warning: too few iterations for a reliable count) 
    caller: 1 wallclock secs (0.87 usr + 0.00 sys = 0.87 CPU) @ 22909507.45/s (n=20000000) 

Und das ist, bevor wir den Anrufer Code unten mit einer Anzahl von Iterationen über den Call-Stack und Lauf String-Funktionen gegen Stack-Ebene Moor, Angenommen, wir schreiben fehlerfreien Code für alle Edge Cases usw.

Das Schreiben von Code, um den Aufrufer zu verwenden, um dies zu bestimmen, ist eine vollständige Neuimplementierung eines Kernmerkmals. Es ist, als würde man fragen: "Wie verwende ich Skalare, um eine verknüpfte Liste zu implementieren?" Die Antwort sollte lauten "Verwenden Sie ein Array", nicht "Hier ist wie!"

+0

Ich bin verwirrt, wie dies die Frage beantwortet ... Das OP wurde "beauftragt," Anrufer "... zu verwenden, um die spezifizierten Informationen zu bestimmen. Haben Sie ein Beispiel dafür, wie diese Variable in einem Skript erfolgreich verwendet werden könnte? – abiessu

+0

http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – Oesor

+1

@abiessu Ich würde einen ähnlichen Kommentar machen, aber diese Antwort wird sicherlich für zukünftige Besucher nützlich sein, auch wenn es liegt außerhalb des Aufgabenbereichs des OP (ich nehme Hausaufgaben an). – ThisSuitIsBlackNot

Verwandte Themen