Assertions: Difference between revisions
Line 272:
(* evaluate stuff to return here when a is 42 *)</lang>
It is possible to compile with the parameter <code>-noassert</code> then the compiler won't compile the assertion checks.
=={{header|Oz}}==
|
Revision as of 02:47, 20 June 2010
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
Assertions are a way of breaking out of code when there is an error or an unexpected input. Some languages throw exceptions and some treat it as a break point.
Show an assertion in your language by asserting that an integer variable is equal to 42.
Ada
Using pragma Assert: <lang ada>pragma Assert (A = 42, "Oops!");</lang> The behavior of pragma is controlled by pragma Assertion_Policy. Another way is to use the predefined package Ada.Assertions: <lang ada>with Ada.Assertions; use Ada.Assertions; ... Assert (A = 42, "Oops!");</lang> The procedure Assert propagates Assertion_Error when condition is false.
ALGOL 68
The "Revised Report on the Algorithmic Language - ALGOL 68" suggest that ASSERT may be made available by a particular implementation, quote: "Pragmats may ... convey to the implementation some piece of information affecting some aspect of the meaning of the program which is not defined by this Report,..."
Example given[1]:
INT a, b; read((a, b)) PR ASSERT a >= 0 & b > 0 PR;
This works with neither ELLA ALGOL 68 nor ALGOL 68G.
The standard alternative would be to implement the assertions as an exception as per the Exceptions sample code.
In ELLA ALGOL 68 the ASSERT is implemented as an operator in the environment prelude: <lang algol68>OP ASSERT = (VECTOR [] CHAR assertion,BOOL valid) VOID: IF NOT valid THEN type line on terminal(assertion);
terminal error( 661 {invalid assertion } )
FI;</lang> And can be "USEd" as follows: <lang algol68>PROGRAM assertions CONTEXT VOID USE standard,environment BEGIN
INT a := 43; "Oops!" ASSERT ( a = 42 )
END FINISH</lang>
AutoHotkey
<lang AutoHotkey>if (a != 42) { OutputDebug, "a != 42" ; sends output to a debugger if connected ListVars ; lists values of local and global variables Pause ; pauses the script, use ExitApp to exit instead }</lang>
C
<lang c>#include <assert.h>
int main(){
int a; /* ...input or change a here */ assert(a == 42); /* aborts program when a is not 42 */
return 0;
}</lang>
C++
<lang cpp>#include <cassert> // assert.h also works
int main() {
int a; // ... input or change a here
assert(a == 42); // Aborts program if a is not 42, unless the NDEBUG macro was defined // when including <cassert>, in which case it has no effect
}</lang>
Note that assert does not get a std::
prefix because it's a macro.
C#
<lang csharp>using System.Diagnostics;
Debug.Assert(a == 42);</lang>
Clojure
<lang lisp>(assert (= i 42))</lang>
Common Lisp
<lang lisp>(let ((x 42))
(assert (and (integerp x) (= 42 x))))</lang>
D
<lang d>import std.string; void main() {
int a = readln().chomp().atoi(); assert(a == 42, "You did not input 42!");
}</lang>
E
E does not have the specific feature of assertions which may be disabled by a global option. But it does have a utility to throw an exception if a condition is false:
<lang e>require(a == 42) # default message, "Required condition failed"
require(a == 42, "The Answer is Wrong.") # supplied message
require(a == 42, fn { `Off by ${a - 42}.` }) # computed only on failure</lang>
Eiffel
version 2.4
There are many assertion types in Eiffel, one is the following:
File called main.e: <lang eiffel>class MAIN
creation main feature main is local test: TEST; do create test;
io.read_integer; test.assert(io.last_integer); end
end</lang> Another file called test.e: <lang eiffel>class TEST
feature assert(val: INTEGER) is require val = 42; do print("Thanks for the 42!%N"); end
end</lang>
Erlang
Erlang doesn't have an assert statement. However, it is single assignment, and its assignment operator won't complain if you reassign the exact same value to an existing variable but will throw an exception otherwise. <lang erlang>1> N = 42. 42 2> N = 43.
- exception error: no match of right hand side value 43
3> N = 42. 42 4> 44 = N.
- exception error: no match of right hand side value 42
5> 42 = N. 42</lang>
As such, the behavior of Erlang's assignment operator is extremely similar to a regular assert in other languages.
Factor
Throw an exception if the value on the top of the stack is not equal to 42:
<lang factor>USING: kernel ; 42 assert=</lang>
F#
F# provides an assert function that is only enabled when the program is compiled with DEBUG defined. <lang fsharp>let f x =
assert (x > 1) x</lang>
Groovy
<lang groovy>def doSomething = { x, f ->
assert f != null : "f was null!" assert f instanceof Closure : "f was not a closure! f: ${f}" f(x)
}</lang>
Test program: <lang groovy>println doSomething(-1) { x -> -2*Math.asin(x) } try { println doSomething(-1, 50) } catch (Throwable t) { println t.message } try { println doSomething(-1, null) } catch (Throwable t) { println t.message }</lang>
Output:
3.141592653589793 f was not a closure! f: 50. Expression: (f instanceof groovy.lang.Closure). Values: f = 50 f was null!. Expression: (f != null). Values: f = null
Haskell
<lang haskell>import Control.Exception
main = let a = someValue in
assert (a == 42) -- throws AssertionFailed when a is not 42 somethingElse -- what to return when a is 42</lang>
Icon and Unicon
Icon
<lang Icon>... runerr(n,( expression ,"Assertion/error - message.")) # Throw (and possibly trap) an error number n if expression succeeds. ... stop(( expression ,"Assertion/stop - message.")) # Terminate program if expression succeeds. ...</lang>
Unicon
This Icon solution works in Unicon.
Java
<lang java5>public static void main(String[] args){
int a; //...input or change a here assert a == 42;//throws an AssertionError when a is not 42 assert a == 42 : "Error message"; //throws an AssertionError //when a is not 42 with "Error message" for the message //the error message can be any non-void expression
}</lang> Note: assertion checking is disabled by default when you run your program with the java command. You must provide the -ea (short for -enableassertions) flag in order to enable them.
J
<lang j> assert n = 42</lang>
Lisaac
<lang Lisaac>? { n = 42 };</lang>
Lua
<lang lua>a = 5 assert (a == 42) assert (a == 42,'\..a..'\' is not the answer to life, the universe, and everything')</lang>
MATLAB
<lang MATLAB>assert(x == 42,'x = %d, not 42.',x);</lang>
Sample Output: <lang MATLAB>x = 3; assert(x == 42,'Assertion Failed: x = %d, not 42.',x); ??? Assertion Failed: x = 3, not 42. </lang>
Metafont
Metafont has no really an assert built in, but it can easily created:
<lang metafont>def assert(expr t) = if not (t): errmessage("assertion failed") fi enddef;</lang>
This assert
macro uses the errmessage
built in to show the "error". The
errmessage
gives the error message and asks the user what to do.
Usage example:
<lang metafont>n := 41; assert(n=42); message "ok";</lang>
Output (failed assertion):
This is METAFONT, Version 2.71828 (Web2C 7.5.5) (./assert.mf ! assertion failed. <to be read again> ; l.4 assert(n=42); ?
Modula-3
ASSERT
is a pragma, that creates a run-time error if it returns FALSE
.
<lang modula3><*ASSERT a = 42*></lang>
Assertions can be ignored in the compiler by using the -a
switch.
Objective-C
For use within an Objective-C method: <lang objc>NSAssert(a == 42, @"Error message");</lang>
If you want to use formatting arguments, you need to use the assertion macro corresponding to your number of formatting arguments: <lang objc>NSAssert1(a == 42, @"a is not 42, a is actually %d", a); # has 1 formatting arg, so use NSAssert"1"</lang>
Within a regular C function you should use NSCAssert
or NSCAssertN
instead.
OCaml
<lang ocaml>let a = get_some_value () in
assert (a = 42); (* throws Assert_failure when a is not 42 *) (* evaluate stuff to return here when a is 42 *)</lang>
It is possible to compile with the parameter -noassert
then the compiler won't compile the assertion checks.
Oz
Oz does not have an assert statement. But if different values are assigned to the same dataflow variable, an exception will be thrown (similar to Erlang).
<lang oz>declare
proc {PrintNumber N} N=42 %% assert {Show N} end
in
{PrintNumber 42} %% ok {PrintNumber 11} %% throws </lang>
Output:
%***************************** failure ************************** %** %** Tell: 11 = 42 %** %** Call Stack: %** procedure 'PrintNumber' in file "Oz<8>", line 3, column 0, PC = 18600220 %**--------------------------------------------------------------
Perl
While not exactly an assertion, a common Perl idiom is to use ... or die ...
to throw an exception when a certain statement is false.
<lang perl>open my $fh, '<', 'file' or die "Cannot open file: $!\n"; # $! contains the error message from the last error</lang>
Note: the above "or die" idiom is not needed when the "autodie" pragma is in use:
<lang perl>use autodie;
open my $fh, '<', 'file'; # automatically throws an exception on failure</lang>
Another example: <lang perl>my $a = 5;
- ...input or change $a here
$a == 42 or die "Error message\n";
- or, alternatively:
die "Error message\n" unless $a == 42;
- or:
die "Error message\n" if not $a == 42;
- or just:
die "Error message\n" if $a != 42;</lang>
Some third-party modules provide other ways of using assertions in Perl: <lang perl>use Carp::Assert; assert($a == 42);</lang>
There is also a number of ways to test assertions in test suites, for example: <lang perl>is $a, 42; ok $a == 42; cmp_ok $a, '==', 42, 'The answer should be 42';
- etc.</lang>
PHP
<lang php><?php $a = 5
- ...input or change $a here
assert($a == 42) # when $a is not 42, take appropriate actions,
# which is set by assert_options()
?></lang>
PicoLisp
The 'assert' function, in combination with the tilde read macro, generates code only in debug mode: <lang PicoLisp>... ~(assert (= N 42)) # Exists only in debug mode ...</lang> Other possibilities are either to break into an error handler: <lang PicoLisp>(let N 41
(unless (= N 42) (quit "Incorrect N" N)) ) # 'quit' throws an error
41 -- Incorrect N ?</lang> or to stop at a debug break point, allowing to continue with the program: <lang PicoLisp>(let N 41
(unless (= N 42) (! setq N 42)) ) # '!' is a breakpoint
(setq N 42) # Manually fix the value ! # Hit ENTER to leave the breakpoint -> 42</lang>
PL/I
<lang> /* PL/I does not have an assert function as such, */ /* but it is something that can be implemented in */ /* any of several ways. A straight-forward way */ /* raises a user-defined interrupt. */
on condition (assert_failure) snap
put skip list ('Assert failure');
.... if a ^= b then signal condition(assert_failure);
/* Another way is to use the preprocessor, thus: */ %assert: procedure (a, b) returns (character);
return ('if ' || a || '^=' || b || ' then signal condition(assert_failure);');
%end assert; %activate assert;
assert(a, 42); </lang>
Prolog
<lang prolog> test(A):-
assertion(A==42).
</lang>
Python
<lang python>a = 5
- ...input or change a here
assert a == 42 # throws an AssertionError when a is not 42 assert a == 42, "Error message" # throws an AssertionError
# when a is not 42 with "Error message" for the message # the error message can be any expression</lang>
R
<lang R>stopifnot(a==42)</lang>
Ruby
<lang ruby>require "test/unit/assertions" include Test::Unit include Test::Unit::Assertions
n = 5 begin
assert_equal(42, n)
rescue AssertionFailedError
puts "assertion failed: expected 42, got #{n}"
end</lang>
Sather
<lang sather>class MAIN is
main is i ::= 41; assert i = 42; -- fatal -- ... end;
end;</lang>
(The current GNU Sather compiler v1.2.3 I am using to test the code seems to ignore the assertion and no fatal error is raised, despite Sather should, see e.g. here).
Scala
These two are the same thing, and are tagged @elidable(ASSERTION)
:
<lang scala>assert(a == 42)
assert(a == 42, "a isn't equal to 42")
assume(a == 42)
assume(a == 42, "a isn't equal to 42")</lang>
The next one does the same thing as above, but it is not tagged. Often used as a pre-condition checker on class constructors. <lang scala>require(a == 42) require(a == 42, "a isn't equal to 42")</lang>
This one checks a value and returns it for further use (here shown being printed). It
uses assert
, which, as explained, gets tagged.
<lang scala>println(a.ensuring(a == 42))
println(a.ensuring(a == 42, "a isn't equal to 42"))
println(a.ensuring(_ == 42))
println(a.ensuring(_ == 42, "a isn't equal to 42"))</lang>
Scheme
<lang scheme>(let ((x 42))
(assert (and (integer? x) (= x 42))))</lang>
Slate
<lang slate>load: 'src/lib/assert.slate'. define: #n -> 7. assert: n = 42 &description: 'That is not the Answer.'.</lang> raises an AssertionFailed condition (an Error).
Tcl
<lang tcl>package require control
set x 5 control::assert {$x == 42}</lang> Produces the output:
assertion failed: $x == 42
VBScript
Definition
<lang vb>sub Assert( boolExpr, strOnFail ) if not boolExpr then Err.Raise vbObjectError + 99999, , strOnFail end if end sub </lang>
Invocation
<lang vb>dim i i = 43 Assert i=42, "There's got to be more to life than this!"</lang>
Output
<lang VBScript>>cscript "C:\foo\assert.vbs" C:\foo\assert.vbs(3, 3) (null): There's got to be more to life than this!</lang>
Visual Basic
VB's Assert
only fires when run from within the IDE. When compiled, all Debug
lines are ignored.
<lang vb>Debug.Assert i = 42</lang>
- Programming Tasks
- Basic language learning
- Ada
- ALGOL 68
- AutoHotkey
- C
- C++
- C sharp
- Clojure
- Common Lisp
- D
- E
- Eiffel
- Erlang
- Factor
- F Sharp
- Groovy
- Haskell
- Icon
- Unicon
- Java
- J
- Lisaac
- Lua
- MATLAB
- Metafont
- Modula-3
- Objective-C
- OCaml
- Oz
- Perl
- PHP
- PicoLisp
- PL/I
- Prolog
- Python
- R
- Ruby
- Test/unit.rb
- Sather
- Scala
- Scheme
- Slate
- Tcl
- Tcllib
- Gnuplot/Omit
- VBScript
- Visual Basic