Reflection/List properties: Difference between revisions

Add Ecstasy example
(Lingo added)
(Add Ecstasy example)
 
(60 intermediate revisions by 27 users not shown)
Line 1:
{{task|Reflection}} [[Category:Programming Tasks]] [[Category:Object oriented]]
{{omit from|C}}
{{omit from|C++}}
{{omit from|Modula-2}}
{{omit from|Rust}}
 
;Task:
Line 5 ⟶ 9:
 
Some languages support dynamic properties, which in general can only be inspected if a class' public API includes a way of listing them.
 
=={{header|C sharp}}==
{{works with|C sharp|7}}
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
 
public static class Reflection
{
public static void Main() {
var t = new TestClass();
var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
foreach (var prop in GetPropertyValues(t, flags)) {
Console.WriteLine(prop);
}
foreach (var field in GetFieldValues(t, flags)) {
Console.WriteLine(field);
}
}
 
public static IEnumerable<(string name, object value)> GetPropertyValues<T>(T obj, BindingFlags flags) =>
from p in typeof(T).GetProperties(flags)
where p.GetIndexParameters().Length == 0 //To filter out indexers
select (p.Name, p.GetValue(obj, null));
public static IEnumerable<(string name, object value)> GetFieldValues<T>(T obj, BindingFlags flags) =>
typeof(T).GetFields(flags).Select(f => (f.Name, f.GetValue(obj)));
class TestClass
{
private int privateField = 7;
public int PublicNumber { get; } = 4;
private int PrivateNumber { get; } = 2;
}
 
}</syntaxhighlight>
{{out}}
<pre>
(PublicNumber, 4)
(PrivateNumber, 2)
(privateField, 7)
(<PublicNumber>k__BackingField, 4)
(<PrivateNumber>k__BackingField, 2)
</pre>
 
=={{header|D}}==
<syntaxhighlight lang="d">import std.stdio;
 
struct S {
bool b;
 
void foo() {}
private void bar() {}
}
 
class C {
bool b;
 
void foo() {}
private void bar() {}
}
 
void printProperties(T)() if (is(T == class) || is(T == struct)) {
import std.stdio;
import std.traits;
 
writeln("Properties of ", T.stringof, ':');
foreach (m; __traits(allMembers, T)) {
static if (__traits(compiles, (typeof(__traits(getMember, T, m))))) {
alias typeof(__traits(getMember, T, m)) ti;
static if (!isFunction!ti) {
writeln(" ", m);
}
}
}
}
 
void main() {
printProperties!S;
printProperties!C;
}</syntaxhighlight>
{{out}}
<pre>Properties of S:
b
Properties of C:
b</pre>
 
=={{header|Ecstasy}}==
For any object, the type of that object provides access to its properties:
 
<syntaxhighlight lang="ecstasy">
module test {
void run() {
@Inject Console console;
Property[] properties = &this.actualType.properties;
console.print($"The properties of {this}: {properties}");
}
}
</syntaxhighlight>
 
{{out}}
<pre>
x$ xec test
The properties of test: [immutable Array<Class<Object, Object, Object, Struct>> classes, immutable Map<String, Class<Object, Object, Object, Struct>> classByName, String simpleName, String qualifiedName, Version version, immutable Map<String, Module> modulesByPath]
</pre>
 
=={{header|Elena}}==
ELENA 6.x :
<syntaxhighlight lang="elena">import system'routines;
import system'dynamic;
import extensions;
class MyClass
{
int X : prop;
string Y : prop;
}
 
public program()
{
var o := new MyClass
{
this X := 2;
this Y := "String";
};
 
MyClass.__getProperties().forEach::(p)
{
console.printLine("o.",p,"=",p.getPropertyValue(o))
}
}</syntaxhighlight>
{{out}}
<pre>
o.X=2
o.Y=String
</pre>
 
=={{header|Factor}}==
Mirrors present an object's slots and slot values as an associative structure.
<syntaxhighlight lang="factor">USING: assocs kernel math mirrors prettyprint strings ;
 
TUPLE: foo
{ bar string }
{ baz string initial: "hi" }
{ baxx integer initial: 50 read-only } ;
C: <foo> foo
 
"apple" "banana" 200 <foo> <mirror>
[ >alist ] [ object-slots ] bi [ . ] bi@</syntaxhighlight>
{{out}}
<pre>
{ { "bar" "apple" } { "baz" "banana" } { "baxx" 200 } }
{
T{ slot-spec
{ name "bar" }
{ offset 2 }
{ class string }
{ initial "" }
}
T{ slot-spec
{ name "baz" }
{ offset 3 }
{ class string }
{ initial "hi" }
}
T{ slot-spec
{ name "baxx" }
{ offset 4 }
{ class integer }
{ initial 50 }
{ read-only t }
}
}
</pre>
 
=={{header|Fortran}}==
Fortran offers services somewhat as desired, at two levels. Suppose <code>X</code> is the name of some variable. Then, <code>WRITE (6,*) X</code> would send to file unit six (the modern default unit number for "standard output"), the value of <code>X</code>, whatever its type - be it an array, a complex number, an integer, a character variable, or, (with F90 and later) an aggregate or "structure", all with appropriate formats for each part, single or double precision, ''etc''. This is the "free-format" or "list-directed" style, signified by the asterisk in place of a format code or the label of a FORMAT statement. With arrays, repeated values are shown with a repetition count, as in 66*303 meaning sixty-six values of 303. Alas, the @ symbol is not used. Thus, inspection of the style of such output will reveal whether <code>X</code> was an integer, ''etc''.
 
The second level requires slightly more effort: a declaration such as <code>NAMELIST /STUFF/ X</code> enables the use of a statement such as <code>WRITE (6,STUFF)</code> whereupon each item's value will be prefixed with its name in the style of an assignment statement, as in <code>X = 2.7182818</code> if <code>X</code> were to be the name of a simple floating-point variable.
 
There may be a list of items, not just the lone <code>X</code> and these proceedings apply to READ statements also.
 
=={{header|Go}}==
<syntaxhighlight lang="go">package main
 
import (
"fmt"
"image"
"reflect"
)
 
// A type definition
type t struct {
X int
next *t
}
 
func main() {
report(t{})
report(image.Point{})
}
 
func report(x interface{}) {
t := reflect.TypeOf(x)
n := t.NumField()
fmt.Printf("Type %v has %d fields:\n", t, n)
fmt.Println("Name Type Exported")
for i := 0; i < n; i++ {
f := t.Field(i)
fmt.Printf("%-8s %-8v %-8t\n",
f.Name,
f.Type,
f.PkgPath == "",
)
}
fmt.Println()
}</syntaxhighlight>
{{out}}
<pre>
Type main.t has 2 fields:
Name Type Exported
X int true
next *main.t false
 
Type image.Point has 2 fields:
Name Type Exported
X int true
Y int true
</pre>
 
=={{header|Groovy}}==
{{trans|Java}}
<syntaxhighlight lang="groovy">import java.lang.reflect.Field
 
@SuppressWarnings("unused")
class ListProperties {
public int examplePublicField = 42
private boolean examplePrivateField = true
 
static void main(String[] args) {
ListProperties obj = new ListProperties()
Class clazz = obj.class
 
println "All public fields (including inherited):"
(clazz.fields).each { Field f ->
printf "%s\t%s\n", f, f.get(obj)
}
println()
 
println "All declared fields (excluding inherited):"
clazz.getDeclaredFields().each { Field f ->
f.accessible = true
printf "%s\t%s\n", f, f.get(obj)
}
}
}</syntaxhighlight>
{{out}}
<pre>All public fields (including inherited):
public int ListProperties.examplePublicField 42
public static transient boolean ListProperties.__$stMC false
 
All declared fields (excluding inherited):
public int ListProperties.examplePublicField 42
private boolean ListProperties.examplePrivateField true
private static org.codehaus.groovy.reflection.ClassInfo ListProperties.$staticClassInfo org.codehaus.groovy.reflection.ClassInfo@400cff1a
public static transient boolean ListProperties.__$stMC false
private transient groovy.lang.MetaClass ListProperties.metaClass groovy.lang.MetaClassImpl@275710fc[class ListProperties]
private static org.codehaus.groovy.reflection.ClassInfo ListProperties.$staticClassInfo$ null
private static java.lang.ref.SoftReference ListProperties.$callSiteArray java.lang.ref.SoftReference@525f1e4e</pre>
 
=={{header|J}}==
http://rosettacode.org/wiki/Reflection/List_methods#J
Please observe that names&>i.4 lists nouns (pronouns that store data), adverbs (names of verb modifiers returning any of these four parts of speech), conjunctions (which can take three or four arguments, two of which can any part of these four parts of speech and two nouns), and proverbs (names of verbs, which you might call "functions").
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">import java.lang.reflect.Field;
 
public class ListFields {
Line 27 ⟶ 306:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 41 ⟶ 320:
There are multiple ways of getting property names, each of which include different subsets of an object's properties, such as enumerable or inherited properties. Properties in JavaScript can be enumerable or non-enumerable; enumerable properties are accessable when looping over the object with <code>for</code>. <code>Object.getOwnPropertyNames()</code>.
 
<langsyntaxhighlight lang="javascript">var obj = Object.create({
name: 'proto',
proto: true,
Line 72 ⟶ 351:
Object.entries(obj);
//[["name", "obj"], ["obj", true], ["doStuff", function()]]
</syntaxhighlight>
</lang>
 
=={{header|jq}}==
{{works with|jq}}
 
Various properties of JSON values are directly accessible via the
built-in functions `type`, `length` (except for booleans), and, for
JSON objects, `keys` and `keys_unsorted`:
 
* `type` returns the JSON type;
* `length` returns an array's length, the number of (distinct) keys of an object, the absolute value of a number, and 0 for `null`;
 
Note that gojq (the Go implementation of jq) does not support `keys_unsorted`.
 
Other properties can be ascertained programmatically.
See e.g. '''schema.jq''' (https://gist.github.com/pkoppstein/a5abb4ebef3b0f72a6ed) for a schema-inference engine for JSON written in jq; the inferred schemas are themselves JSON documents.
 
'''Example'''
<syntaxhighlight lang="jq">
# Use jq's built-ins to generate a (recursive) synopsis of .
def synopsis:
if type == "boolean" then "Type: \(type)"
elif type == "object"
then "Type: \(type) length:\(length)",
(keys_unsorted[] as $k
| "\($k): \(.[$k] | synopsis )")
else "Type: \(type) length: \(length)"
end;
 
true, null, [1,2], {"a": {"b": 3, "c": 4}, "x": "Rosetta Code"}, now
| ("\n\(.) ::", synopsis)
</syntaxhighlight>
{{out}}
<pre>
true ::
Type: boolean
 
null ::
Type: null length: 0
 
[1,2] ::
Type: array length: 2
 
{"a":{"b":3,"c":4},"x":[0,1]} ::
Type: object length:2
a: Type: object length:2
a: b: Type: number length: 3
a: c: Type: number length: 4
x: Type: string length: 12
 
1629526284.540229 ::
Type: number length: 1629526284.540229
</pre>
 
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<syntaxhighlight lang="julia">for obj in (Int, 1, 1:10, collect(1:10), now())
println("\nObject: $obj\nDescription:")
dump(obj)
end</syntaxhighlight>
 
{{out}}
<pre>
Object: Int64
Description:
Int64 <: Signed
 
Object: 1
Description:
Int64 1
 
Object: 1:10
Description:
UnitRange{Int64}
start: Int64 1
stop: Int64 10
 
Object: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Description:
Array{Int64}((10,)) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 
Object: 2017-10-04T18:03:33.691
Description:
DateTime
instant: Base.Dates.UTInstant{Base.Dates.Millisecond}
periods: Base.Dates.Millisecond
value: Int64 63642823413691</pre>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1
 
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.isAccessible
 
open class BaseExample(val baseProp: String) {
protected val protectedProp: String = "inherited protected value"
}
 
class Example(val prop1: String, val prop2: Int, baseProp: String) : BaseExample(baseProp) {
private val privateProp: String = "private value"
 
val prop3: String
get() = "property without backing field"
 
val prop4 by lazy { "delegated value" }
}
 
fun main(args: Array<String>) {
val example = Example(prop1 = "abc", prop2 = 1, baseProp = "inherited public value")
val props = Example::class.memberProperties
for (prop in props) {
prop.isAccessible = true // makes non-public properties accessible
println("${prop.name.padEnd(13)} -> ${prop.get(example)}")
}
}</syntaxhighlight>
 
{{out}}
<pre>
privateProp -> private value
prop1 -> abc
prop2 -> 1
prop3 -> property without backing field
prop4 -> delegated value
baseProp -> inherited public value
protectedProp -> inherited protected value
</pre>
 
=={{header|Lingo}}==
<langsyntaxhighlight lang="lingo">obj = script("MyClass").new()
obj.foo = 23
obj.bar = 42
Line 84 ⟶ 490:
cnt = obj.count
repeat with i = 1 to cnt
put obj.getPropAt(i)&" = "&obj[i]
end repeat</langsyntaxhighlight>
 
{{Out}}
<pre>
-- "bar = 42"
-- "foo = 23"
</pre>
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">a = 1
b = 2.0
c = "hello world"
 
function listProperties(t)
if type(t) == "table" then
for k,v in pairs(t) do
if type(v) ~= "function" then
print(string.format("%7s: %s", type(v), k))
end
end
end
end
 
print("Global properties")
listProperties(_G)
print("Package properties")
listProperties(package)</syntaxhighlight>
{{out}}
<pre>Global properties
number: a
table: string
number: b
table: package
table: os
table: io
table: arg
string: c
table: math
table: debug
table: table
table: coroutine
table: _G
string: _VERSION
Package properties
table: preload
table: loaded
table: loaders
string: cpath
string: config
string: path</pre>
 
=={{header|Nanoquery}}==
<syntaxhighlight lang="nanoquery">// declare a class that has fields to be listed
class Fields
declare static field1 = "this is a static field. it will not be listed"
declare field2
declare field3
declare field4
end
 
// list all the fields in the class
for fieldname in Fields.getFieldNames()
println fieldname
end</syntaxhighlight>
 
{{out}}
<pre>field3
field2
field4</pre>
=={{header|Nim}}==
<syntaxhighlight lang="nim">type
Foo = object
a: float
b: string
c: seq[int]
let f = Foo(a: 0.9, b: "hi", c: @[1,2,3])
for n, v in f.fieldPairs:
echo n, ": ", v</syntaxhighlight>
{{out}}
<pre>a: 0.9
b: hi
c: @[1, 2, 3]</pre>
 
=={{header|Objective-C}}==
<langsyntaxhighlight lang="objc">#import <Foundation/Foundation.h>
#import <objc/runtime.h>
 
Line 149 ⟶ 630:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 160 ⟶ 641:
</pre>
 
=={{header|Perl 6ooRexx}}==
Whereas in PL/I variables habe a (declared) type, in REXX and ooRexx a "typeless" variable
can be assigned a string or object, respectively.
The datatype builtin function can be used to determine the data type of a given string.
 
Many of these options are also supported by other REXX implementations.
You can get a list of an object's attributes (instance variables) using <tt>.^attributes</tt>, which is part of the [https://docs.perl6.org/type/Metamodel$COLON$COLONClassHOW Meta Object Protocol]..<br>
<syntaxhighlight lang="oorexx">/* REXX demonstrate uses of datatype() */
Each is represented as an <tt>Attribute</tt> object that contains a bunch of info:
/* test values */
d.1=''
d.2='a23'
d.3='101'
d.4='123'
d.5='12345678901234567890'
d.6='abc'
d.7='aBc'
d.8='1'
d.9='0'
d.10='Walter'
d.11='ABC'
d.12='f23'
d.13='123'
/* supported options */
t.1='A' /* Alphanumeric */
t.2='B' /* Binary */
t.3='I' /* Internal whole number */
t.4='L' /* Lowercase */
t.5='M' /* Mixed case */
t.6='N' /* Number */
t.7='O' /* lOgical */
t.8='S' /* Symbol */
t.9='U' /* Uppercase */
t.10='V' /* Variable */
t.11='W' /* Whole number */
t.12='X' /* heXadecimal */
t.13='9' /* 9 digits */
 
hdr=left('',20)
<lang perl6>class Foo {
Do j=1 To 13
has $!a = now;
hdr=hdr t.j
has Str $.b;
End
has Int $.c is rw;
hdr=hdr 'datatype(v)'
Say hdr
Do i=1 To 13
ol=left(d.i,20)
Do j=1 To 13
ol=ol datatype(d.i,t.j)
End
ol=ol datatype(d.i)
Say ol
End
Say hdr</syntaxhighlight>
{{out}}
<pre> A B I L M N O S U V W X 9 datatype(v)
0 1 0 0 0 0 0 0 0 0 0 1 0 CHAR
a23 1 0 0 0 0 0 0 1 0 1 0 1 0 CHAR
101 1 1 1 0 0 1 0 1 0 0 1 1 1 NUM
123 1 0 1 0 0 1 0 1 0 0 1 1 1 NUM
12345678901234567890 1 0 0 0 0 1 0 1 0 0 0 1 0 NUM
abc 1 0 0 1 1 0 0 1 0 1 0 1 0 CHAR
aBc 1 0 0 0 1 0 0 1 0 1 0 1 0 CHAR
1 1 1 1 0 0 1 1 1 0 0 1 1 1 NUM
0 1 1 1 0 0 1 1 1 0 0 1 1 1 NUM
Walter 1 0 0 0 1 0 0 1 0 1 0 0 0 CHAR
ABC 1 0 0 0 1 0 0 1 1 1 0 1 0 CHAR
f23 1 0 0 0 0 0 0 1 0 1 0 1 0 CHAR
123 1 0 1 0 0 1 0 1 0 0 1 1 1 NUM
A B I L M N O S U V W X 9 datatype(v)</pre>
 
=={{header|Perl}}==
In Perl's bare-bones native OO system, an object is sometimes nothing more than a hash blessed into a class. It's properties could be simply listed by iterating over the keys. However more complex data structures can be present, so the safest option is always to use <code>Data::Dumper</code> to examine an object.
<syntaxhighlight lang="perl">{
package Point;
use Class::Spiffy -base;
 
field 'x';
field 'y';
}
 
{
my $object = Foo.new: b => "Hello", c => 42;
package Circle;
use base qw(Point);
field 'r';
}
 
my $p1 = Point->new(x => 8, y => -5);
for $object.^attributes {
my $c1 = Circle->new(r => 4);
say join ", ", .name, .readonly, .container.^name, .get_value($object);
my $c2 = Circle->new(x => 1, y => 2, r => 3);
}</lang>
 
use Data::Dumper;
say Dumper $p1;
say Dumper $c1;
say Dumper $c2;</syntaxhighlight>
{{out}}
<pre>$VAR1 = bless( {
'x' => 8,
$!a, True, Any, Instant:1470517602.295992
'y' => -5
$!b, True, Str, Hello
}, 'Point' );
$!c, False, Int, 42
 
$VAR1 = bless( {
'r' => 4
}, 'Circle' );
 
$VAR1 = bless( {
'r' => 3,
'x' => 1,
'y' => 2
}, 'Circle' );
</pre>
 
=={{header|Phix}}==
Public attributes (in this case, <tt>$.b</tt> and <tt>$.c</tt>) are really just attributes for which the compiler also auto-generates a method of the same name. See [[Reflection/List_methods#Perl_6]].
{{libheader|Phix/Class}}
Needs 0.8.1+
Note that content from and parameters to get_struct_type/fields() may change between releases.<br>
You should certainly be prepared for them to return NULL for unrecognised field names and types.<br>
Technically the code below is re-fetching tid and flags before returning them in a textual format.
 
<!--<syntaxhighlight lang="phix">-->
<span style="color: #008080;">class</span> <span style="color: #000000;">c</span> <span style="color: #7060A8;">nullable</span>
<span style="color: #004080;">integer</span> <span style="color: #004080;">int</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">public</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">atm</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">2.3</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">str</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"4point5"</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">seq</span>
<span style="color: #008080;">public</span><span style="color: #0000FF;">:</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">obj</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"an object"</span><span style="color: #0000FF;">}</span>
<span style="color: #000000;">c</span> <span style="color: #000000;">child</span>
<span style="color: #008080;">private</span> <span style="color: #008080;">function</span> <span style="color: #000000;">foo</span><span style="color: #0000FF;">();</span>
<span style="color: #008080;">public</span> <span style="color: #008080;">procedure</span> <span style="color: #000000;">bar</span><span style="color: #0000FF;">();</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">class</span>
<span style="color: #000000;">c</span> <span style="color: #000000;">c_instance</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #000000;">structs</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> <span style="color: #7060A8;">as</span> <span style="color: #000000;">structs</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">nulls</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">=</span><span style="color: #004600;">NULL</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"NULL"</span><span style="color: #0000FF;">:</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">fields</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">structs</span><span style="color: #0000FF;">:</span><span style="color: #000000;">get_struct_fields</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fields</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #0000FF;">{</span><span style="color: #004080;">string</span> <span style="color: #000000;">name</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">tid</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">flags</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">fields</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">flags</span><span style="color: #0000FF;">,</span><span style="color: #000000;">SF_RTN</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- (exclude foo/bar)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nulls</span><span style="color: #0000FF;">(</span><span style="color: #000000;">structs</span><span style="color: #0000FF;">:</span><span style="color: #000000;">get_field_type</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">name</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)),</span>
<span style="color: #000000;">f</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nulls</span><span style="color: #0000FF;">(</span><span style="color: #000000;">structs</span><span style="color: #0000FF;">:</span><span style="color: #000000;">get_field_flags</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">name</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">))</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">v</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nulls</span><span style="color: #0000FF;">(</span><span style="color: #000000;">structs</span><span style="color: #0000FF;">:</span><span style="color: #000000;">fetch_field</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c_instance</span><span style="color: #0000FF;">,</span><span style="color: #000000;">name</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"type:%-11s, name:%-5s, flags:%s, value:%v\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #000000;">name</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">,</span><span style="color: #000000;">v</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
 
{{out}}
<pre>
type:ST_INTEGER , name:int , flags:SF_PRIVATE, value:1
type:ST_ATOM , name:atm , flags:SF_PUBLIC, value:2.3
type:ST_STRING , name:str , flags:SF_PRIVATE, value:"4point5"
type:ST_SEQUENCE, name:seq , flags:SF_PRIVATE, value:{}
type:ST_OBJECT , name:obj , flags:SF_PUBLIC, value:{"an object"}
type:c , name:child, flags:SF_PUBLIC, value:"NULL"
</pre>
 
=={{header|PHP}}==
<langsyntaxhighlight lang="php"><?
class Foo {
}
Line 195 ⟶ 806:
 
var_dump(get_object_vars($obj));
?></langsyntaxhighlight>
{{out}}
<pre>
Line 204 ⟶ 815:
bool(true)
}
</pre>
 
=={{header|PicoLisp}}==
The function <code>show</code> can be used to print all properties of an object.
 
First we define a rectangle class <code>+Rectangle</code> as subclass of a shape class <code>+Shape</code>:
 
<syntaxhighlight lang="picolisp">
# The Rectangle class
(class +Rectangle +Shape)
# dx dy
 
(dm T (X Y DX DY)
(super X Y)
(=: dx DX)
(=: dy DY) )
 
(dm area> ()
(* (: dx) (: dy)) )
 
(dm perimeter> ()
(* 2 (+ (: dx) (: dy))) )
 
(dm draw> ()
(drawRect (: x) (: y) (: dx) (: dy)) ) # Hypothetical function 'drawRect'
</syntaxhighlight>
 
Then we can create an object of the +Rectangle class and check its properties using the <code>show</code> function.
 
<syntaxhighlight lang="text">
: (setq R (new '(+Rectangle) 0 0 30 20))
-> $177356065126400
 
: (show R)
$177715702441044 (+Rectangle)
dy 20
dx 30
y 0
x 0
-> $177715702441044
</syntaxhighlight>
 
 
=={{header|PL/I}}==
<code>PUT DATA(X)</code> will send to SYSOUT the value(s) of X prefixed by the name(s), formatted appropriately for single/double bit/integer/real/complex, character, ''etc.'' whether <code>X</code> is a single datum, an array, a data structure, ''etc.'' A list of items may be specified, not just the single <code>X</code> and for input, the word is <code>GET</code>. Similarly, <code>PUT STRING(TEXT) DATA(X)</code> will place such output in a character variable, which may have to be large...
 
=={{header|PowerShell}}==
In PowerShell '''everything''' is an object. To find any type of member of any object use the <code>Get-Member</code> Cmdlet.
 
Here we find the properties of a <code>[DateTime]</code> object:
<syntaxhighlight lang="powershell">
Get-Date | Get-Member -MemberType Property
</syntaxhighlight>
 
{{Out}}
<pre>
TypeName: System.DateTime
 
Name MemberType Definition
---- ---------- ----------
Date Property datetime Date {get;}
Day Property int Day {get;}
DayOfWeek Property System.DayOfWeek DayOfWeek {get;}
DayOfYear Property int DayOfYear {get;}
Hour Property int Hour {get;}
Kind Property System.DateTimeKind Kind {get;}
Millisecond Property int Millisecond {get;}
Minute Property int Minute {get;}
Month Property int Month {get;}
Second Property int Second {get;}
Ticks Property long Ticks {get;}
TimeOfDay Property timespan TimeOfDay {get;}
Year Property int Year {get;}
</pre>
The "Add" methods of a <code>[DateTime]</code> object:
<syntaxhighlight lang="powershell">
Get-Date | Get-Member -MemberType Method -Name Add*
</syntaxhighlight>
{{Out}}
<pre>
TypeName: System.DateTime
 
Name MemberType Definition
---- ---------- ----------
Add Method datetime Add(timespan value)
AddDays Method datetime AddDays(double value)
AddHours Method datetime AddHours(double value)
AddMilliseconds Method datetime AddMilliseconds(double value)
AddMinutes Method datetime AddMinutes(double value)
AddMonths Method datetime AddMonths(int months)
AddSeconds Method datetime AddSeconds(double value)
AddTicks Method datetime AddTicks(long value)
AddYears Method datetime AddYears(int value)
</pre>
 
Line 209 ⟶ 913:
The <code>[https://docs.python.org/3.5/library/functions.html#dir dir()]</code> function and Python's <code>[https://docs.python.org/3.5/library/inspect.html#module-inspect inspect]</code> module both will list properties.
 
<langsyntaxhighlight lang="python">class Parent(object):
__priv = 'private'
Line 290 ⟶ 994:
inspect.getmembers(chld)
#[('__class__', <class '__main__.Child'>), ..., ('args', (0, 'I', 'two')), ('args_bleh', "(0, 'I', 'two') bleh"), ('doNothing', <bound method Child.doNothing of Child(chld, 0, 'I', 'two')>), ('doStuff', <bound method Child.doStuff of Child(chld, 0, 'I', 'two')>), ('name', 'chld'), ('name_bleh', 'chld bleh'), ('own', "chld's own"), ('own_bleh', "chld's own bleh"), ('reBleh', <_sre.SRE_Pattern object at 0x10067bd20>), ('reBleh_bleh', '<_sre.SRE_Pattern object at 0x10067bd20> bleh')]
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
 
You can get a list of an object's attributes (instance variables) using <tt>.^attributes</tt>, which is part of the [https://docs.raku.org/type/Metamodel$COLON$COLONClassHOW Meta Object Protocol]..<br>
Each is represented as an <tt>Attribute</tt> object that contains a bunch of info:
 
<syntaxhighlight lang="raku" line>class Foo {
has $!a = now;
has Str $.b;
has Int $.c is rw;
}
 
my $object = Foo.new: b => "Hello", c => 42;
 
for $object.^attributes {
say join ", ", .name, .readonly, .container.^name, .get_value($object);
}</syntaxhighlight>
 
{{out}}
<pre>
$!a, True, Any, Instant:1470517602.295992
$!b, True, Str, Hello
$!c, False, Int, 42
</pre>
 
Public attributes (in this case, <tt>$.b</tt> and <tt>$.c</tt>) are really just attributes for which the compiler also auto-generates a method of the same name. See [[Reflection/List_methods#Raku]].
 
=={{header|REXX}}==
===version 1===
(This REXX version is modeled after the &nbsp; '''PL/I''' &nbsp; entry.)
 
 
The &nbsp; '''say''' &nbsp; instruction can display a value (its contents) to
the console (terminal) as well as
its length &nbsp; (the number of characters in its value).
 
Since &nbsp; ''everything'' &nbsp; in REXX is a character string, the &nbsp; ''type'' &nbsp; of the
variable (character) need not be explicitly expressed.
 
 
A simplistic example:
<syntaxhighlight lang="rexx">j=2
abc.j= -4.12
 
 
say 'variable abc.2 (length' length(abc.2)')=' abc.2</syntaxhighlight>
<br><br>
===version 2===
<syntaxhighlight lang="rexx">/* REXX shows the "equivalent" to PL/I's PUT DATA for a simple variable */
/* put_data2('a.') to show all a.tail values isn't that easy :-) */
j=2
abc.j= -4.12
Say put_data('abc.2') /* Put Data(abc(2)) */
string=put_data('abc.2') /* Put string(string) Data(abc(2)) */
Say string
Exit
put_data:
Parse Arg variable
return(variable'='''value(variable)'''')</syntaxhighlight>
{{out}}
<pre>abc.2='-4.12'
abc.2='-4.12'</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">class Foo
@@xyz = nil
def initialize(name, age)
Line 321 ⟶ 1,088:
p Foo.class_variable_get(:@@xyz) #=> :xyz
p Foo.class_variable_set(:@@abc, 123) #=> 123
p Foo.class_variables #=> [:@@xyz, :@@abc]</langsyntaxhighlight>
 
=={{header|Scala}}==
===Java Interoperability===
{{Out}}Best seen running in your browser [https://scastie.scala-lang.org/MdkPxH6yTlS4W8TaXYxSgA Scastie (remote JVM)].
<syntaxhighlight lang="scala">object ListProperties extends App {
private val obj = new {
val examplePublicField: Int = 42
private val examplePrivateField: Boolean = true
}
private val clazz = obj.getClass
 
println("All public methods (including inherited):")
clazz.getFields.foreach(f => println(s"${f}\t${f.get(obj)}"))
 
println("\nAll declared fields (excluding inherited):")
clazz.getDeclaredFields.foreach(f => println(s"${f}}"))
}</syntaxhighlight>
 
=={{header|Smalltalk}}==
for names of slots defined in the class (excludes inherited):
<syntaxhighlight lang="smalltalk">someObject class instVarNames</syntaxhighlight>
for all slot names (incl. inherited):
<syntaxhighlight lang="text">someObject class allInstVarNames</syntaxhighlight>
to get a Dictionary (aka. HashTable) mapping names to values:
<syntaxhighlight lang="text">someObject class allInstVarNames collect:[:nm | nm -> (someObject instVarNamed:nm)] as:Dictionary</syntaxhighlight>
 
A class can make this a secret by redefining #instVar access to eg. raise an exception.
Notice: this is not considered good Smalltalk style - it should be used by debuggers and object inspectors only, except for special frameworks (such as code generators etc.).
 
=={{header|Tcl}}==
Tcl objects do not have properties exactly (externally visible variables), though a common idiom pioneered by <b>Tk</b> is <i>options</i> exposed by the <tt>configure</tt> and <tt>cget</tt> commands.
 
For objects supporting this protocol, you can list all options by invoking the <tt>configure</tt> method without arguments (result split over multiple lines for readability):
<syntaxhighlight lang="tcl">% package require Tk
8.6.5
% . configure
{-bd -borderwidth} {-borderwidth borderWidth BorderWidth 0 0} {-class class Class Toplevel Tclsh}
{-menu menu Menu {} {}} {-relief relief Relief flat flat} {-screen screen Screen {} {}} {-use use Use {} {}}
{-background background Background #d9d9d9 #d9d9d9} {-bg -background} {-colormap colormap Colormap {} {}}
{-container container Container 0 0} {-cursor cursor Cursor {} {}} {-height height Height 0 0}
{-highlightbackground highlightBackground HighlightBackground #d9d9d9 #d9d9d9}
{-highlightcolor highlightColor HighlightColor #000000 #000000}
{-highlightthickness highlightThickness HighlightThickness 0 0} {-padx padX Pad 0 0} {-pady padY Pad 0 0}
{-takefocus takeFocus TakeFocus 0 0} {-visual visual Visual {} {}} {-width width Width 0 0}</syntaxhighlight>
 
Two-element sublists (eg <tt>-bd -borderwidth</tt>) represent aliases, and five-element sublists are of the form <tt>{optionName dbName dbClass defaultValue currentValue}</tt>. <tt>dbName</tt> and <tt>dbClass</tt> are related to how the option is specified in the <i>option database</i>.
 
Simply listing the option names is like this:
 
<syntaxhighlight lang="tcl">% lmap o [. configure] {if {[llength $o] == 2} continue else {lindex $o 0}}
-borderwidth -class -menu -relief -screen -use -background -colormap -container -cursor -height
-highlightbackground -highlightcolor -highlightthickness -padx -pady -takefocus -visual -width</syntaxhighlight>
 
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<syntaxhighlight lang="vbnet">Imports System.Reflection
 
Module Module1
 
Class TestClass
Private privateField = 7
Public ReadOnly Property PublicNumber = 4
Private ReadOnly Property PrivateNumber = 2
End Class
 
Function GetPropertyValues(Of T)(obj As T, flags As BindingFlags) As IEnumerable
Return From p In obj.GetType().GetProperties(flags)
Where p.GetIndexParameters().Length = 0
Select New With {p.Name, Key .Value = p.GetValue(obj, Nothing)}
End Function
 
Function GetFieldValues(Of T)(obj As T, flags As BindingFlags) As IEnumerable
Return obj.GetType().GetFields(flags).Select(Function(f) New With {f.Name, Key .Value = f.GetValue(obj)})
End Function
 
Sub Main()
Dim t As New TestClass()
Dim flags = BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance
For Each prop In GetPropertyValues(t, flags)
Console.WriteLine(prop)
Next
For Each field In GetFieldValues(t, flags)
Console.WriteLine(field)
Next
End Sub
 
End Module</syntaxhighlight>
{{out}}
<pre>{ Name = PublicNumber, Value = 4 }
{ Name = PrivateNumber, Value = 2 }
{ Name = privateField, Value = 7 }
{ Name = _PublicNumber, Value = 4 }
{ Name = _PrivateNumber, Value = 2 }</pre>
 
=={{header|Wren}}==
Wren doesn't currently have reflection as such but it's possible to identify a class's properties and list them at runtime by placing a suitable attribute on the class.
 
Note that, since attributes are stored internally as a map, the order in which the property names appear is undefined.
<syntaxhighlight lang="wren">#! instance_methods(m, n, o)
#! instance_properties(p, q, r)
class C {
construct new() {}
 
m() {}
 
n() {}
 
o() {}
p {}
 
q {}
r {}
}
 
var c = C.new() // create an object of type C
System.print("List of properties available for object 'c':")
for (property in c.type.attributes.self["instance_properties"]) System.print(property.key)</syntaxhighlight>
 
{{out}}
<pre>
List of properties available for object 'c':
r
q
p
</pre>
 
=={{header|zkl}}==
Line 327 ⟶ 1,221:
 
Every object has a "properties" method, which returns a list of property names [for that object].
<langsyntaxhighlight lang="zkl">properties:=List.properties;
properties.println();
List(1,2,3).property(properties[0]).println(); // get value
List(1,2,3).Property(properties[0])().println(); // method that gets value
List(1,2,3).BaseClass(properties[0]).println(); // another way to get value</langsyntaxhighlight>
{{out}}
<pre>
162

edits