.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Regexp::Debugger 3pm" .TH Regexp::Debugger 3pm "2023-11-18" "perl v5.36.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Regexp::Debugger \- Visually debug regexes in\-place .SH "VERSION" .IX Header "VERSION" This document describes Regexp::Debugger version 0.002007 .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use Regexp::Debugger; .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" When you load this module, any regex in the same lexical scope will be visually (and interactively) debugged as it matches. .SH "INTERFACE" .IX Header "INTERFACE" The module itself provides no \s-1API.\s0 You load it and the debugger is automatically activated in that lexical scope. .PP The debugger offers the following commands: .ie n .IP """?""" 4 .el .IP "\f(CW?\fR" 4 .IX Item "?" : Print a help message listing these commands .ie n .IP """s""" 4 .el .IP "\f(CWs\fR" 4 .IX Item "s" : Step forward (stepping into any named subpattern calls) .ie n .IP """n""" 4 .el .IP "\f(CWn\fR" 4 .IX Item "n" : Step forward (stepping \fIover\fR any named subpattern calls) .ie n .IP """\-""" 4 .el .IP "\f(CW\-\fR" 4 .IX Item "-" : Step backward (stepping into any named subpattern calls) .ie n .IP """p""" 4 .el .IP "\f(CWp\fR" 4 .IX Item "p" : Step backward (stepping \fIover\fR any named subpattern calls) .ie n .IP """r""" 4 .el .IP "\f(CWr\fR" 4 .IX Item "r" : Continue forward until the end of the current (sub)pattern .ie n .IP """m""" 4 .el .IP "\f(CWm\fR" 4 .IX Item "m" : Continue forward to the next regex component that matches .ie n .IP """M""" 4 .el .IP "\f(CWM\fR" 4 .IX Item "M" : Continue forward to the next regex component that matches in the current (sub)pattern (i.e. silently stepping over any named subpattern calls) .ie n .IP """f""" 4 .el .IP "\f(CWf\fR" 4 .IX Item "f" : Continue forward to the next regex component that fails to match something .ie n .IP """F""" 4 .el .IP "\f(CWF\fR" 4 .IX Item "F" : Continue forward to the next regex component that fails to match something in the current (sub)pattern (i.e. silently stepping over any named subpattern calls) .ie n .IP """c""" 4 .el .IP "\f(CWc\fR" 4 .IX Item "c" : Continue forward until the entire regex matches or completely backtracks .ie n .IP """C""" 4 .el .IP "\f(CWC\fR" 4 .IX Item "C" : Continue forward until the entire regex matches or completely backtracks, silently stepping over any named subroutine calls .ie n .IP """R""" 4 .el .IP "\f(CWR\fR" 4 .IX Item "R" : Rewind to the start of the entire match .ie n .IP """/""" 4 .el .IP "\f(CW/\fR" 4 .IX Item "/" : Repeat the previous command .ie n .IP """v""" 4 .el .IP "\f(CWv\fR" 4 .IX Item "v" : Switch to regex/string visualization mode .ie n .IP """h""" 4 .el .IP "\f(CWh\fR" 4 .IX Item "h" : Switch to heatmapped visualization mode .ie n .IP """e""" 4 .el .IP "\f(CWe\fR" 4 .IX Item "e" : Switch to the event log .ie n .IP """j""" 4 .el .IP "\f(CWj\fR" 4 .IX Item "j" : Switch to the underlying \s-1JSON\s0 data .ie n .IP """d""" 4 .el .IP "\f(CWd\fR" 4 .IX Item "d" : Describe each component of the regex in detail .ie n .IP """V""" 4 .el .IP "\f(CWV\fR" 4 .IX Item "V" .PD 0 .ie n .IP """H""" 4 .el .IP "\f(CWH\fR" 4 .IX Item "H" .ie n .IP """E""" 4 .el .IP "\f(CWE\fR" 4 .IX Item "E" .ie n .IP """J""" 4 .el .IP "\f(CWJ\fR" 4 .IX Item "J" .ie n .IP """D""" 4 .el .IP "\f(CWD\fR" 4 .IX Item "D" .PD : Take a snapshot of the corresponding display mode. .Sp When prompted for a filename: .RS 4 .ie n .IP """""" 4 .el .IP "\f(CW\fR" 4 .IX Item "" \&...prints the snapshot to the terminal .ie n .IP """""" 4 .el .IP "\f(CW\fR" 4 .IX Item "" \&...prints the snapshot to a file named "./rxrx_\fI\s-1DISPLAY_MODE\s0\fR_\fI\s-1TIMESTAMP\s0\fR" .IP "Anything else" 4 .IX Item "Anything else" \&...prints the snapshot to that file .RE .RS 4 .RE .ie n .IP """q""" 4 .el .IP "\f(CWq\fR" 4 .IX Item "q" : Quit the debugger and finish matching this regex without any further visualization. The program continues to execute and other regexes may still be debugged. .ie n .IP """x""" 4 .el .IP "\f(CWx\fR" 4 .IX Item "x" : Exit the debugger and the entire program immediately. .SH "CONFIGURATION" .IX Header "CONFIGURATION" You can configure the debugger by setting up a \fI.rxrx\fR file in in the current directory or in your home directory. This configuration consists of single-line \fIkey\fR:\fIvalue\fR pairs (everything else in the file is silently ignored). .SS "Display mode configuration" .IX Subsection "Display mode configuration" If the \f(CW\*(C`\f(CW\*(Aqdisplay\*(Aq\f(CW\*(C'\fR key is specified, the debugger starts in that mode. The four available modes are: .PP .Vb 2 \& # Show dynamic visualization of matching (the default)... \& display : visual \& \& # Show dynamic heatmap visualization of matching... \& display : heatmap \& \& # Show multi\-line matching event log... \& display : events \& \& # Show JSON encoding of matching process... \& display : JSON .Ve .SS "Whitespace display configuration" .IX Subsection "Whitespace display configuration" Normally, the debugger compacts whitespaces in the regex down to a single space character, but you can configure that with the \&\f(CW\*(C`show_ws\*(C'\fR key: .PP .Vb 2 \& # Compact whitespace and comments to a single space (the default)... \& show_ws : compact \& \& # Compact whitespace, but show comments, newlines (\en), and tabs (\et)... \& show_ws : visible \& \& # Don\*(Aqt compact whitespace, and show newlines and tabs as \en and \et... \& show_ws : original .Ve .SS "Colour configuration" .IX Subsection "Colour configuration" The following keys reconfigure the colours with which the debugger displays various information: .PP \fIColours for debugging information\fR .IX Subsection "Colours for debugging information" .IP "\(bu" 4 \&\f(CW\*(C`try_col\*(C'\fR .Sp The colour in which attempts to match part of the regex are reported .IP "\(bu" 4 \&\f(CW\*(C`match_col\*(C'\fR .Sp The colour in which successful matches of part of the regex are reported .IP "\(bu" 4 \&\f(CW\*(C`fail_col\*(C'\fR .Sp The colour in which unsuccessful matches of part of the regex are reported .IP "\(bu" 4 \&\f(CW\*(C`ws_col\*(C'\fR .Sp The colour in which special characters (such as \*(L"\en\*(R", \*(L"\et\*(R", \*(L"\ee\*(R", etc.) are reported (as single letters: 'n', 't', 'e', etc.) .IP "\(bu" 4 \&\f(CW\*(C`info_col\*(C'\fR .Sp The colour in which other information is reported .PP \fIColours for regex descriptions\fR .IX Subsection "Colours for regex descriptions" .IP "\(bu" 4 \&\f(CW\*(C`desc_regex_col\*(C'\fR .Sp The colour in which components of the regex are displayed .IP "\(bu" 4 \&\f(CW\*(C`desc_text_col\*(C'\fR .Sp The colour in which descriptions of regex components are displayed .IP "\(bu" 4 \&\f(CW\*(C`desc_sep_col\*(C'\fR .Sp The colour in which separators between component descriptions are displayed. .PP \fIColours for heatmaps\fR .IX Subsection "Colours for heatmaps" .PP Any key that starts with \f(CW\*(C`heatmap\*(C'\fR... is treated as a specifier for an equal part of the total range of each heatmap. .PP These names are sorted (numerically, if possible; otherwise alphabetically) and the corresponding values are then used to display equal percentiles from the heatmap. .PP For example (using numeric sorting): .PP .Vb 3 \& heatmap_0_colour : cyan on_black # 0\-33rd percentile \& heatmap_50_colour : yellow on_black # 34\-66th percentile \& heatmap_100_colour : red on_black # 67\-100th percentile .Ve .PP Or, equivalently (using alphabetic sorting): .PP .Vb 3 \& heatmap_infrequent : cyan on_black # 0\-33rd percentile \& heatmap_more_frequent : yellow on_black # 34\-66th percentile \& heatmap_very_frequent : red on_black # 67\-100th percentile .Ve .PP \fIColour specifications\fR .IX Subsection "Colour specifications" .PP The colour values that may be used in any of the above colour specifications are any combination of the following (i.e. the colour specifiers supported by the Term::ANSIColor module): .PP .Vb 3 \& clear reset bold dark \& faint underline underscore blink \& reverse concealed \& \& black red green yellow \& blue magenta cyan white \& bright_black bright_red bright_green bright_yellow \& bright_blue bright_magenta bright_cyan bright_white \& \& on_black on_red on_green on_yellow \& on_blue on_magenta on_cyan on_white \& on_bright_black on_bright_red on_bright_green on_bright_yellow \& on_bright_blue on_bright_magenta on_bright_cyan on_bright_white .Ve .PP The default colour configurations are: .PP .Vb 5 \& try_col : bold magenta on_black \& match_col : bold cyan on_black \& fail_col : yellow on_red \& ws_col : bold blue underline \& info_col : white on_black \& \& desc_regex_col : white on_black \& desc_text_col : cyan on_black \& desc_sep_col : blue on_black underline \& \& heatmap_\|_20th_percentile : white on_black \& heatmap_\|_40th_percentile : cyan on_blue \& heatmap_\|_60th_percentile : blue on_cyan \& heatmap_\|_80th_percentile : red on_yellow \& heatmap_100th_percentile : yellow on_red .Ve .SS "Output configuration" .IX Subsection "Output configuration" Normally Regexp::Debugger sends its visualizations to the terminal and expects input from the same device. .PP However, you can configure the module to output its information (in standard \s-1JSON\s0 format) to a nominated file instead, using the \&\f(CW\*(Aqsave_to\*(Aq\fR option: .PP .Vb 1 \& save_to : filename_to_save_data_to.json .Ve .PP Data saved in this way may be re-animated using the \f(CW\*(C`rxrx\*(C'\fR utility, or by calling \f(CW\*(C`Regexp::Debugger::rxrx()\*(C'\fR directly. (See: \*(L"COMMAND-LINE \&\s-1DEBUGGING\*(R"\s0 for details). .SS "Configuration \s-1API\s0" .IX Subsection "Configuration API" You can also configure the debugger on a program-by-program basis, by passing any of the above key/value pairs when the module is loaded. .PP For example: .PP .Vb 1 \& use Regexp::Debugger fail => \*(Aqbold red\*(Aq, whitespace => \*(Aqcompact\*(Aq; .Ve .PP Note that any configuration specified in the user's \fI.rxrx\fR file is overridden by an explicit specification of this type. .PP The commonest use of this mechanism is to dump regex debugging information from an non-interactive program: .PP .Vb 1 \& use Regexp::Debugger save_to => \*(Aqregex_debugged.json\*(Aq; .Ve .PP Note that, when \f(CW\*(Aqsave_to\*(Aq\fR is specified within a program, the value supplied does not have to be a string specifying the filename. You can also provide an actual filehandle (or equivalent). For example: .PP .Vb 4 \& use Regexp::Debugger save_to => IO::Socket::INET\->new( \& Proto => "tcp", \& PeerAddr => \*(Aqlocalhost:666\*(Aq, \& ); .Ve .SH "COMMAND-LINE DEBUGGING" .IX Header "COMMAND-LINE DEBUGGING" The module provides a non-exported subroutine (\f(CW\*(C`rxrx()\*(C'\fR) that implements a useful command-line regex debugging utility. .PP The utility can be invoked with: .PP .Vb 1 \& perl \-MRegexp::Debugger \-E \*(AqRegexp::Debugger::rxrx\e(@ARGV\e)\*(Aq .Ve .PP which is usually aliased in the shell to \f(CW\*(C`rxrx\*(C'\fR (and will be referred to by that name hereafter). .SS "Regex debugging \s-1REPL\s0" .IX Subsection "Regex debugging REPL" When called without any arguments, \f(CW\*(C`rxrx\*(C'\fR initiates a simple \s-1REPL\s0 that allows the user to type in regexes and strings and debug matches between them: .IP "\(bu" 4 Any line starting with a \f(CW\*(C`/\*(C'\fR is treated as a new regex to match with. The closing \f(CW\*(C`/\*(C'\fR may be omitted. If the closing \f(CW\*(C`/\*(C'\fR is supplied, any one or more of the following flags may be specified immediately after it: \f(CW\*(C`x\*(C'\fR, \f(CW\*(C`i\*(C'\fR, \f(CW\*(C`m\*(C'\fR, \f(CW\*(C`s\*(C'\fR, \f(CW\*(C`a\*(C'\fR, \f(CW\*(C`u\*(C'\fR, \f(CW\*(C`d\*(C'\fR, \f(CW\*(C`l\*(C'\fR. .IP "\(bu" 4 Any line starting with a \f(CW\*(C`+/\*(C'\fR is treated as the first line of a new multi\- line regex to match with. Subsequent lines are added to the regex until the closing \f(CW\*(C`/\*(C'\fR is encountered. Any one or more of the following flags may be specified immediately after the closing \f(CW\*(C`/\*(C'\fR: \f(CW\*(C`x\*(C'\fR, \f(CW\*(C`i\*(C'\fR, \f(CW\*(C`m\*(C'\fR, \&\f(CW\*(C`s\*(C'\fR, \f(CW\*(C`a\*(C'\fR, \f(CW\*(C`u\*(C'\fR, \f(CW\*(C`d\*(C'\fR, \f(CW\*(C`l\*(C'\fR. .IP "\(bu" 4 Any line starting with a \f(CW\*(C`\*(Aq\*(C'\fR or \f(CW\*(C`"\*(C'\fR is treated as a new string to match against. The corresponding closing delimiter may be omitted. .IP "\(bu" 4 Any line beginning with \f(CW\*(C`m\*(C'\fR causes the \s-1REPL\s0 to match the current regex against the current string, visualizing the match in the usual way. .IP "\(bu" 4 Any line beginning with \f(CW\*(C`g\*(C'\fR causes the \s-1REPL\s0 to exhaustively match the current regex against the current string (i.e. as if the regex had a /g flag), visualizing all the matches in the usual way. .IP "\(bu" 4 Any line beginning with \f(CW\*(C`d\*(C'\fR causes the \s-1REPL\s0 to display a detailed decomposition and explanation of the current regex. .IP "\(bu" 4 Any line beginning with \f(CW\*(C`q\*(C'\fR or \f(CW\*(C`x\*(C'\fR causes the \s-1REPL\s0 to quit and exit. .IP "\(bu" 4 Any line beginning with \f(CW\*(C`?\*(C'\fR invokes the help listing for the \s-1REPL.\s0 .PP If the IO::Prompter module (version 0.004 or later) is available, the input process remembers its history, which you can recall by typing \&\f(CW\*(C`CTRL\-R\*(C'\fR. Repeated \f(CW\*(C`CTRL\-R\*(C'\fR's step successively backwards through earlier inputs. \f(CW\*(C`CTRL\-N\*(C'\fR steps successfully forward again. You can then use \f(CW\*(C`CTRL\-B\*(C'\fR/\f(CW\*(C`CTRL\-F\*(C'\fR/\f(CW\*(C`CTRL\-A\*(C'\fR/\f(CW\*(C`CTRL\-E\*(C'\fR to move the cursor around the line of recalled input, to delete or insert characters. This is useful for modifying and retrying a recently entered regex or string. .SS "Debugging regexes from a dumped session" .IX Subsection "Debugging regexes from a dumped session" When called with a filename, \f(CW\*(C`rxrx\*(C'\fR first checks whether the file contains a \s-1JSON\s0 dump of a previous debugging, in which case it replays the visualization of that regex match interactively. .PP This is useful for debugging non-interactive programs where the \&\f(CW\*(Aqsave_to\*(Aq\fR option was used (see \*(L"Output configuration\*(R" and \&\*(L"Configuration \s-1API\*(R"\s0). .PP In this mode, all the features of the interactive debugger (as listed under \*(L"\s-1INTERFACE\*(R"\s0) are fully available: you can step forwards and backwards through the match, skip to the successful submatch or a breakpoint, swap visualization modes, and take snapshots. .SS "Wrap-around regex debugging" .IX Subsection "Wrap-around regex debugging" When called with the name of a file that does \fInot\fR contain a \s-1JSON\s0 dump, \f(CW\*(C`rxrx\*(C'\fR attempts to execute the file as a Perl program, with Regexp::Debugger enabled at the top level. In other words: .PP .Vb 1 \& rxrx prog.pl .Ve .PP is a convenient shorthand for: .PP .Vb 1 \& perl \-MRegexp::Debugger prog.pl .Ve .SH "LIMITATIONS" .IX Header "LIMITATIONS" .ie n .SS """/x""\-mode comments" .el .SS "\f(CW/x\fP\-mode comments" .IX Subsection "/x-mode comments" Due to limitations in the Perl \f(CW\*(C`overload::constant()\*(C'\fR mechanism, the current implementation cannot always distinguish whether a regex has an external /x modifier (and hence, what whitespace and comment characters mean). Whitespace is handled correctly in almost all cases, but comments are sometimes not. .PP When processing a \f(CW\*(C`# comment to end of line\*(C'\fR within a regex, the module currently assumes a \f(CW\*(C`/x\*(C'\fR is in effect at start of the regex (unless that assumption causes the regex to fail to compile). This will sometimes cause erroneous behaviour if an unescaped \f(CW\*(C`#\*(C'\fR is used in a non\-\f(CW\*(C`/x\*(C'\fR regex. .PP Unfortunately, this limitation is unlikely to be fully removed in a future release, unless an additional flag-detection mechanism is added to \f(CW\*(C`overload::constant()\*(C'\fR. .PP Note, however, that this limitation does not affect the handling of comments in \&\f(CW\*(C`(?x:...)\*(C'\fR blocks or of literal \f(CW\*(C`#\*(C'\fR in \f(CW\*(C`(?\-x:...)\*(C'\fR blocks within a regex. These are always correctly handled, which means that explicitly using either of these blocks is a reliable workaround. Alternatively, there is no problem if you always use the \f(CW\*(C`/x\*(C'\fR modifier on every debugged regex (for example, via \f(CW\*(C`use re \*(Aq/x\*(Aq\*(C'\fR). Nor if you explicitly escape every literal \&\f(CW\*(C`#\*(C'\fR (i.e. write it as \f(CW\*(C`\e#\*(C'\fR). .PP As regards whitespace, the one case where the current implementation does not always correctly infer behaviour is where whitespace is used to separate a repetition qualifier from the atom it qualifies in a non\-\f(CW\*(C`/x\*(C'\fR regex, such as: .PP .Vb 1 \& / x + / .Ve .PP Because the module defaults to assuming that regexes always have \f(CW\*(C`/x\*(C'\fR applied, this is always interpreted as: .PP .Vb 1 \& /\e x+\e /x .Ve .PP rather than what it really is, namely: .PP .Vb 1 \& /\e x\e +\e / .Ve .PP The most reliable workaround for the time being is either to always use \&\f(CW\*(C`/x\*(C'\fR on any regex, or never to separate repetition qualifiers from their preceding atoms. .SS "Multiple 'save_to' with the same target" .IX Subsection "Multiple 'save_to' with the same target" At present, making the same file the target of two successive \f(CW\*(C`save_to\*(C'\fR requests causes the second \s-1JSON\s0 data structure to overwrite the first. .PP This limitation will be removed in a subsequent release (but this will certainly involve a small change to the structure of the \s-1JSON\s0 data that is written, even when only one \f(CW\*(C`save_to\*(C'\fR is specified). .SS "Variable interpolations" .IX Subsection "Variable interpolations" The module handles the interpolation of strings correctly, expanding them in-place before debugging begins. .PP However, it currently does not correctly handle the interpolation of \f(CW\*(C`qr\*(C'\fR'd regexes. That is, this: .PP .Vb 1 \& use Regexp::Debugger; \& \& my $ident = qr{ [^\eW\ed]\ew* }x; # a qr\*(Aqd regex... \& \& $str =~ m{ ($ident) : (.*) }xms; # ...interpolated into another regex .Ve .PP does not work correctly...and usually will not even compile. .PP It is expected that this limitation will be removed in a future release, however it may only be possible to fix the problem for more recent versions of Perl (i.e. 5.14 and later) in which the regex engine is re-entrant. .SH "DIAGNOSTICS" .IX Header "DIAGNOSTICS" .ie n .IP """Odd number of configuration args after ""use Regexp::Debugger""""" 4 .el .IP "\f(CWOdd number of configuration args after ``use Regexp::Debugger''\fR" 4 .IX Item "Odd number of configuration args after ""use Regexp::Debugger""" The module expects configuration arguments (see \*(L"Configuration \s-1API\*(R"\s0) to be passed as \f(CW\*(C`key => value\*(C'\fR pairs. You passed something else. .ie n .IP """Unknown \*(Aqshow_ws\*(Aq option: %s""" 4 .el .IP "\f(CWUnknown \*(Aqshow_ws\*(Aq option: %s\fR" 4 .IX Item "Unknown show_ws option: %s" The only valid options for the \f(CW\*(Aqshow_ws\*(Aq\fR configuration option are \&\f(CW\*(Aqcompact\*(Aq\fR, \f(CW\*(Aqvisible\*(Aq\fR, or \f(CW\*(Aqoriginal\*(Aq\fR. You specified something else (or misspelled one of the above). .ie n .IP """Unknown \*(Aqdisplay\*(Aq option: %s""" 4 .el .IP "\f(CWUnknown \*(Aqdisplay\*(Aq option: %s\fR" 4 .IX Item "Unknown display option: %s" The only valid options for the \f(CW\*(Aqdisplay\*(Aq\fR configuration option are \&\f(CW\*(Aqvisual\*(Aq\fR or \f(CW\*(Aqheatmap\*(Aq\fR or \f(CW\*(Aqevents\*(Aq\fR or \f(CW\*(AqJSON\*(Aq\fR. You specified something else (or misspelled one of the above). .ie n .IP """Invalid \*(Aqsave_to\*(Aq option: %s (%s)""" 4 .el .IP "\f(CWInvalid \*(Aqsave_to\*(Aq option: %s (%s)\fR" 4 .IX Item "Invalid save_to option: %s (%s)" The value associated with the \f(CW\*(Aqsave_to\*(Aq\fR option is expected to be a filehandle opened for writing, or else a string containing the name of a file that can be opened for writing. You either passed an unopened filehandle, an unwritable filename, or something that wasn't a plausible file. Alternatively, if you passed a filepath, was the directory not accessible to, or writeable by, you? .ie n .IP """Possible typo in %s""" 4 .el .IP "\f(CWPossible typo in %s\fR" 4 .IX Item "Possible typo in %s" Prior to executing each regex, the module checks for common regex problems that can be detected statically. For example, it looks for the two most common typos made when defining and calling independent subpatterns. Namely: writing \f(CW\*(C`(...)\*(C'\fR instead of \f(CW\*(C`(?...)\*(C'\fR and \f(CW\*(C`(&SUBPAT)\*(C'\fR instead of \f(CW\*(C`(?&SUBPAT)\*(C'\fR .Sp To silence these warnings, just fix the typos. .Sp Or, if the constructs are intentional, change \f(CW\*(C`(...)\*(C'\fR to \f(CW\*(C`(\e...)\*(C'\fR and \f(CW\*(C`(&SUBPAT)\*(C'\fR to \f(CW\*(C`(\e&SUBPAT)\*(C'\fR .SH "DEPENDENCIES" .IX Header "DEPENDENCIES" This module only works with Perl 5.10.1 and later. .PP The following modules are used when available: .IP "Term::ANSIColor" 4 .IX Item "Term::ANSIColor" Text colouring only works if this module can be loaded. Otherwise, all output will be monochromatic. .IP "Win32::Console::ANSI" 4 .IX Item "Win32::Console::ANSI" Under Windows, text colouring also requires that this module can be loaded. Otherwise, all output will be monochromatic. .IP "File::HomeDir" 4 .IX Item "File::HomeDir" If it can't find a useful value for \f(CW$ENV{HOME}\fR, Regexp::Debugger attempts to use this module to determine the user's home directory, in order to search for a \fI.rxrx\fR config file. .IP "\s-1JSON::XS\s0" 4 .IX Item "JSON::XS" .PD 0 .IP "\s-1JSON\s0" 4 .IX Item "JSON" .IP "\s-1JSON::DWIW\s0" 4 .IX Item "JSON::DWIW" .IP "JSON::Syck" 4 .IX Item "JSON::Syck" .PD \&\s-1JSON\s0 output (i.e. for the \f(CW\*(Aqsave_to\*(Aq\fR option) is only possible if one of these modules can be loaded. Otherwise, all \s-1JSON\s0 output will default to an empty \f(CW\*(C`{}\*(C'\fR. .IP "Term::ReadKey" 4 .IX Item "Term::ReadKey" Single-character interactions only work if this module can be loaded. Otherwise, all command interactions will require a \f(CW\*(C`\*(C'\fR after them. .IP "Time::HiRes" 4 .IX Item "Time::HiRes" Autogenerated timestamps (e.g. for snapshots) will only be sub-second accurate if this module can be loaded. Otherwise, all timestamps will only be to the nearest second. .SH "INCOMPATIBILITIES" .IX Header "INCOMPATIBILITIES" None reported, but this module will almost certainly not play nicely with any other that modifies regexes using \f(CW\*(C`overload::constant\*(C'\fR. .SH "BUGS AND LIMITATIONS" .IX Header "BUGS AND LIMITATIONS" No bugs have been reported. .PP Please report any bugs or feature requests to \&\f(CW\*(C`bug\-regexp\-debugger@rt.cpan.org\*(C'\fR, or through the web interface at . .SH "AUTHOR" .IX Header "AUTHOR" Damian Conway \f(CW\*(C`\*(C'\fR .SH "LICENCE AND COPYRIGHT" .IX Header "LICENCE AND COPYRIGHT" Copyright (c) 2011\-2012, Damian Conway \f(CW\*(C`\*(C'\fR. All rights reserved. .PP This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See perlartistic. .SH "DISCLAIMER OF WARRANTY" .IX Header "DISCLAIMER OF WARRANTY" \&\s-1BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE \*(L"AS IS\*(R" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION.\s0 .PP \&\s-1IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE\s0 (\s-1INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE\s0), \s-1EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\s0