Introspection: Difference between revisions

Added Java
(Added a solution in Ada.)
(Added Java)
Line 7:
=={{header|Ada}}==
Ada doesn't allow you to ask about compiler versions, but you can query specific parameters of the target, such as the range of the standard integer type, or the precision of the standard floating point type:
'''<ada>with''' Ada.Integer_Text_IO, Ada.Text_IO;
'''procedure''' Introspection '''is'''
'''use''' Ada.Integer_Text_IO, Ada.Text_IO;
'''begin'''
Put ("Integer range: ");
Put (Integer'First);
Line 20:
Put (Float'Digits);
New_Line;
'''end''' Introspection;</ada>
 
 
=={{header|C}}==
Line 27 ⟶ 26:
 
{{works with|C|94 and later}}
<c>#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
#pragma error("C compiler must adhere to at least C99 for the following code.")
#else
/* rest of file */
#endif</c>
 
However, there is no facility in C for checking whether individual variables and functions have been declared. In open source, the GNU [[autotools]] are often used for this purpose, doing this kind of check in a shell script and defining symbols such as __HAVE_ABS__ which ''can'' be checked by the preprocessor.
Line 39 ⟶ 38:
The DMD compiler has macros defined for the version, more easily accessible through std.compiler:
 
<d>import std.compiler;
static if (version_major < 2 || version_minor > 7) {
// this prevents further compilation
static assert (false, "I can't cope with this compiler version");
}</d>
 
To check if something compiles or not:
 
<d>version(D_Version2) {
static if( __traits(compiles,abs(bloop)) ) {
Line 56 ⟶ 55:
}
} else static assert(0, "Requires D version 2");</d>
 
Note that this checks that bloop is of a type which abs() accepts. It is generic code; if the type of abs() changes, so will the return type of the function. The test can also be written so that it will work on D version 1:
 
<d>static if ( is(typeof(abs(bloop))) ) {
typeof(abs(bloop)) computeAbsBloop() {
return abs(bloop);
}
}</d>
 
=={{header|E}}==
Line 87 ⟶ 86:
bloop @ abs
[then] [then]
 
=={{header|Java}}==
You can't see if a variable or function is available in Java (it will be a compile time error if you try to use them when you they aren't available), but you can check the version number using the <tt>System</tt> class:
<java>public class VersCheck {
public static void main(String[] args) {
String vers = System.getProperty("java.version");
vers = vers.substring(0,vers.indexOf('.')) + "." + //some String fiddling to get the version number into a usable form
vers.substring(vers.indexOf('.')+1,vers.lastIndexOf('.'));
if(Double.parseDouble(vers) >= 1.5){
System.out.println("YAY!");
}else{
System.err.println("Must use Java >=1.5");
}
}
}</java>
 
=={{header|MAXScript}}==
Line 120 ⟶ 134:
=={{header|Perl}}==
{{works with|Perl|5.x}}
<perl>require v5.6.1; # run time version check
require 5.6.1; # ditto
require 5.006_001; # ditto; preferred for backwards compatibility</perl>
Checking whether a variable exists is kind of daft. Good style dictates that I declare the variables I'm going to use, and then I already know $bloop exists. Checking for the ''value'' of a variable however is something very common.
<perl>defined $bloop;
# returns true if bloop has been filled with something useful</perl>
What if 'bloop' is a computed value? Good style forbids that I dereference willy-nilly variables with unknown names, that's what hashes are good for.
<perl>$computed = 'bloop';
exists $introspect{$computed};
# returns true if the key bloop exists in hash %introspect</perl>
But neither you can do this, for example:
<perl>#$bloop = -123; # uncomment this line to see the difference
if (defined($::{'bloop'})) {print abs(${'bloop'})} else {print "bloop isn't defined"};</perl>
The trick in this example is to use bloop variable by reference ${'bloop'} (otherwise it will be created unconditionally by the compiler). Perl store nametables inside hashes: '::' - for main package and 'xxx::' for package 'xxx'.
In Perl, you cannot check for the existence of built-in functions, of which abs() is one. However in practice that's not a problem because most functions live in classes, and those are easily inspectable at runtime.
<perl>use UNIVERSAL qw(can);
use Math::Cephes qw();
print Math::Cephes->fabs($bloop) if can 'Math::Cephes', 'fabs';</perl>
 
=={{header|Pop11}}==
Line 170 ⟶ 184:
 
=={{header|Python}}==
<python># Checking for system version
import sys
major, minor, bugfix = sys.version_info[:3]
Line 176 ⟶ 190:
sys.exit('Python 2 is required')
<pre>
def defined(name): # LBYL (Look Before You Leap)
return name in globals() or name in locals() or name in vars(__builtins__)
Line 192 ⟶ 206:
if defined2('bloop') and defined2('abs') and callable(abs):
print abs(bloop)
</prepython>
 
=={{header|Raven}}==
Line 202 ⟶ 216:
 
=={{header|Ruby}}==
<ruby>exit if RUBY_VERSION < '1.8.6'
puts bloop.abs if defined?(bloop) and bloop.respond_to?(:abs)</ruby>
 
=={{header|Tcl}}==
Anonymous user