Skip to main content
Ctrl+K
PetaPerl - Home PetaPerl - Home
  • מבוא
  • תחילת העבודה
  • אפשרויות CLI
  • מדריכי הדרכה
  • Reference
  • Errata
  • מבוא
  • תחילת העבודה
  • אפשרויות CLI
  • מדריכי הדרכה
  • Reference
  • Errata

Section Navigation

  • PPerl Architecture
    • JIT Compilation
    • Auto-FFI (Peta::FFI)
    • Native Modules
    • Differences from Perl 5
  • Concurrent Execution
    • Parallel Execution
    • Threads
      • ithreads basics
      • Shared data
      • Alternatives to ithreads
  • ביטויים רגולריים
    • יסודות
    • מחלקות תווים
    • עוגנים והיגדים
    • מכמתים
    • קבוצות ולכידות
    • ברירה
    • מתאמים
    • החלפה
    • יוניקוד
    • ביצועים
    • השוואה בין־מנועית
  • ביצועים
    • מדידה
    • ניבים
    • מיון
    • כתיבת pperl מהיר
  • תכנות מונחה־עצמים
    • מחלקות מודרניות
    • OO קלאסי
    • ירושה ופתרון מתודות
    • תפקידים והאצלה
    • העברה מהקלאסי למודרני
  • ניפוי שגיאות בתוכניות Perl
    • Preflight: תפיסת באגים לפני זמן ריצה
    • ניפוי שגיאות באמצעות print, warn, ומשפחת Carp
    • חריגות, die, ועצמי שגיאה מטופסים
    • מנפה השגיאות האינטראקטיבי
    • Breakpoints, actions, ו־watches
    • בחינת מצב
    • Tracing: צפייה בזרימת הביצוע
    • שילוב IDE ו־DAP
  • המדריך המלא לחד־שורתיים ב־Perl
    • ה־switches
    • מתכונים מתקדמים
    • חד־שורתיים מבוססי regex
    • חד־שורתיים מספריים ושל תאריכים
    • מחד־שורתי ל־alias של shell
    • מלכודות והפתעות
  • קישור משתנים
    • סקלרים קשורים
    • האשים קשורים
    • מערכים קשורים
    • מטפלי קובץ קשורים
  • מגיעים משפה אחרת
    • מ־Python ל־Perl
    • מ־PHP ל־Perl
    • מ־Ruby ל־Perl
    • מ־Lua ל־Perl
    • מ־sed ל־Perl
    • מ־awk ל־Perl
    • מ־shell ל־Perl
    • מ־Tcl ל־Perl
  • The Definitive Guide to Graphics with Perl
    • Foundations: pixels, paths, and color
    • Drawing primitives from scratch
    • Raster drawing with Imager
    • GD and ImageMagick when you need them
    • Vector graphics: Cairo and SVG
    • Image metadata and applied 2D charting
    • 2D on a screen: GUI canvases
    • Reaching further: Peta::FFI for graphics
    • A native Cairo binding, shipped
    • Capstone: a drawing application
    • Capstone: a 2D game
    • Known gaps and what’s next
  • pack ו־unpack - הדרכה
    • בתים ורוחבים
    • Endianness
    • מחרוזות, ביטים וחצאי־בתים
    • קיבוץ ומונים
    • מיקום וריפוד
    • פרוטוקולי רשת - שאילתת DNS
    • פורמטים של קבצים - כותרת GIF
  • Opening files
    • Reading, writing, appending
    • Encoding and layers
    • Pipes
    • In-memory handles
    • Handling errors
  • הפניות - הדרכה
    • יסודות - לקיחת הפניות ושימוש בהן
    • מערכים של מערכים
    • האשים ומבנים מעורבים
    • הפניות אנונימיות - [...] ו־{...}
    • הפניות לתת־שגרה
    • הפניות חלשות
  • Unicode - a tutorial
    • Strings and encodings
    • קלט/פלט
    • Regex ותכונות
    • Pitfalls
    • מתכונים
  • לוגיקה בוליאנית למתכנתי Perl - הדרכה
    • אמיתיוּת
    • אופרטורים
    • טבלאות אמת
    • חוקי דה־מורגן
    • שלמות פונקציונלית
    • יישומים
  • תקשורת בין־תהליכית - הדרכה
    • תהליכי משנה ו־co-processes
    • FIFOs
    • סוקטים של TCP
    • סוקטים של UNIX-domain ו־UDP
    • System V IPC
  • מדריכי הדרכה
  • ניפוי שגיאות בתוכניות Perl
  • ניפוי שגיאות באמצעות print, warn, ומשפחת Carp

ניפוי שגיאות באמצעות print, warn, ומשפחת Carp#

פרק זה מכסה אבחונים לא־אינטראקטיביים: prints מוטמעים, dumps של משתנים, stack traces מתוך התוכנית. טכניקות אלה נשארות המסלול המהיר ביותר להבנה של ״מה הקוד שלי באמת רואה כאן?״ עבור באגים שזולים לשחזור.

קוראים שכבר מכירים את print ואת warn ימצאו כאן את הווריאנטים המובנים השווים את המאמץ: משפחת Carp לדיווח מצד הקורא, Data::Dumper והחלופות המודרניות שלו, ושורות־פקודה אחת ל־stack-trace בכל מקום.

warn מול print - בחירת הזרם הנכון#

warn כותבת ל־STDERR; print משתמשת ב־STDOUT כברירת מחדל. השתמשו ב־warn עבור אבחונים: היא שומרת על פלט תוכנית נקי, שורדת הפניית STDOUT מחדש, והיא הזרם שלוגרים כבר לוכדים.

warn "*** foo=[$foo] bar=[@bar]\n";

עטפו ערכים בסוגריים מילוליים כדי שרווחים גוררים ושורות חדשות יהיו גלויים בפלט. "foo=[$foo]" חושף foo=[  ] שבו "foo=$foo" מציג רק foo= .

ללא \n גורר, warn (ו־die) מצרפים at FILE line N. מנקודת המבט של הקורא. עם \n, הם לא. כלל אצבע: צרפו \n עבור הודעות הפונות למשתמש; השמיטו אותו עבור אבחונים למפתחים שעבורם נחוץ המיקום.

תגיות מיקום זולות מהקומפיילר:

warn "reached $0 " . __FILE__ . ':' . __LINE__ . "\n";
warn "in @{[__SUB__->name]}\n";          # 5.16+

משפחת Carp - דיווח מצד הקורא#

כאשר פונקציית ספרייה נכשלת, הצבעה על המקור של הספרייה עצמה כמעט אף פעם לא שימושית. משפחת Carp מדווחת מהמסגרת של הקורא:

פונקציה

מדווחת מ

fatal?

stack trace?

carp

caller

לא

לא

croak

caller

כן

לא

cluck

caller

לא

מלא

confess

caller

כן

מלא

use Carp;

sub open_config {
    my $path = shift // croak "open_config: missing path";
    open my $fh, '<', $path or croak "cannot read $path: $!";
    return $fh;
}

קוד ספרייה צריך להשתמש ב־croak/carp, לא ב־die/warn - הודעת השגיאה מצביעה על שורת הקורא, ששם נכנס התיקון.

Stack traces מבלי לגעת בקוד#

Carp::Always מתקין את $SIG{__DIE__} ואת $SIG{__WARN__} כדי לנתב דרך Carp::confess / Carp::cluck. הריצו סקריפט מתנהג בצורה שגויה עם:

perl -MCarp::Always script.pl

כל die ו־warn מפיקים מחסנית מלאה. ללא שינויים במקור. זה הדבר הראשון לפנות אליו כשקריסה מספקת הודעת שורה־אחת חסרת שימוש.

Devel::Confess הוא מקבילה drop-in עם פחות מקרי קצה סביב עצמים בעלי overloading:

perl -d:Confess script.pl

שני המודולים מוסיפים עלות לכל warn ו־die; השתמשו בהם במהלך חקירה, לא בייצור יציב.

להתקנה קבועה בתוך הקוד:

use Carp;
$SIG{__DIE__}  = sub { return if $^S; Carp::confess(@_) };
$SIG{__WARN__} = sub { Carp::cluck(@_) };

return if $^S; - ״לחזור אם אנו בתוך eval״. ללא שמירה זו, כל חריגה נתפסת משלמת את עלות העקבה. ראו exceptions עבור התבנית המלאה של $SIG{__DIE__}.

Dumping של מבני נתונים#

העבירו הפניה לכל dumper; ביצוע dump ל־hash או למערך חשופים מדפיס את הצורה השטוחה־כרשימה שלהם ומאבד את המבנה.

Data::Dumper - אוניברסלי, מודול core, ניתן ל־roundtrip דרך eval#

use Data::Dumper;

$Data::Dumper::Sortkeys = 1;
$Data::Dumper::Indent   = 1;
$Data::Dumper::Terse    = 1;
$Data::Dumper::Deepcopy = 1;

warn Dumper(\%config);
  • Sortkeys הופך את הפלט ליציב ב־diff.

  • Indent=1 היא ההגדרה הקריאה (0 = שטוח, 2 = ברירת מחדל, 3 = עם אינדקסי מערך).

  • Terse=1 מדכא את קידומות $VAR1 = כשאינכם זקוקים ליכולת round-trip.

  • Deepcopy=1 משבית את המעקב ״ראיתי את ההפניה הזו קודם״ של $VAR1->{...} - מדפיס את הנתונים, לא שחזור של גרף.

Data::Dumper::Concise הוא drop-in עם ברירות מחדל הגיוניות מיושמות מראש; הסטנדרט בקהילת DBIx::Class / Moose.

Data::Printer - צבעוני, מודרני, קריא#

use DDP;
p %config;                    # not a reference - DDP handles both

Data::Printer מדפיס פלט נראה־טוב יותר מ־Data::Dumper, צובע לפי טיפוס, מטפל בעצמים באופן מיוחד (מחלקה, מאפיינים, overloads), ואינו מנסה לבצע round-trip. העדיפו אותו כאשר המטרה היא קריאת ה־dump, לא הזנתו מחדש למערכת.

Data::Dump - שורה־אחת קומפקטית#

use Data::Dump qw(dd);
dd \%config;                  # prints to STDERR in compact form

ה־Data::Dump של Gisle Aas. שימושי כאשר פלט ברירת המחדל של Data::Dumper מילולי מדי עבור שורת warn יחידה.

מתי לפנות אל מה#

  • Data::Dumper כאשר ייתכן שתזינו את הפלט בחזרה ל־eval או תשוו שני dumps.

  • Data::Printer (DDP) כאשר אדם קורא את הפלט.

  • Data::Dump כאשר רוצים סיכום בשורה אחת.

  • Data::Dumper::Concise בפרויקטים שכבר משתמשים בו.

debug prints מותנים#

קבוע של זמן־הידור עובר אופטימיזציה מלאה והוסר כאשר הוא שקרי:

use constant DEBUG => 0;

warn "state=$state\n" if DEBUG;

עם DEBUG => 0, הבדיקה if DEBUG מתקפלת בזמן הידור וה־warn אינה מופיעה מעולם ב־op tree - עלות אפס בזמן ריצה.

חברו לסביבה כדי שניתן יהיה להפוך את הדגל ללא עריכה:

use constant DEBUG => $ENV{APP_DEBUG} // 0;

ערוצים מרובים באמצעות bitmask:

use constant { WEB => 1, SQL => 2, REGEX => 4 };
my $DEBUG = $ENV{APP_DEBUG} // 0;

sub dbg { my $c = shift; warn "[DBG] @_\n" if $DEBUG & $c }

dbg WEB,   "request $req_id start\n";
dbg SQL,   "query: $sql\n";
dbg REGEX, "matched: $&\n";         # (unless you care about perf - see below)

חלופת source-filter: Smart::Comments#

use Smart::Comments;

my @stuff = compute();
### @stuff                 # prints: @stuff: [...]
### Checking key: $key     # print, plus asserts $key is truthy
### Processing |=| ... for @stuff

שורות המתחילות ב־### נכתבות מחדש כ־prints (ועם תחביר מיוחד, פסי התקדמות ו־assertions). המודול הוא source filter - הוא משכתב את טקסט התוכנית לפני ההידור - ולכן מספרי שורות מדווחים יכולים לסטות בשורה אחת. כאשר אינו מיובא, הערות ה־### מתהדרות לכלום. הסטייה היא המחיר של אי־עומס הקוד בשורות warn מפורשות.

Taint ו־$& - עלויות לוואי שכדאי להכיר#

הפניה אל $&, $`, או $' בכל מקום בתוכנית מאלצת את perl לתחזק את הגלובלים האלה של הקשר התאמה עבור כל התאמת regex בתוכנית כולה, כולל התאמות בתוך מודולים טעונים. היסטורית, הדבר הטיל האטה ניכרת; ב־perls מודרניים העלות קטנה יותר אך אינה אפס, והכלל עדיין בתוקף: אל תגעו בהם אם ניתן להימנע מכך.

השתמשו ב־@- / @+ (מערכי מיקום של התאמה), לכידות בעלות שם, או במתאם /p עם ${^MATCH}, ${^PREMATCH}, ${^POSTMATCH} במקום. הווריאנטים של /p מטילים את העלות רק על התאמות שמצטרפות במפורש.

לוגינג עם חותמת זמן#

warn שנכתב ידנית עם localtime מספיק לחקירות חד־פעמיות:

use Time::HiRes qw(gettimeofday);
sub t { my ($s, $us) = gettimeofday; sprintf "%d.%06d", $s, $us }
warn sprintf "[%s] state=%s\n", t(), $state;

לכל דבר מובנה יותר, השתמשו ב־framework לוגינג במקום לפתח משלכם:

  • Log::Any - בטוח לספריות; לפלוט לוגים מבלי לבחור backend. שלבו עם מתאם (Log::Any::Adapter::Log4perl, ::Stdout, ::Syslog) ביישום.

  • Log::Log4perl - קטגוריה / רמה / appender / layout; מונע על־ידי קובץ הגדרות.

  • Log::Dispatch - נתב ברמה נמוכה יותר; משמש לעיתים קרובות תחת Log::Any.

רמות סטנדרטיות, מהנמוכה לגבוהה: TRACE, DEBUG, INFO, WARN, ERROR, FATAL. הגנו על TRACE / DEBUG מאחורי דגל סביבה בייצור.

למידע נוסף#

  • exceptions - die, $@, $SIG{__DIE__}, מחלקות חריגה מטופסות, ה־try/catch המודרני.

  • interactive-debugger - כאשר הוספת prints עולה יותר מהפעלת perl -d.

  • tracing - עקבה של תוכנית שלמה שורה־אחר־שורה ללא עריכת המקור.

הקודם

Preflight: תפיסת באגים לפני זמן ריצה

הבא

חריגות, die, ועצמי שגיאה מטופסים

On this page
  • warn מול print - בחירת הזרם הנכון
  • משפחת Carp - דיווח מצד הקורא
  • Stack traces מבלי לגעת בקוד
  • Dumping של מבני נתונים
    • Data::Dumper - אוניברסלי, מודול core, ניתן ל־roundtrip דרך eval
    • Data::Printer - צבעוני, מודרני, קריא
    • Data::Dump - שורה־אחת קומפקטית
    • מתי לפנות אל מה
  • debug prints מותנים
  • חלופת source-filter: Smart::Comments
  • Taint ו־$& - עלויות לוואי שכדאי להכיר
  • לוגינג עם חותמת זמן
  • למידע נוסף
Source (accessible & AI-friendly)

© 2025-present PetaMem, s.r.o.  ·  rendered —

Documentation under development!

כתב ויתור & דיווחי באגים  ·  רישיון  ·  הורדת pperl