Print debugging statement: Difference between revisions

m
(J)
m (→‎{{header|Wren}}: Minor tidy)
 
(5 intermediate revisions by 4 users not shown)
Line 14:
=={{header|Applesoft BASIC}}==
Debugging commands TRACE and NOTRACE turn on and off showing line numbers as the program runs. The LIST command can be embedded in the program to display lines of the program. The RUN command can used to start the program at a specific line number. The STOP command stops the program and displays an error message. The CLEAR and RUN commands clear all variables.
<langsyntaxhighlight lang="gwbasic"> 0 PRINT "START"
1 IF DEBUG THEN LIST 1: PRINT "TEST"
2 IF DEBUG THEN LIST 2: TRACE
Line 20:
4 IF DEBUG THEN LIST 4, 6: PRINT "ALPHA" : RUN 4
5 NOTRACE
6 LIST 6: PRINT "END"</langsyntaxhighlight>
<syntaxhighlight lang ="gwbasic">RUN</langsyntaxhighlight>
{{out}}
<pre>
Line 33:
END
</pre>
<langsyntaxhighlight lang="gwbasic">CLEAR:DEBUG=1:GOTO</langsyntaxhighlight>
{{out}}
<pre>
Line 61:
C doesn't have a built-in print debugging statement. However, it can be defined by users as a macro.
 
<langsyntaxhighlight Clang="c">#include <stdio.h>
 
#define DEBUG_INT(x) printf( #x " at line %d\nresult: %d\n\n", __LINE__, x)
Line 77:
add(2, 7);
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 95:
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <iostream>
 
// requires support for variadic macros in this form
Line 107:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|COBOL}}==
Line 114:
Explicit debug usually just uses DISPLAY, and usually directed at SYSERR. Compiler Directing Facility debug is supported with <code>>>D</code> directive statements. GnuCOBOL also supports full on line step tracing, controlled by both compile time switch, <code>-ftraceall</code>, and a truthy setting in a `COB_SET_TRACE` environment variable (so program step logging can be switched on and off without a recompile (for tracking down pesky production run mysteries)).
 
<langsyntaxhighlight lang="cobol">gcobol*>
*> steptrace.cob
*> Tectonics: cobc -xj -fdebugging-line -ftraceall steptrace.cob
Line 134:
display "from " FUNCTION MODULE-ID " in " FUNCTION MODULE-SOURCE
goback.
end program steptrace.</langsyntaxhighlight>
 
That is fixed form COBOL, columns 1 through 6 ignored by the preprocessor (historical format, from the days of punch card input) with column 7 being a special indicator column, star for comments, dash for continuations, and D is supported by GnuCOBOL for Debug lines. The <code>>>D</code> form is a newer addition to the Compiler Directing Facility, and can float anywhere on a free format compile line.
Line 166:
Using templates and default arguments provides options for specifying a debug function.
The file and line could be included as either template arguments or function arguments.
<langsyntaxhighlight lang="d">import std.stdio;
 
void debugln(string file = __FILE__, size_t line = __LINE__, S...)(S args) {
Line 185:
debugWrite("Goodbye", ' ', "world", '!');
}
</syntaxhighlight>
</lang>
{{out}}
<pre>[debug.d@12]
Line 197:
{{libheader| System.sysutils}}
Delphi has a "OutputDebugString" for debug, but not give lines and filename of source.
<syntaxhighlight lang="delphi">
<lang Delphi>
program DebugApp;
 
Line 215:
writeln(Add(2, 7));
readln;
end.</langsyntaxhighlight>
 
In next we have a workaround using a idea from '''user3989283'''[[https://stackoverflow.com/questions/7214213/how-to-get-line-number-at-runtime]]. This code override the default assert function to gain access to line and file name.
Obs.: In this example default action of assert is disabled, but you can enable calling in HookAssert (at end).
 
<syntaxhighlight lang="delphi">
<lang Delphi>
program DebugApp;
 
Line 278:
 
ReleaseDebug;
end.</langsyntaxhighlight>
{{out}}
Example log:
<pre>[26/08/2020 18:56:51] [Line: 0051] File: ...\Debug\DebugApp.dpr
<pre>
2 + 7 = 9</pre>
[26/08/2020 18:56:51] [Line: 0051] File: ...\Debug\DebugApp.dpr
 
2 + 7 = 9
=={{header|FreeBASIC}}==
</pre>
{{works with|FreeBASIC|0.16.1+}}
Using intrinsic Definitions (macro value) set by the compiler
<syntaxhighlight lang="vb">#if __FB_DEBUG__ <> 0
#print Debug mode
Dim err_command_line As Ubyte
err_command_line = __fb_err__
Select Case err_command_line
Case 0
Print "No Error Checking enabled on the Command Line!"
Case 1
Print "Some Error Checking enabled on the Command Line!"
Case 3
Print "QBasic style Error Checking enabled on the Command Line!"
Case 7
Print "Extreme Error Checking enabled on the Command Line!"
Case Else
Print "Some Unknown Error level has been set!"
End Select
#else
#print Release mode
#endif
 
Sleep</syntaxhighlight>
 
=={{header|Go}}==
Go doesn't have a built-in print debugging statement as such. Nor does it have macros.
Line 291 ⟶ 315:
 
Note that a label for the expression (whether it's a simple variable or not) must be passed to the 'debug' function as there is no way to deduce it otherwise.
<langsyntaxhighlight lang="go">package main
 
import (
Line 326 ⟶ 350:
q := &p
debug("q", q)
}</langsyntaxhighlight>
 
{{out}}
Line 353 ⟶ 377:
"q" at line 35 type '*main.point'
value: &main.point{x:2, y:3}
</pre>
 
=={{Header|Insitux}}==
 
Here's one method of debugging programs I like to demonstrate: mocking every built-in operation with a function that executes the operation and afterwards outputs its parameters and result.
 
<syntaxhighlight lang="insitux">
(for s (-> (symbols)
(filter about)
(remove ["print" "mock" "unmocked" "unmock" "do" "reset"]))
(mock s (fn (let result ((unmocked ...) (unmocked s) args))
(print "(" s " " ((unmocked join) " " args) ") => " result)
result)))
 
(function inside-2d? X Y areaX areaY areaW areaH
(and (<= areaX X (+ areaX areaW))
(<= areaY Y (+ areaY areaH))))
 
(inside-2d? 50 50 0 0 100 100)
</syntaxhighlight>
 
{{out}}
 
<pre>
(fast+ 0 100) => 100
(<= 0 50 100) => true
(fast+ 0 100) => 100
(<= 0 50 100) => true
true
</pre>
 
For obtaining line and column number, the special value <code>err-ctx</code> evaluates as its own source position.
 
<syntaxhighlight lang="insitux">
err-ctx
</syntaxhighlight>
 
{{out}}
 
<pre>
{:line 1, :col 1}
</pre>
 
=={{header|J}}==
J does not provide any specialized debugging statements. So we might typically use <code>echo</code>. But, we could define <code>dump=:{{y[echo(,:x,':&nbsp;'),&.|:1&nbsp;1}._1&nbsp;_1}.":<y }}</code> which would let us include informative labels in the debugging output. Thus, for example, we could use function composition to see what's going on inside a J expression like this:<langsyntaxhighlight Jlang="j"> $i.3 3
3 3
$'a' dump i.3 3
Line 362 ⟶ 427:
3 4 5
6 7 8
3 3</langsyntaxhighlight> Or, like this:<syntaxhighlight lang J="j"> +/\2 3 5 7
2 5 10 17
' sum'&dump@+/@('list'&dump)\2 3 5 7
Line 375 ⟶ 440:
sum: 15
sum: 17
2 5 10 17</langsyntaxhighlight>Caution: this approach disables J's internal optimizations for frequently used expressions (in the above example, J uses associativity to increase the performance of +/\ from O(n^2) to O(n), but the <tt>dump</tt> version gains no such benefit).<br /><br />
That said, we could also rely on J's debugging information if we did not want to provide explicit labels for everything (this would not usefully distinguish between different points on the same line). For example: <langsyntaxhighlight lang="j">dump=: {{
if.#d=.13!:13'' do.
echo (,:': ',~;:inv":&.>0 2{1{d) ,&.|:1 1}._1 _1}.":<y
end.
y
}}</langsyntaxhighlight>
 
Here, we get debugging output only if debugging is enabled. And we're annotating each value with the name of the routine, and the line within that routine. Thus:
<langsyntaxhighlight Jlang="j">example=: {{
j=. 1
dump r=. 2
Line 395 ⟶ 460:
example''
example 1: 2
3</langsyntaxhighlight>
 
 
Line 401 ⟶ 466:
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">import java.util.Objects;
 
public class PrintDebugStatement {
Line 436 ⟶ 501:
oops.run();
}
}</langsyntaxhighlight>
{{out}}
<pre>[DEBUG][PrintDebugStatement.java PrintDebugStatement.main#30] Hello world.
Line 451 ⟶ 516:
 
The '''debug''' built-in is a 0-arity filter which behaves somewhat like `tee /dev/stderr` in *ix -- that is, it prints its input as a message to '''stderr''' and also passes it along to the next filter, as illustrated by this transcript:
<syntaxhighlight lang="sh">
<lang sh>
jq -n '"abc" | debug | length'
["DEBUG:","abc"]
3
</syntaxhighlight>
</lang>
 
'''$__loc__'''
Line 471 ⟶ 536:
=={{header|Julia}}==
Julia has native print logging type functions, including a core Logging module. In addition, there are several additional downloadable modules, such as Memento, with extended logging functionality. Julia's builtin logging has defined macros for logging levels: @error, @warn, @info, and @debug. By default, debug level statements in code are not printed unless the logging level is set to allow debug statements to print, which can be enabled by setting the JULIA_DEBUG environment variable.
<langsyntaxhighlight lang="julia">function test()
@info "starting test()"
a = [1, 2]
Line 490 ⟶ 555:
 
test()
</langsyntaxhighlight>{{out}}
<pre>
[ Info: starting test()
Line 504 ⟶ 569:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">fun printDebug(message: String) {
val exception = RuntimeException()
val stackTrace = exception.stackTrace
Line 531 ⟶ 596:
}
nested()
}</langsyntaxhighlight>
{{out}}
<pre>[DEBUG][PrintDebuggingStatement.kt PrintDebuggingStatementKt.main#18] Hello world.
Line 539 ⟶ 604:
 
=={{header|Ksh}}==
<langsyntaxhighlight lang="ksh">
#!/bin/ksh
 
Line 577 ⟶ 642:
(( result = x + y ))
exit
</syntaxhighlight>
</lang>
{{out}}<pre>
Line 33: Command: 'typeset -li x y result'
Line 600 ⟶ 665:
Together with data functors like <code>$module</code>, <code>$pred</code>, <code>$line</code>, trace goals can be used for debugging print statements as in the following example. Together with the [https://mercurylang.org/information/doc-latest/mercury_library/require.html require] module's utilities, trace goals can be used for assert() statements or pre/post assertions.
 
<langsyntaxhighlight Mercurylang="mercury">:- module add.
:- interface.
:- import_module io.
Line 617 ⟶ 682:
main(!IO) :-
2 `add` 7 = N,
io.print_line(N, !IO).</langsyntaxhighlight>
 
{{out}} (with a non-debug grade)
Line 636 ⟶ 701:
 
The conditional activation is done using a “when” statement. Here is an example:
<langsyntaxhighlight Nimlang="nim">when defined(debug):
echo "Debugging info: $1 $2 $3".format(x, y, z)</langsyntaxhighlight>
When compiling, if nothing is specified, no code is generated to display the debugging information. If we want to generate the debug statements, we have to specify <code>-d:debug</code> when compiling, for instance if the file is named “example.nim”: <code>nim c -d:debug example.nim</code>. Note that the name “debug” has been chosen as an example but maybe any valid Nim identifier not already used. This allows to use different flags according to what we want to debug.
 
If is also possible to use existing flags instead of defining new ones:
<langsyntaxhighlight Nimlang="nim">when not defined(release):
echo "Debugging info: ", x, " ", y, " ", z</langsyntaxhighlight>
In this case, by default (debug build), the code for the statement is generated. But if we produce a release build (<code>-d:release</code> option), the debugging code will not be generated.
 
Line 651 ⟶ 716:
Last, but not least, Nim provides a simple and efficient log module. Using logger objects, this module allows to write log data to the console or into a file. As expected of a logging module, it provides several levels for debugging:
 
<langsyntaxhighlight Nimlang="nim">Level = enum
lvlAll, ## All levels active
lvlDebug, ## Debug level and above are active
Line 659 ⟶ 724:
lvlError, ## Error level and above are active
lvlFatal, ## Fatal level and above are active
lvlNone ## No levels active; nothing is logged</langsyntaxhighlight>
 
These levels are mapped to the following names: "DEBUG", "DEBUG", "INFO", "NOTICE", "WARN","ERROR", "FATAL", "NONE".
Line 666 ⟶ 731:
 
Logging debugging data is then a simple as writing:
<langsyntaxhighlight Nimlang="nim">debug "Debugging info: $1 $2 $3".format(x, y, z)</langsyntaxhighlight>
 
=={{header|Perl}}==
<code>Carp</code> is a core module, always available.
<langsyntaxhighlight lang="perl">use Carp;
 
$str = 'Resistance'; carp "'$str' is futile."; print "\n";
Line 682 ⟶ 747:
sub fiddle { faddle(2*shift) }
sub faddle { fuddle(3*shift) }
sub fuddle { ( carp("'$_[0]', interesting number.") ); }</langsyntaxhighlight>
{{out}}
<pre>'Resistance' is futile. at printf_debug.pl line 11.
Line 700 ⟶ 765:
to the language, albeit as yet undocumented.
 
<!--<langsyntaxhighlight Phixlang="phix">(notonline)-->
<span style="color: #008080;">function</span> <span style="color: #000000;">_debug_info</span><span style="color: #0000FF;">()</span>
<span style="color: #000080;font-style:italic;">-- use throw to convert a return address and routine number
Line 755 ⟶ 820:
<span style="color: #008080;">return</span> <span style="color: #000000;">_debug_info</span><span style="color: #0000FF;">()[</span><span style="color: #000000;">E_PATH</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<!--</langsyntaxhighlight>-->
 
This can be used as follows (0.8.1+)
 
<!--<langsyntaxhighlight Phixlang="phix">-->
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">/</span><span style="color: #000000;">reflections</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
Line 771 ⟶ 836:
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">()</span>
<!--</langsyntaxhighlight>-->
 
{{out}}
Line 790 ⟶ 855:
{{libheader|logging}}
Python's builtin [https://docs.python.org/3.8/library/logging.html logging module] allows extensive customization of output format and destination.
<langsyntaxhighlight lang="python">import logging, logging.handlers
 
LOG_FILENAME = "logdemo.log"
Line 827 ⟶ 892:
print_cubes(10)
 
logger.info("All done")</langsyntaxhighlight>
{{out}}<b>Contents of logdemo.log</b>
<pre>
Line 859 ⟶ 924:
Pyret has the [https://www.pyret.org/docs/latest/s_spies.html <code>spy</code> expression]. The expression can print the value of an identifier, using the identifier itself as a label if it's not already given. It could also print the value of an arbitrary expression, but it needs an explicit label in this case.
 
<langsyntaxhighlight lang="pyret">fun add(x, y):
result = x + y
spy "in add":
Line 870 ⟶ 935:
end
 
add(2, 7)</langsyntaxhighlight>
 
{{out}}
Line 887 ⟶ 952:
Racket doesn't have a built-in print debugging statement. However, it can be defined by users as a macro.
 
<langsyntaxhighlight lang="racket">#lang racket
 
(require syntax/parse/define)
Line 912 ⟶ 977:
(debug result))
 
(add 2 7)</langsyntaxhighlight>
 
{{out}}
Line 943 ⟶ 1,008:
Comments with the files line numbers are added here to make it easier to match up the debug output with the file. Typically you would be editing the file in an editor that provides line numbering so that wouldn't be necessary/helpful.
 
<syntaxhighlight lang="raku" perl6line>my &pdb = &die;
 
CATCH {
Line 978 ⟶ 1,043:
alpha($a); #line 34
delta("Δ"); #line 35
.&beta for ^3; #line 36</langsyntaxhighlight>
 
{{out}}
Line 1,041 ⟶ 1,106:
 
The following output is from the Regina REXX interpreter.
<langsyntaxhighlight lang="rexx">/*REXX program to demonstrate debugging (TRACE) information while executing a program*/
/*────────────────────────────────────────────── (below) the I is for information. */
trace i
Line 1,053 ⟶ 1,118:
end /*j*/
 
say 'total=' total /*stick a fork in it, we're all done. */</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the input of: &nbsp; &nbsp; <tt> 9 </tt>}}
<pre>
Line 1,107 ⟶ 1,172:
 
What is generally done in practice is to hard-code some location indicator (such as the line number itself) at which a variable's value is being obtained. The Go example code then looks like this when translated to Wren.
<langsyntaxhighlight ecmascriptlang="wren">import "./fmt" for Fmt
 
class Point {
Line 1,140 ⟶ 1,205:
debug.call("p", p, 32)
var l = [1, "two", 3]
debug.call("l", l, 34)</langsyntaxhighlight>
 
{{out}}
Line 1,167 ⟶ 1,232:
"l" at line 34 type 'Num String Num'
value: 1 two 3
</pre>
<br>
{{libheader|Wren-debug}}
We can also rewrite this code using the above module which, whilst still quite basic, provides a more structured approach to debugging than the first version.
<syntaxhighlight lang="wren">import "./fmt" for Fmt
import "./debug" for Debug
 
class Point {
construct new(x, y) {
_x = x
_y = y
}
x { _x }
y { _y }
toString { "(%(_x), %(_y))" }
}
 
var add = Fn.new { |x, y|
var result = x + y
Debug.print("x|y|result|result+1", 16, x, y, result, result + 1)
return result
}
 
add.call(2, 7)
var b = true
var s = "Hello"
var p = Point.new(2, 3)
var l = [1, "two", 3]
Debug.nl
Debug.print("b|s|p|l", 25, b, s, p, l)</syntaxhighlight>
 
{{out}}
<pre>
EXPR on line 16 of type Int : x = 2
EXPR on line 16 of type Int : y = 7
EXPR on line 16 of type Int : result = 9
EXPR on line 16 of type Int : result+1 = 10
NL
EXPR on line 25 of type Bool : b = true
EXPR on line 25 of type String : s = Hello
EXPR on line 25 of type Point : p = (2, 3)
EXPR on line 25 of type List : l = [1, two, 3]
</pre>
 
Line 1,172 ⟶ 1,279:
Print debugging is similar to C. The _debug_ keyword conditionally compiles
code (ie the debug code isn't compiled unless debugging is turned on).
<langsyntaxhighlight lang="zkl">fcn ds(line=__LINE__){
println("This is line %d of file %s compiled on %s"
.fmt(line,__FILE__,__DATE__));
Line 1,179 ⟶ 1,286:
ds(__LINE__); println("Debug level is ",__DEBUG__);
vm.stackTrace().println();
}</langsyntaxhighlight>
{{out}}
<pre>
9,476

edits