Reflection/List methods: Difference between revisions

From Rosetta Code
Content added Content deleted
(Add Ecstasy example)
 
(14 intermediate revisions by 9 users not shown)
Line 4: Line 4:
{{omit from|Modula-2}}
{{omit from|Modula-2}}
{{omit from|Rust}}
{{omit from|Rust}}
{{omit from|6502 Assembly}}
{{omit from|68000 Assembly}}
{{omit from|Z80 Assembly}}
{{omit from|8086 Assembly}}
{{omit from|x86 Assembly}}
{{omit from|ARM Assembly}}
[[Category:Programming Tasks]] [[Category:Object oriented]]
[[Category:Programming Tasks]] [[Category:Object oriented]]


Line 12: Line 18:


=={{header|C sharp}}==
=={{header|C sharp}}==
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;
using System.Reflection;
using System.Reflection;


Line 37: Line 43:
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 55: Line 61:
=={{header|Clojure}}==
=={{header|Clojure}}==


<lang clojure>
<syntaxhighlight lang="clojure">
; Including listing private methods in the clojure.set namespace:
; Including listing private methods in the clojure.set namespace:
=> (keys (ns-interns 'clojure.set))
=> (keys (ns-interns 'clojure.set))
Line 62: Line 68:
; Only public:
; Only public:
=> (keys (ns-publics 'clojure.set))
=> (keys (ns-publics 'clojure.set))
(union map-invert join select intersection superset? index subset? rename rename-keys project difference)</lang>
(union map-invert join select intersection superset? index subset? rename rename-keys project difference)</syntaxhighlight>


=={{header|D}}==
=={{header|D}}==
D allows you to perform compile-time reflection for code generation, such as printing a list of the functions in a struct or class.
D allows you to perform compile-time reflection for code generation, such as printing a list of the functions in a struct or class.
<lang D>struct S {
<syntaxhighlight lang="d">struct S {
bool b;
bool b;


Line 98: Line 104:
printMethods!S;
printMethods!S;
printMethods!C;
printMethods!C;
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 112: Line 118:
opEquals
opEquals
factory</pre>
factory</pre>

=={{header|Ecstasy}}==
For any object, the type of that object provides access to its methods and functions:

<syntaxhighlight lang="ecstasy">
module test {
void run() {
@Inject Console console;

String[] names = &this.actualType.multimethods.keys.toArray();
console.print($"Method/function names on {this}: {names}");

Method[] methods = &this.actualType.methods;
console.print($"The methods of {this}: {methods}");

Function[] functions = &this.actualType.functions;
console.print($"The functions of {this}: {functions}");
}
}
</syntaxhighlight>

{{out}}
<pre>
x$ xec test
Method/function names on test: [toString, makeImmutable, to, estimateStringLength, appendTo, exTo, toEx, exToEx, isModuleImport, classForName, typeForName, run, hashCode, maxOf, notGreaterThan, compare, equals, minOf, notLessThan]
The methods of test: [String toString(), immutable Object makeImmutable(), Range<Orderable> to(Orderable that), Int estimateStringLength(), Appender<Char> appendTo(Appender<Char> buf), Range<Orderable> exTo(Orderable that), Range<Orderable> toEx(Orderable that), Range<Orderable> exToEx(Orderable that), conditional Module isModuleImport(), conditional Class classForName(String name), conditional Type typeForName(String name), void run()]
The functions of test: [Int hashCode(Type<Package> CompileType, CompileType value), CompileType maxOf(Type<Orderable> CompileType, CompileType value1, CompileType value2), CompileType notGreaterThan(Type<Orderable> CompileType, CompileType value1, CompileType value2), Ordered compare(Type<Const> CompileType, CompileType value1, CompileType value2), Boolean equals(Type<Package> CompileType, CompileType value1, CompileType value2), CompileType minOf(Type<Orderable> CompileType, CompileType value1, CompileType value2), CompileType notLessThan(Type<Orderable> CompileType, CompileType value1, CompileType value2)]
</pre>


=={{header|Elena}}==
=={{header|Elena}}==
ELENA 5.0 :
ELENA 6.x :
<lang elena>import system'routines;
<syntaxhighlight lang="elena">import system'routines;
import system'dynamic;
import system'dynamic;
import extensions;
import extensions;
Line 130: Line 164:
var o := new MyClass();
var o := new MyClass();
o.__getClass().__getMessages().forEach:(p)
o.__getClass().__getMessages().forEach::(p)
{
{
console.printLine("o.",p)
console.printLine("o.",p)
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 142: Line 176:
o.myMethod1[1]
o.myMethod1[1]
o.myMethod2[2]
o.myMethod2[2]
o.#cast[1]
</pre>
</pre>


=={{header|Factor}}==
=={{header|Factor}}==
In Factor, methods are contained in generic words rather than objects, while methods specialize on a class. Therefore, the programmer must decide whether they want the list of methods in a generic word, or the list of methods that specialize on a class. Luckily, the <tt>methods</tt> word can do either depending on what type you give it (a word or a class). The returned sequence contains first-class word values suitable for executing.
In Factor, methods are contained in generic words rather than objects, while methods specialize on a class. Therefore, the programmer must decide whether they want the list of methods in a generic word, or the list of methods that specialize on a class. Luckily, the <tt>methods</tt> word can do either depending on what type you give it (a word or a class). The returned sequence contains first-class word values suitable for executing.
<lang factor>USING: io math prettyprint see ;
<syntaxhighlight lang="factor">USING: io math prettyprint see ;


"The list of methods contained in the generic word + :" print
"The list of methods contained in the generic word + :" print
Line 153: Line 186:


"The list of methods specializing on the fixnum class:" print
"The list of methods specializing on the fixnum class:" print
fixnum methods .</lang>
fixnum methods .</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 203: Line 236:
M\ fixnum u>=
M\ fixnum u>=
}
}
</pre>

=={{header|Frink}}==
Frink allows you to list the methods of a Frink-based or Java-based object with the <CODE>methods[obj]</CODE> function.
<syntaxhighlight lang="frink">a = new array
methods[a]</syntaxhighlight>
{{out}}
<pre>[
pushAll[arg1],
insert[arg1, arg2],
indexOf[arg1],
indexOf[arg1, arg2],
removeAll[arg1],
shuffle[],
dimensions[],
push[arg1],
pop[],
contains[arg1],
subsets[],
subsets[arg1, arg2],
transpose[],
isEmpty[],
lexicographicPermute[],
lexicographicPermute[arg1],
popFirst[],
clear[],
peek[],
shallowCopy[],
pushFirst[arg1],
removeValue[arg1],
timSort[],
timSort[arg1],
timSort[arg1, arg2],
permute[],
removeLen[arg1, arg2],
lastIndexOf[arg1],
lastIndexOf[arg1, arg2],
combinations[arg1],
removeRandom[],
remove[arg1],
remove[arg1, arg2]]
</pre>

Or, for a Java object:
<syntaxhighlight lang="frink">f = newJava["java.io.File", "."]
methods[f]</syntaxhighlight>
{{out}}
<pre>[
boolean equals[java.lang.Object arg1],
long length[],
java.lang.String toString[],
int hashCode[],
int compareTo[java.lang.Object arg1],
int compareTo[java.io.File arg1],
java.lang.String getName[],
java.lang.String[] list[java.io.FilenameFilter arg1],
java.lang.String[] list[],
java.lang.String getParent[],
boolean isAbsolute[],
boolean delete[],
boolean setReadOnly[],
boolean canRead[],
java.lang.String getPath[],
java.net.URI toURI[],
java.net.URL toURL[],
java.io.File getParentFile[],
java.lang.String getAbsolutePath[],
java.io.File getAbsoluteFile[],
java.lang.String getCanonicalPath[],
java.io.File getCanonicalFile[],
boolean isDirectory[],
boolean canWrite[],
boolean exists[],
boolean isFile[],
boolean isHidden[],
long lastModified[],
boolean createNewFile[],
void deleteOnExit[],
java.io.File[] listFiles[java.io.FileFilter arg1],
java.io.File[] listFiles[],
java.io.File[] listFiles[java.io.FilenameFilter arg1],
boolean mkdir[],
boolean mkdirs[],
boolean renameTo[java.io.File arg1],
boolean setLastModified[long arg1],
boolean setWritable[boolean arg1],
boolean setWritable[boolean arg1, boolean arg2],
boolean setReadable[boolean arg1],
boolean setReadable[boolean arg1, boolean arg2],
boolean setExecutable[boolean arg1, boolean arg2],
boolean setExecutable[boolean arg1],
boolean canExecute[],
java.io.File[] listRoots[],
long getTotalSpace[],
long getFreeSpace[],
long getUsableSpace[],
java.io.File createTempFile[java.lang.String arg1, java.lang.String arg2, java.io.File arg3],
java.io.File createTempFile[java.lang.String arg1, java.lang.String arg2],
java.nio.file.Path toPath[],
void wait[long arg1],
void wait[long arg1, int arg2],
void wait[],
java.lang.Class getClass[],
void notify[],
void notifyAll[]]
</pre>
</pre>


Line 211: Line 349:
of each exported method.<br>
of each exported method.<br>
privateMethod is not exported because the first character is lowercase.
privateMethod is not exported because the first character is lowercase.
<lang go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 247: Line 385:
}
}
fmt.Println()
fmt.Println()
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 267: Line 405:
Sub func(image.Point, image.Point) image.Point func(image.Point) image.Point
Sub func(image.Point, image.Point) image.Point func(image.Point) image.Point
</pre>
</pre>

=={{Header|Insitux}}==

Insitux does not have classes and therefore technically does not have methods. However, it is possible to list all the functions in global lexical space:

<syntaxhighlight lang="insitux">
; lists all built-in and user-defined functions, including those within variables
(-> (symbols)
(map eval)
(filter (comp type-of (= "func"))))

; lists only user-defined functions, including those within variables
(-> (symbols)
(map eval)
(filter (comp type-of (= "func")))
(remove about))
</syntaxhighlight>


=={{header|J}}==
=={{header|J}}==
<syntaxhighlight lang="j">
<lang j>
NB. define a stack class
NB. define a stack class
coclass 'Stack'
coclass 'Stack'
Line 311: Line 466:
COCREATOR items
COCREATOR items
</syntaxhighlight>
</lang>


=={{header|Java}}==
=={{header|Java}}==
<lang java>import java.lang.reflect.Method;
<syntaxhighlight lang="java">import java.lang.reflect.Method;


public class ListMethods {
public class ListMethods {
Line 338: Line 493:
}
}
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 362: Line 517:
In JavaScript, methods are properties that are functions, so methods are retrieved by [[Reflection/List properties|getting properties]] and filtering. 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.
In JavaScript, methods are properties that are functions, so methods are retrieved by [[Reflection/List properties|getting properties]] and filtering. 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.


<lang javascript>// Sample classes for reflection
<syntaxhighlight lang="javascript">// Sample classes for reflection
function Super(name) {
function Super(name) {
this.name = name;
this.name = name;
Line 446: Line 601:
Object.entries(sub)
Object.entries(sub)
.filter(function(p) {return typeof p[1] == 'function';})
.filter(function(p) {return typeof p[1] == 'function';})
//[["subOwn", function () {...}]]</lang>
//[["subOwn", function () {...}]]</syntaxhighlight>


=={{header|Julia}}==
=={{header|Julia}}==
{{works with|Julia|0.6}}
{{works with|Julia|0.6}}


<lang julia>methods(methods)
<syntaxhighlight lang="julia">methods(methods)
methods(println)</lang>
methods(println)</syntaxhighlight>


{{out}}
{{out}}
Line 468: Line 623:
=={{header|Kotlin}}==
=={{header|Kotlin}}==
Note that kotlin-reflect.jar needs to be included in the classpath for this program.
Note that kotlin-reflect.jar needs to be included in the classpath for this program.
<lang scala>// Version 1.2.31
<syntaxhighlight lang="scala">// Version 1.2.31


import kotlin.reflect.full.functions
import kotlin.reflect.full.functions
Line 491: Line 646:
val fs = c.functions
val fs = c.functions
for (f in fs) println("${f.name}, ${f.visibility}")
for (f in fs) println("${f.name}, ${f.visibility}")
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 508: Line 663:


=={{header|Lingo}}==
=={{header|Lingo}}==
<lang lingo>-- parent script "MyClass"
<syntaxhighlight lang="lingo">-- parent script "MyClass"


on foo (me)
on foo (me)
Line 516: Line 671:
on bar (me)
on bar (me)
put "bar"
put "bar"
end</lang>
end</syntaxhighlight>


<lang lingo>obj = script("MyClass").new()
<syntaxhighlight lang="lingo">obj = script("MyClass").new()
put obj.handlers()
put obj.handlers()
-- [#foo, #bar]
-- [#foo, #bar]
Line 528: Line 683:


call(#bar, obj)
call(#bar, obj)
-- "bar"</lang>
-- "bar"</syntaxhighlight>


=={{header|Lua}}==
=={{header|Lua}}==
<lang lua>function helloWorld()
<syntaxhighlight lang="lua">function helloWorld()
print "Hello World"
print "Hello World"
end
end
Line 551: Line 706:
end
end


printFunctions(_G)</lang>
printFunctions(_G)</syntaxhighlight>
{{out}}
{{out}}
<pre>assert
<pre>assert
Line 586: Line 741:


=={{header|Nanoquery}}==
=={{header|Nanoquery}}==
<lang Nanoquery>// create a class with methods that will be listed
<syntaxhighlight lang="nanoquery">// create a class with methods that will be listed
class Methods
class Methods
def static method1()
def static method1()
Line 605: Line 760:
for method in dir(new(Methods))
for method in dir(new(Methods))
println method
println method
end</lang>
end</syntaxhighlight>


{{out}}
{{out}}
Line 642: Line 797:
=={{header|Nim}}==
=={{header|Nim}}==
Nim separates data and functions, but with method call syntax, any function that has that object as its first parameter can be used like a method:
Nim separates data and functions, but with method call syntax, any function that has that object as its first parameter can be used like a method:
<lang nim>type Foo = object
<syntaxhighlight lang="nim">type Foo = object
proc bar(f:Foo) = echo "bar"
proc bar(f:Foo) = echo "bar"
var f:Foo
var f:Foo
f.bar()</lang>
f.bar()</syntaxhighlight>
this also means object 'methods' can be defined across multiple source files
this also means object 'methods' can be defined across multiple source files


Line 655: Line 810:
and
and
* have our type, or a related type (var Foo, ptr Foo, ref Foo) as first parameter
* have our type, or a related type (var Foo, ptr Foo, ref Foo) as first parameter
<lang nim>import macros, fusion/matching
<syntaxhighlight lang="nim">import macros, fusion/matching
{.experimental: "caseStmtMacros".}
{.experimental: "caseStmtMacros".}
macro listMethods(modulepath:static string, typename): untyped =
macro listMethods(modulepath:static string, typename): untyped =
Line 680: Line 835:
.._]: procs.add($name)
.._]: procs.add($name)
result = newLit(procs)
result = newLit(procs)


type Bar = object
type Bar = object
proc a*(b: Bar) = discard
proc a*(b: Bar) = discard
Line 687: Line 842:
template c*(b: var Bar, c: float) = discard
template c*(b: var Bar, c: float) = discard
iterator d*(b: ptr Bar):int = discard
iterator d*(b: ptr Bar):int = discard
method e*(b:ref Bar) = discard
method e*(b:ref Bar) {.base.} = discard
proc second_param*(a: int, b: Bar) = discard #will not match
proc second_param*(a: int, b: Bar) = discard #will not match
proc unexported(a: Bar) = discard #will not match
proc unexported(a: Bar) = discard #will not match


template thisfile:string =
template thisfile:string =
instantiationInfo().filename
instantiationInfo().filename
echo thisfile.listMethods(Bar)
echo thisfile.listMethods(Bar)

#works for any module:
#works for any module:
#const lib = "/path/to/nim/lib/pure/collections/tables.nim"
#const lib = "/path/to/nim/lib/pure/collections/tables.nim"
echo listMethods(lib,Table[A,B])</lang>
echo listMethods(lib,Table[A,B])</syntaxhighlight>
{{out}}<pre>@["a", "b", "c", "d", "e"]
{{out}}<pre>@["a", "b", "c", "d", "e"]
@["[]=", "[]", "[]", "hasKey", "contains", "hasKeyOrPut", "getOrDefault", "getOrDefault", "mgetOrPut", "len", "add", "del", "pop", "take", "clear", "$", "withValue", "withValue", "pairs", "mpairs", "keys", "values", "mvalues", "allValues"]</pre>
@["[]=", "[]", "[]", "hasKey", "contains", "hasKeyOrPut", "getOrDefault", "getOrDefault", "mgetOrPut", "len", "add", "del", "pop", "take", "clear", "$", "withValue", "withValue", "pairs", "mpairs", "keys", "values", "mvalues", "allValues"]</pre>


=={{header|Objective-C}}==
=={{header|Objective-C}}==
<lang objc>#import <Foundation/Foundation.h>
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <objc/runtime.h>


Line 725: Line 880:
free(methods);
free(methods);
return 0;
return 0;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 735: Line 890:
Note that the overloaded comparison operator also shows up in the list of methods.
Note that the overloaded comparison operator also shows up in the list of methods.


<lang perl>package Nums;
<syntaxhighlight lang="perl">package Nums;


use overload ('<=>' => \&compare);
use overload ('<=>' => \&compare);
Line 744: Line 899:


my $a = Nums->new(42);
my $a = Nums->new(42);
print "$_\n" for %{ref ($a)."::" });</lang>
print "$_\n" for %{ref ($a)."::" });</syntaxhighlight>
{{out}}
{{out}}
<pre>double
<pre>double
Line 755: Line 910:


Another alternative is the module <code>Class::MOP</code>, which implements a meta-object protocol for the Perl. It alters nothing about Perl's object system; it is just a tool for manipulation and introspection. Note that this output includes methods inherited methods (<tt>DOES, VERSION, can, isa</tt>)
Another alternative is the module <code>Class::MOP</code>, which implements a meta-object protocol for the Perl. It alters nothing about Perl's object system; it is just a tool for manipulation and introspection. Note that this output includes methods inherited methods (<tt>DOES, VERSION, can, isa</tt>)
<lang perl>use Class::MOP;
<syntaxhighlight lang="perl">use Class::MOP;
my $meta = Class::MOP::Class->initialize( ref $a );
my $meta = Class::MOP::Class->initialize( ref $a );
say join "\n", $meta->get_all_method_names()</lang>
say join "\n", $meta->get_all_method_names()</syntaxhighlight>
{{out}}
{{out}}
<pre>compare
<pre>compare
Line 772: Line 927:
===emulated===
===emulated===
Even before the introduction of classes (see below), but this sort of thing was fairly easy to emulate.
Even before the introduction of classes (see below), but this sort of thing was fairly easy to emulate.
<!--<syntaxhighlight lang="phix">-->
<lang Phix>enum METHODS, PROPERTIES
<span style="color: #008080;">enum</span> <span style="color: #000000;">METHODS</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">PROPERTIES</span>

sequence all_methods = {}
<span style="color: #004080;">sequence</span> <span style="color: #000000;">all_methods</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>

function method_visitor(object key, object /*data*/, object /*user_data*/)
<span style="color: #008080;">function</span> <span style="color: #000000;">method_visitor</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">key</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">object</span> <span style="color: #000080;font-style:italic;">/*data*/</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">/*user_data*/</span><span style="color: #0000FF;">)</span>
all_methods = append(all_methods,key)
<span style="color: #000000;">all_methods</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">all_methods</span><span style="color: #0000FF;">,</span><span style="color: #000000;">key</span><span style="color: #0000FF;">)</span>
return 1
<span style="color: #008080;">return</span> <span style="color: #000000;">1</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>

function get_all_methods(object o)
<span style="color: #008080;">function</span> <span style="color: #000000;">get_all_methods</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">o</span><span style="color: #0000FF;">)</span>
all_methods = {}
<span style="color: #000000;">all_methods</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
traverse_dict(routine_id("method_visitor"),0,o[METHODS])
<span style="color: #7060A8;">traverse_dict</span><span style="color: #0000FF;">(</span><span style="color: #000000;">method_visitor</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">o</span><span style="color: #0000FF;">[</span><span style="color: #000000;">METHODS</span><span style="color: #0000FF;">])</span>
return all_methods
<span style="color: #008080;">return</span> <span style="color: #000000;">all_methods</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>

--class X: Xmethods emulates a vtable
<span style="color: #008080;">function</span> <span style="color: #000000;">exists</span><span style="color: #0000FF;">()</span>
constant Xmethods = new_dict()
<span style="color: #008080;">return</span> <span style="color: #008000;">"exists"</span>

<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function exists()
return "exists"
<span style="color: #000080;font-style:italic;">--class X: Xmethods emulates a vtable</span>
end function
<span style="color: #008080;">constant</span> <span style="color: #000000;">Xmethods</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new_dict</span><span style="color: #0000FF;">({{</span><span style="color: #008000;">"exists"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">exists</span><span style="color: #0000FF;">}})</span>

setd("exists",routine_id("exists"),Xmethods)
<span style="color: #000080;font-style:italic;">--class X: destructor</span>

<span style="color: #008080;">procedure</span> <span style="color: #000000;">destructor</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">o</span><span style="color: #0000FF;">)</span>
--class X: destructor
<span style="color: #7060A8;">destroy_dict</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">[</span><span style="color: #000000;">PROPERTIES</span><span style="color: #0000FF;">])</span>
procedure destructor(object o)
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
destroy_dict(o[PROPERTIES])
end procedure
<span style="color: #000080;font-style:italic;">--class X: create new instances</span>
constant r_destroy = routine_id("destructor")
<span style="color: #008080;">function</span> <span style="color: #000000;">newX</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">)</span>

<span style="color: #004080;">integer</span> <span style="color: #000000;">Xproperties</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new_dict</span><span style="color: #0000FF;">({{</span><span style="color: #008000;">"x"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"y"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">}})</span>
--class X: create new instances
<span style="color: #004080;">object</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">delete_routine</span><span style="color: #0000FF;">({</span><span style="color: #000000;">Xmethods</span><span style="color: #0000FF;">,</span><span style="color: #000000;">Xproperties</span><span style="color: #0000FF;">},</span><span style="color: #000000;">destructor</span><span style="color: #0000FF;">)</span>
function newX(object x,y)
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
integer Xproperties = new_dict()
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
setd("x",x,Xproperties)
setd("y",y,Xproperties)
<span style="color: #004080;">object</span> <span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">newX</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"string"</span><span style="color: #0000FF;">)</span>
object res = delete_routine({Xmethods,Xproperties},r_destroy)
return res
<span style="color: #0000FF;">?</span><span style="color: #000000;">get_all_methods</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)</span>
end function
<!--</syntaxhighlight>-->

object x = newX(2,"string")

?get_all_methods(x)</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 822: Line 974:
Needs 0.8.1+
Needs 0.8.1+
Note that content from and parameters to get_struct_fields() may change between releases.
Note that content from and parameters to get_struct_fields() may change between releases.
<!--<syntaxhighlight lang="phix">-->
<lang Phix>class c
<span style="color: #008080;">class</span> <span style="color: #000000;">c</span>
private function foo();
<span style="color: #008080;">private</span> <span style="color: #008080;">function</span> <span style="color: #000000;">foo</span><span style="color: #0000FF;">();</span>
public procedure bar();
<span style="color: #008080;">public</span> <span style="color: #008080;">procedure</span> <span style="color: #000000;">bar</span><span style="color: #0000FF;">();</span>
end class
<span style="color: #008080;">end</span> <span style="color: #008080;">class</span>

include builtins\structs.e as structs
<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>
sequence f = structs:get_struct_fields(c)
<span style="color: #004080;">sequence</span> <span style="color: #000000;">f</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>
for i=1 to length(f) do
<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;">f</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
{string name, integer tid, integer flags} = f[i]
<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;">f</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
if and_bits(flags,SF_RTN) then
<span style="color: #008080;">if</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>
if tid!=ST_INTEGER then ?9/0 end if -- (sanity check)
<span style="color: #008080;">if</span> <span style="color: #000000;">tid</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">ST_INTEGER</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- (sanity check)</span>
printf(1,"%s:%s\n",{name,structs:get_field_flags(c,name,true)})
<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;">"%s:%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">name</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>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
{{out}}
<pre>
<pre>
Line 843: Line 997:


=={{header|PHP}}==
=={{header|PHP}}==
<lang php><?
<syntaxhighlight lang="php"><?
class Foo {
class Foo {
function bar(int $x) {
function bar(int $x) {
Line 855: Line 1,009:
echo $method_info;
echo $method_info;
}
}
?></lang>
?></syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 867: Line 1,021:
}
}
</pre>
</pre>


=={{header|PicoLisp}}==
The function <code>methods</code> can be used to print all methods of an object (only in debug mode):

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 methods using the <code>method</code> function.

<syntaxhighlight lang="text">
: (setq R (new '(+Rectangle) 0 0 30 20))
-> $177356065126400

: (methods R)
-> ((draw> . +Rectangle) (perimeter> . +Rectangle) (area> . +Rectangle) (T . +Rectangle) (move> . +Shape))
</syntaxhighlight>





=={{header|Python}}==
=={{header|Python}}==
In Python, methods are properties that are functions, so methods are retrieved by [[Reflection/List properties|getting properties]] and filtering, using (e.g.) <code>[https://docs.python.org/3.5/library/functions.html#dir dir()]</code> and a list comprehension. Python's <code>[https://docs.python.org/3.5/library/inspect.html#module-inspect inspect]</code> module offers a simple way to get a list of an object's methods, though it won't include wrapped, C-native methods (type 'method-wrapper', type 'wrapper_descriptor', or class 'wrapper_descriptor', depending on version). Dynamic methods can be listed by overriding <code>[https://docs.python.org/3/reference/datamodel.html#object.__dir__ __dir__]</code> in the class.
In Python, methods are properties that are functions, so methods are retrieved by [[Reflection/List properties|getting properties]] and filtering, using (e.g.) <code>[https://docs.python.org/3.5/library/functions.html#dir dir()]</code> and a list comprehension. Python's <code>[https://docs.python.org/3.5/library/inspect.html#module-inspect inspect]</code> module offers a simple way to get a list of an object's methods, though it won't include wrapped, C-native methods (type 'method-wrapper', type 'wrapper_descriptor', or class 'wrapper_descriptor', depending on version). Dynamic methods can be listed by overriding <code>[https://docs.python.org/3/reference/datamodel.html#object.__dir__ __dir__]</code> in the class.


<lang python>import inspect
<syntaxhighlight lang="python">import inspect


# Sample classes for inspection
# Sample classes for inspection
Line 963: Line 1,156:
# names using inspect
# names using inspect
map(lambda t: t[0], inspect.getmembers(sub, predicate=inspect.ismethod))
map(lambda t: t[0], inspect.getmembers(sub, predicate=inspect.ismethod))
#['__dir__', '__getattr__', '__init__', '__str__', 'cls', 'doSub', 'doSup', 'otherMethod', 'strs', 'subCls', 'supCls']</lang>
#['__dir__', '__getattr__', '__init__', '__str__', 'cls', 'doSub', 'doSup', 'otherMethod', 'strs', 'subCls', 'supCls']</syntaxhighlight>


=={{header|Raku}}==
=={{header|Raku}}==
Line 971: Line 1,164:
Each is represented as a <tt>Method</tt> object that contains a bunch of info:
Each is represented as a <tt>Method</tt> object that contains a bunch of info:


<lang perl6>class Foo {
<syntaxhighlight lang="raku" line>class Foo {
method foo ($x) { }
method foo ($x) { }
method bar ($x, $y) { }
method bar ($x, $y) { }
Line 981: Line 1,174:
for $object.^methods {
for $object.^methods {
say join ", ", .name, .arity, .count, .signature.gist
say join ", ", .name, .arity, .count, .signature.gist
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 991: Line 1,184:


=={{header|Ring}}==
=={{header|Ring}}==
<lang ring>
<syntaxhighlight lang="ring">
# Project : Reflection/List methods
# Project : Reflection/List methods


Line 1,009: Line 1,202:
func f4
func f4
see "hello from f4" + nl
see "hello from f4" + nl
</syntaxhighlight>
</lang>
Output:
Output:
<pre>
<pre>
Line 1,028: Line 1,221:
Dynamic methods can be listed by overriding these methods. Ancestor methods can be filtered out by subtracting a list of methods from the ancestor.
Dynamic methods can be listed by overriding these methods. Ancestor methods can be filtered out by subtracting a list of methods from the ancestor.


<lang ruby># Sample classes for reflection
<syntaxhighlight lang="ruby"># Sample classes for reflection
class Super
class Super
CLASSNAME = 'super'
CLASSNAME = 'super'
Line 1,159: Line 1,352:
#=> [:superOwn, :subOwn, :incr]
#=> [:superOwn, :subOwn, :incr]
p sub.singleton_methods
p sub.singleton_methods
#=> [:superOwn, :subOwn]</lang>
#=> [:superOwn, :subOwn]</syntaxhighlight>


=={{header|Scala}}==
=={{header|Scala}}==
===Java Interoperability===
===Java Interoperability===
{{Out}}Best seen running in your browser by [https://scastie.scala-lang.org/5mLHFfBeQCuGpc9Q7PXxgw Scastie (remote JVM)].
{{Out}}Best seen running in your browser by [https://scastie.scala-lang.org/5mLHFfBeQCuGpc9Q7PXxgw Scastie (remote JVM)].
<lang Scala>object ListMethods extends App {
<syntaxhighlight lang="scala">object ListMethods extends App {


private val obj = new {
private val obj = new {
Line 1,179: Line 1,372:
clazz.getDeclaredMethods.foreach(m => println(s"${m}}"))
clazz.getDeclaredMethods.foreach(m => println(s"${m}}"))


}</lang>
}</syntaxhighlight>


=={{header|Sidef}}==
=={{header|Sidef}}==
The super-method ''Object.methods()'' returns an Hash with method names as keys and ''LazyMethod'' objects as values. Each ''LazyMethod'' can be called with zero or more arguments, internally invoking the method on the object on which ''.methods'' was called.
The super-method ''Object.methods()'' returns an Hash with method names as keys and ''LazyMethod'' objects as values. Each ''LazyMethod'' can be called with zero or more arguments, internally invoking the method on the object on which ''.methods'' was called.
<lang ruby>class Example {
<syntaxhighlight lang="ruby">class Example {
method foo { }
method foo { }
method bar(arg) { say "bar(#{arg})" }
method bar(arg) { say "bar(#{arg})" }
Line 1,192: Line 1,385:


var meth = obj.methods.item(:bar) # `LazyMethod` representation for `obj.bar()`
var meth = obj.methods.item(:bar) # `LazyMethod` representation for `obj.bar()`
meth(123) # calls obj.bar()</lang>
meth(123) # calls obj.bar()</syntaxhighlight>


=={{header|Tcl}}==
=={{header|Tcl}}==
In TclOO, the <tt>info</tt> command can inspect the complete state of an object or a class, including private and methods:
In TclOO, the <tt>info</tt> command can inspect the complete state of an object or a class, including private and methods:


<lang Tcl>% info object methods ::oo::class -all -private
<syntaxhighlight lang="tcl">% info object methods ::oo::class -all -private
<cloned> create createWithNamespace destroy eval new unknown variable varname</lang>
<cloned> create createWithNamespace destroy eval new unknown variable varname</syntaxhighlight>


For <i>many</i> more examples, see https://wiki.tcl.tk/40640 and the linked manuals for <tt>info class</tt> and <tt>info object</tt>. Plugins for <b>tkcon</b> and <b>twDebugInspector</b> (also found on the wiki) use this to create interactive object inspectors similar to [[Smalltalk]]'s.
For <i>many</i> more examples, see https://wiki.tcl.tk/40640 and the linked manuals for <tt>info class</tt> and <tt>info object</tt>. Plugins for <b>tkcon</b> and <b>twDebugInspector</b> (also found on the wiki) use this to create interactive object inspectors similar to [[Smalltalk]]'s.

=={{header|Wren}}==
Wren doesn't currently have reflection as such but it's possible to identify a class's methods 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 method 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 instance methods available for object 'c':")
for (method in c.type.attributes.self["instance_methods"]) System.print(method.key)</syntaxhighlight>

{{out}}
<pre>
List of instance methods available for object 'c':
n
m
o
</pre>


=={{header|zkl}}==
=={{header|zkl}}==
Every object has a "methods" method, which returns a list of method names [for that object]. If you want to get a method from a string, you can use reflection.
Every object has a "methods" method, which returns a list of method names [for that object]. If you want to get a method from a string, you can use reflection.
<lang zkl>methods:=List.methods;
<syntaxhighlight lang="zkl">methods:=List.methods;
methods.println();
methods.println();
List.method(methods[0]).println(); // == .Method(name) == .BaseClass(name) </lang>
List.method(methods[0]).println(); // == .Method(name) == .BaseClass(name) </syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>

Latest revision as of 14:30, 24 April 2024

Task
Reflection/List methods
You are encouraged to solve this task according to the task description, using any language you may know.
Task

The goal is to get the methods of an object, as names, values or both.

Some languages offer dynamic methods, which in general can only be inspected if a class' public API includes a way of listing them.

C#

using System;
using System.Reflection;

public class Rosetta
{
    public static void Main()
    {
        //Let's get all methods, not just public ones.
        BindingFlags flags = BindingFlags.Instance | BindingFlags.Static
            | BindingFlags.Public | BindingFlags.NonPublic
            | BindingFlags.DeclaredOnly;

        foreach (var method in typeof(TestForMethodReflection).GetMethods(flags))
            Console.WriteLine(method);
    }
    
    class TestForMethodReflection
    {
        public void MyPublicMethod() {}
        private void MyPrivateMethod() {}
        
        public static void MyPublicStaticMethod() {}
        private static void MyPrivateStaticMethod() {}
    }
    
}
Output:
Void MyPublicMethod()
Void MyPrivateMethod()
Void MyPublicStaticMethod()
Void MyPrivateStaticMethod()

//If we do not use BindingFlags.DeclaredOnly, we also get:
System.String ToString()
Boolean Equals(System.Object)
Int32 GetHashCode()
System.Type GetType()
Void Finalize()
System.Object MemberwiseClone()

Clojure

; Including listing private methods in the clojure.set namespace:
=> (keys (ns-interns 'clojure.set))
(union map-invert join select intersection superset? index bubble-max-key subset? rename rename-keys project difference)

; Only public: 
=> (keys (ns-publics 'clojure.set))
(union map-invert join select intersection superset? index subset? rename rename-keys project difference)

D

D allows you to perform compile-time reflection for code generation, such as printing a list of the functions in a struct or class.

struct S {
    bool b;

    void foo() {}
    private void bar() {}
}

class C {
    bool b;

    void foo() {}
    private void bar() {}
}

void printMethods(T)() if (is(T == class) || is(T == struct)) {
    import std.stdio;
    import std.traits;

    writeln("Methods 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() {
    printMethods!S;
    printMethods!C;
}
Output:
Methods of S:
    foo
    bar
Methods of C:
    foo
    bar
    toString
    toHash
    opCmp
    opEquals
    factory

Ecstasy

For any object, the type of that object provides access to its methods and functions:

module test {
    void run() {
        @Inject Console console;

        String[] names = &this.actualType.multimethods.keys.toArray();
        console.print($"Method/function names on {this}: {names}");

        Method[] methods = &this.actualType.methods;
        console.print($"The methods of {this}: {methods}");

        Function[] functions = &this.actualType.functions;
        console.print($"The functions of {this}: {functions}");
    }
}
Output:
x$ xec test
Method/function names on test: [toString, makeImmutable, to, estimateStringLength, appendTo, exTo, toEx, exToEx, isModuleImport, classForName, typeForName, run, hashCode, maxOf, notGreaterThan, compare, equals, minOf, notLessThan]
The methods of test: [String toString(), immutable Object makeImmutable(), Range<Orderable> to(Orderable that), Int estimateStringLength(), Appender<Char> appendTo(Appender<Char> buf), Range<Orderable> exTo(Orderable that), Range<Orderable> toEx(Orderable that), Range<Orderable> exToEx(Orderable that), conditional Module isModuleImport(), conditional Class classForName(String name), conditional Type typeForName(String name), void run()]
The functions of test: [Int hashCode(Type<Package> CompileType, CompileType value), CompileType maxOf(Type<Orderable> CompileType, CompileType value1, CompileType value2), CompileType notGreaterThan(Type<Orderable> CompileType, CompileType value1, CompileType value2), Ordered compare(Type<Const> CompileType, CompileType value1, CompileType value2), Boolean equals(Type<Package> CompileType, CompileType value1, CompileType value2), CompileType minOf(Type<Orderable> CompileType, CompileType value1, CompileType value2), CompileType notLessThan(Type<Orderable> CompileType, CompileType value1, CompileType value2)]

Elena

ELENA 6.x :

import system'routines;
import system'dynamic;
import extensions;
 
class MyClass
{
    myMethod1() {}
 
    myMethod2(x) {}
}
 
public program()
{
    var o := new MyClass();
 
    o.__getClass().__getMessages().forEach::(p)
    {
        console.printLine("o.",p)
    }
}
Output:
o.equal[2]
o.notequal[2]
o.toPrintable[1]
o.myMethod1[1]
o.myMethod2[2]

Factor

In Factor, methods are contained in generic words rather than objects, while methods specialize on a class. Therefore, the programmer must decide whether they want the list of methods in a generic word, or the list of methods that specialize on a class. Luckily, the methods word can do either depending on what type you give it (a word or a class). The returned sequence contains first-class word values suitable for executing.

USING: io math prettyprint see ;

"The list of methods contained in the generic word + :" print
\ + methods . nl

"The list of methods specializing on the fixnum class:" print
fixnum methods .
Output:
The list of methods contained in the generic word + :
{ M\ bignum + M\ complex + M\ fixnum + M\ float + M\ ratio + }

The list of methods specializing on the fixnum class:
{
    M\ fixnum '
    M\ fixnum (bit-count)
    M\ fixnum (eql?)
    M\ fixnum (log2)
    M\ fixnum (positive>dec)
    M\ fixnum (random-integer)
    M\ fixnum *
    M\ fixnum +
    M\ fixnum -
    M\ fixnum /f
    M\ fixnum /i
    M\ fixnum /mod
    M\ fixnum <
    M\ fixnum <=
    M\ fixnum >
    M\ fixnum >=
    M\ fixnum >bignum
    M\ fixnum >fixnum
    M\ fixnum >float
    M\ fixnum >integer
    M\ fixnum ^n
    M\ fixnum bit?
    M\ fixnum bitand
    M\ fixnum bitnot
    M\ fixnum bitor
    M\ fixnum bitxor
    M\ fixnum eql?
    M\ fixnum equal?
    M\ fixnum hashcode*
    M\ fixnum integer>fixnum
    M\ fixnum integer>fixnum-strict
    M\ fixnum max
    M\ fixnum min
    M\ fixnum mod
    M\ fixnum number=
    M\ fixnum real<=>
    M\ fixnum shift
    M\ fixnum u<
    M\ fixnum u<=
    M\ fixnum u>
    M\ fixnum u>=
}

Frink

Frink allows you to list the methods of a Frink-based or Java-based object with the methods[obj] function.

a = new array
methods[a]
Output:
[
pushAll[arg1], 
insert[arg1, arg2], 
indexOf[arg1], 
indexOf[arg1, arg2], 
removeAll[arg1], 
shuffle[], 
dimensions[], 
push[arg1], 
pop[], 
contains[arg1], 
subsets[], 
subsets[arg1, arg2], 
transpose[], 
isEmpty[], 
lexicographicPermute[], 
lexicographicPermute[arg1], 
popFirst[], 
clear[], 
peek[], 
shallowCopy[], 
pushFirst[arg1], 
removeValue[arg1], 
timSort[], 
timSort[arg1], 
timSort[arg1, arg2], 
permute[], 
removeLen[arg1, arg2], 
lastIndexOf[arg1], 
lastIndexOf[arg1, arg2], 
combinations[arg1], 
removeRandom[], 
remove[arg1], 
remove[arg1, arg2]]

Or, for a Java object:

f = newJava["java.io.File", "."]
methods[f]
Output:
[
boolean equals[java.lang.Object arg1], 
long length[], 
java.lang.String toString[], 
int hashCode[], 
int compareTo[java.lang.Object arg1], 
int compareTo[java.io.File arg1], 
java.lang.String getName[], 
java.lang.String[] list[java.io.FilenameFilter arg1], 
java.lang.String[] list[], 
java.lang.String getParent[], 
boolean isAbsolute[], 
boolean delete[], 
boolean setReadOnly[], 
boolean canRead[], 
java.lang.String getPath[], 
java.net.URI toURI[], 
java.net.URL toURL[], 
java.io.File getParentFile[], 
java.lang.String getAbsolutePath[], 
java.io.File getAbsoluteFile[], 
java.lang.String getCanonicalPath[], 
java.io.File getCanonicalFile[], 
boolean isDirectory[], 
boolean canWrite[], 
boolean exists[], 
boolean isFile[], 
boolean isHidden[], 
long lastModified[], 
boolean createNewFile[], 
void deleteOnExit[], 
java.io.File[] listFiles[java.io.FileFilter arg1], 
java.io.File[] listFiles[], 
java.io.File[] listFiles[java.io.FilenameFilter arg1], 
boolean mkdir[], 
boolean mkdirs[], 
boolean renameTo[java.io.File arg1], 
boolean setLastModified[long arg1], 
boolean setWritable[boolean arg1], 
boolean setWritable[boolean arg1, boolean arg2], 
boolean setReadable[boolean arg1], 
boolean setReadable[boolean arg1, boolean arg2], 
boolean setExecutable[boolean arg1, boolean arg2], 
boolean setExecutable[boolean arg1], 
boolean canExecute[], 
java.io.File[] listRoots[], 
long getTotalSpace[], 
long getFreeSpace[], 
long getUsableSpace[], 
java.io.File createTempFile[java.lang.String arg1, java.lang.String arg2, java.io.File arg3], 
java.io.File createTempFile[java.lang.String arg1, java.lang.String arg2], 
java.nio.file.Path toPath[], 
void wait[long arg1], 
void wait[long arg1, int arg2], 
void wait[], 
java.lang.Class getClass[], 
void notify[], 
void notifyAll[]]

Go

Shows the name, method expression and method value of each exported method.
privateMethod is not exported because the first character is lowercase.

package main

import (
	"fmt"
	"image"
	"reflect"
)

type t int // A type definition

// Some methods on the type
func (r t) Twice() t       { return r * 2 }
func (r t) Half() t        { return r / 2 }
func (r t) Less(r2 t) bool { return r < r2 }
func (r t) privateMethod() {}

func main() {
	report(t(0))
	report(image.Point{})
}

func report(x interface{}) {
	v := reflect.ValueOf(x)
	t := reflect.TypeOf(x) // or v.Type()
	n := t.NumMethod()
	fmt.Printf("Type %v has %d exported methods:\n", t, n)
	const format = "%-6s %-46s %s\n"
	fmt.Printf(format, "Name", "Method expression", "Method value")
	for i := 0; i < n; i++ {
		fmt.Printf(format,
			t.Method(i).Name,
			t.Method(i).Func.Type(),
			v.Method(i).Type(),
		)
	}
	fmt.Println()
}
Output:
Type main.t has 3 exported methods:
Name   Method expression                              Method value
Half   func(main.t) main.t                            func() main.t
Less   func(main.t, main.t) bool                      func(main.t) bool
Twice  func(main.t) main.t                            func() main.t

Type image.Point has 8 exported methods:
Name   Method expression                              Method value
Add    func(image.Point, image.Point) image.Point     func(image.Point) image.Point
Div    func(image.Point, int) image.Point             func(int) image.Point
Eq     func(image.Point, image.Point) bool            func(image.Point) bool
In     func(image.Point, image.Rectangle) bool        func(image.Rectangle) bool
Mod    func(image.Point, image.Rectangle) image.Point func(image.Rectangle) image.Point
Mul    func(image.Point, int) image.Point             func(int) image.Point
String func(image.Point) string                       func() string
Sub    func(image.Point, image.Point) image.Point     func(image.Point) image.Point

Insitux

Insitux does not have classes and therefore technically does not have methods. However, it is possible to list all the functions in global lexical space:

; lists all built-in and user-defined functions, including those within variables
(-> (symbols)
    (map eval)
    (filter (comp type-of (= "func"))))

; lists only user-defined functions, including those within variables
(-> (symbols)
    (map eval)
    (filter (comp type-of (= "func")))
    (remove about))

J

   NB. define a stack class
   coclass 'Stack'
   create =: 3 : 'items =: i. 0'
   push =: 3 : '# items =: items , < y'
   top =: 3 : '> {: items'
   pop =: 3 : ([;._2' a =. top 0; items =: }: items; a;')
   destroy =: codestroy
   cocurrent 'base'

   names_Stack_''      NB. all names
create  destroy pop     push    top     

   'p' names_Stack_ 3  NB. verbs that start with p
pop  push 


   NB. make an object.  The dyadic definition of cownew invokes the create verb
   S =: conew~ 'Stack'

   names__S''          NB. object specific names
COCREATOR items     
   

   pop__S              NB. introspection: get the verbs definition
3 : 0
 a =. top 0       
 items =: }: items
 a                
)
   

   NB. get the search path of object S
   copath S
┌─────┬─┐
Stackz
└─────┴─┘
   

   names__S 0         NB. get the object specific data
COCREATOR items

Java

import java.lang.reflect.Method;

public class ListMethods {
    public int examplePublicInstanceMethod(char c, double d) {
        return 42;
    }

    private boolean examplePrivateInstanceMethod(String s) {
        return true;
    }
    
    public static void main(String[] args) {
        Class clazz = ListMethods.class;

        System.out.println("All public methods (including inherited):");
        for (Method m : clazz.getMethods()) {
            System.out.println(m);
        }
        System.out.println();
        System.out.println("All declared methods (excluding inherited):");
        for (Method m : clazz.getDeclaredMethods()) {
            System.out.println(m);
        }
    }
}
Output:
public static void ListMethods.main(java.lang.String[])
public int ListMethods.examplePublicInstanceMethod(char,double)
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()

All declared methods (excluding inherited):
public static void ListMethods.main(java.lang.String[])
public int ListMethods.examplePublicInstanceMethod(char,double)
private boolean ListMethods.examplePrivateInstanceMethod(java.lang.String)

JavaScript

In JavaScript, methods are properties that are functions, so methods are retrieved by getting properties and filtering. 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.

// Sample classes for reflection
function Super(name) {
    this.name = name;
    this.superOwn = function() { return 'super owned'; };
}
Super.prototype = {
    constructor: Super
    className: 'super',
    toString: function() { return "Super(" + this.name + ")"; },
    doSup: function() { return 'did super stuff'; }
}

function Sub() {
    Object.getPrototypeOf(this).constructor.apply(this, arguments);
    this.rest = [].slice.call(arguments, 1);
    this.subOwn = function() { return 'sub owned'; };
}
Sub.prototype = Object.assign(
    new Super('prototype'),
    {
        constructor: Sub
        className: 'sub',
        toString: function() { return "Sub(" + this.name + ")"; },
        doSub: function() { return 'did sub stuff'; }
    });

Object.defineProperty(Sub.prototype, 'shush', {
    value: function() { return ' non-enumerable'; },
    enumerable: false // the default
});

var sup = new Super('sup'),
    sub = new Sub('sub', 0, 'I', 'two');

Object.defineProperty(sub, 'quiet', {
    value: function() { return 'sub owned non-enumerable'; },
    enumerable: false
});

// get enumerable methods on an object and its ancestors
function get_method_names(obj) {
    var methods = [];
    for (var p in obj) {
        if (typeof obj[p] == 'function') {
            methods.push(p);
        }
    }
    return methods;
}

get_method_names(sub);
//["subOwn", "superOwn", "toString", "doSub", "doSup"]

// get enumerable properties on an object and its ancestors
function get_property_names(obj) {
    var properties = [];
    for (var p in obj) {
        properties.push(p);
    }
    return properties;
}

// alternate way to get enumerable method names on an object and its ancestors
function get_method_names(obj) {
    return get_property_names(obj)
        .filter(function(p) {return typeof obj[p] == 'function';});
}

get_method_names(sub);
//["subOwn", "superOwn", "toString", "doSub", "doSup"]

// get enumerable & non-enumerable method names set directly on an object
Object.getOwnPropertyNames(sub)
    .filter(function(p) {return typeof sub[p] == 'function';})
//["subOwn", "shhh"]

// get enumerable method names set directly on an object
Object.keys(sub)
    .filter(function(p) {return typeof sub[p] == 'function';})
//["subOwn"]

// get enumerable method names & values set directly on an object
Object.entries(sub)
    .filter(function(p) {return typeof p[1] == 'function';})
//[["subOwn", function () {...}]]

Julia

Works with: Julia version 0.6
methods(methods)
methods(println)
Output:
# 3 methods for generic function "methods":
methods(f::Core.Builtin) in Base at reflection.jl:588
methods(f::ANY) in Base at reflection.jl:601
methods(f::ANY, t::ANY) in Base at reflection.jl:580

# 3 methods for generic function "println":
println(io::IO) in Base at coreio.jl:6
println(io::IO, xs...) in Base at strings/io.jl:54
println(xs...) in Base at coreio.jl:5

Kotlin

Note that kotlin-reflect.jar needs to be included in the classpath for this program.

// Version 1.2.31

import kotlin.reflect.full.functions

open class MySuperClass {
    fun mySuperClassMethod(){}
}

open class MyClass : MySuperClass() {
    fun myPublicMethod(){}

    internal fun myInternalMethod(){}

    protected fun myProtectedMethod(){}

    private fun myPrivateMethod(){}
}

fun main(args: Array<String>) {
    val c = MyClass::class
    println("List of methods declared in ${c.simpleName} and its superclasses:\n")
    val fs = c.functions
    for (f in fs) println("${f.name}, ${f.visibility}")
}
Output:
List of methods declared in MyClass and its superclasses:

myInternalMethod, INTERNAL
myPrivateMethod, PRIVATE
myProtectedMethod, PROTECTED
myPublicMethod, PUBLIC
equals, PUBLIC
hashCode, PUBLIC
mySuperClassMethod, PUBLIC
toString, PUBLIC

Lingo

-- parent script "MyClass"

on foo (me)
  put "foo"
end

on bar (me)
  put "bar"
end
obj = script("MyClass").new()
put obj.handlers()
-- [#foo, #bar]

-- The returned list contains the object's methods ("handlers") as "symbols".
-- Those can be used like this to call the corresponding method:
call(#foo, obj)
-- "foo"

call(#bar, obj)
-- "bar"

Lua

function helloWorld()
    print "Hello World"
end

-- Will list all functions in the given table, but does not recurse into nexted tables
function printFunctions(t)
    local s={}
    local n=0
    for k in pairs(t) do
        n=n+1 s[n]=k
    end
    table.sort(s)
    for k,v in ipairs(s) do
        f = t[v]
        if type(f) == "function" then
            print(v)
        end
    end
end

printFunctions(_G)
Output:
assert
collectgarbage
dofile
error
gcinfo
getfenv
getmetatable
helloWorld
ipairs
load
loadfile
loadstring
module
newproxy
next
pairs
pcall
print
printFunctions
rawequal
rawget
rawset
require
select
setfenv
setmetatable
tonumber
tostring
type
unpack
xpcall

Nanoquery

// create a class with methods that will be listed
class Methods
	def static method1()
		return "this is a static method. it will not be printed"
	end
	def method2()
		return "this is not a static method"
	end

	def operator=(other)
		// operator methods are listed by both their defined name and
		// by their internal name, which in this case is isEqual
		return true
	end
end

// lists all nanoquery and java native methods
for method in dir(new(Methods))
	println method
end
Output:
add
toString
exp
getField
copy
divide
setField
multiply
lessThan
greaterThan
getInnerClass
getInnerStack
getInterpreter
serialize
deserialize
deserialize
subtract
isSerializable
isEqual
mod
wait
wait
wait
equals
hashCode
getClass
notify
notifyAll
Methods
method2
method2
operator=

Nim

Nim separates data and functions, but with method call syntax, any function that has that object as its first parameter can be used like a method:

type Foo = object
proc bar(f:Foo) = echo "bar"
var f:Foo
f.bar()

this also means object 'methods' can be defined across multiple source files

It's possible to inspect a module's entire AST at compile time with a macro, here we are interested in

  • any method-like definitions (funcs,procs,iterators,methods,macros,templates,etc)

that are

  • exported (publicly useable)

and

  • have our type, or a related type (var Foo, ptr Foo, ref Foo) as first parameter
import macros, fusion/matching
{.experimental: "caseStmtMacros".}
macro listMethods(modulepath:static string, typename): untyped =
  let module = parseStmt(staticRead(modulepath))
  var procs: seq[string]
  for stmt in module:
    case stmt
      of (kind: in {nnkFuncDef,nnkProcDef..nnkIteratorDef}):#any kind of methody thing
        case stmt
        of [
          PostFix[_, @name],#only exported procs
          _,
          _,
          FormalParams[
            _, #return type
            IdentDefs[ #first parameter
          _, #paramname
          (typename |        #Foo
          VarTy[typename] |  #var Foo
          PtrTy[typename] |  #ptr Foo
          RefTy[typename]),  #ref Foo
          _],
            .._], #other params
          .._]: procs.add($name)
  result = newLit(procs)
 
 
type Bar = object
proc a*(b: Bar) = discard
func b*(b: Bar, c: int): string = discard
template c*(b: var Bar, c: float) = discard
iterator d*(b: ptr Bar):int = discard
method e*(b:ref Bar) {.base.} = discard
proc second_param*(a: int, b: Bar) = discard #will not match
proc unexported(a: Bar) = discard #will not match
 
 
template thisfile:string =
  instantiationInfo().filename
echo thisfile.listMethods(Bar)
 
#works for any module:
#const lib = "/path/to/nim/lib/pure/collections/tables.nim"
echo listMethods(lib,Table[A,B])
Output:
@["a", "b", "c", "d", "e"]
@["[]=", "[]", "[]", "hasKey", "contains", "hasKeyOrPut", "getOrDefault", "getOrDefault", "mgetOrPut", "len", "add", "del", "pop", "take", "clear", "$", "withValue", "withValue", "pairs", "mpairs", "keys", "values", "mvalues", "allValues"]

Objective-C

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

@interface Foo : NSObject
@end
@implementation Foo
- (int)bar:(double)x {
  return 42;
}
@end

int main() {
  unsigned int methodCount;
  Method *methods = class_copyMethodList([Foo class], &methodCount);
  for (unsigned int i = 0; i < methodCount; i++) {
    Method m = methods[i];
    SEL selector = method_getName(m);
    const char *typeEncoding = method_getTypeEncoding(m);
    NSLog(@"%@\t%s", NSStringFromSelector(selector), typeEncoding);
  }
  free(methods);
  return 0;
}
Output:
bar:	i24@0:8d16

Perl

Given this simple class, display results of introspection of the symbol table hash. Note that the overloaded comparison operator also shows up in the list of methods.

package Nums;

use overload ('<=>' => \&compare);
sub new     { my $self = shift; bless [@_] }
sub flip    { my @a = @_; 1/$a }
sub double  { my @a = @_; 2*$a }
sub compare { my ($a, $b) = @_; abs($a) <=> abs($b) }

my $a = Nums->new(42);
print "$_\n" for %{ref ($a)."::" });
Output:
double
(<=>
new
BEGIN
flip
compare
((

Another alternative is the module Class::MOP, which implements a meta-object protocol for the Perl. It alters nothing about Perl's object system; it is just a tool for manipulation and introspection. Note that this output includes methods inherited methods (DOES, VERSION, can, isa)

use Class::MOP;
my $meta = Class::MOP::Class->initialize( ref $a );
say join "\n", $meta->get_all_method_names()
Output:
compare
new
(<=>
VERSION
double
isa
flip
can
DOES

Phix

emulated

Even before the introduction of classes (see below), but this sort of thing was fairly easy to emulate.

enum METHODS, PROPERTIES

sequence all_methods = {}

function method_visitor(object key, object /*data*/, /*user_data*/)
    all_methods = append(all_methods,key)
    return 1
end function

function get_all_methods(object o)
    all_methods = {}
    traverse_dict(method_visitor,0,o[METHODS])
    return all_methods
end function

function exists()
    return "exists"
end function

--class X: Xmethods emulates a vtable
constant Xmethods = new_dict({{"exists",exists}})

--class X: destructor
procedure destructor(object o)
    destroy_dict(o[PROPERTIES])
end procedure

--class X: create new instances
function newX(object x,y)
    integer Xproperties = new_dict({{"x",x},{"y",y}})
    object res = delete_routine({Xmethods,Xproperties},destructor)
    return res
end function

object x = newX(2,"string")

?get_all_methods(x)
Output:
{"exists"}

classes

Library: Phix/Class

Needs 0.8.1+ Note that content from and parameters to get_struct_fields() may change between releases.

class c
    private function foo();
    public procedure bar();
end class
 
include builtins\structs.e as structs
sequence f = structs:get_struct_fields(c)
for i=1 to length(f) do
    {string name, integer tid, integer flags} = f[i]
    if and_bits(flags,SF_RTN) then
        if tid!=ST_INTEGER then ?9/0 end if -- (sanity check)
        printf(1,"%s:%s\n",{name,structs:get_field_flags(c,name,true)})
    end if
end for
Output:
foo:SF_PRIVATE+SF_FUNC
bar:SF_PROC

PHP

<?
class Foo {
    function bar(int $x) {
    }
}

$method_names = get_class_methods('Foo');
foreach ($method_names as $name) {
    echo "$name\n";
    $method_info = new ReflectionMethod('Foo', $name);
    echo $method_info;
}
?>
Output:
bar
Method [ <user> public method bar ] {
  @@ /Users/xuanluo/test.php 3 - 4

  - Parameters [1] {
    Parameter #0 [ <required> int $x ]
  }
}


PicoLisp

The function methods can be used to print all methods of an object (only in debug mode):

First we define a rectangle class +Rectangle as subclass of a shape class +Shape:

# 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'

Then we can create an object of the +Rectangle class and check its methods using the method function.

: (setq R (new '(+Rectangle) 0 0 30 20)) 
-> $177356065126400

: (methods R)
-> ((draw> . +Rectangle) (perimeter> . +Rectangle) (area> . +Rectangle) (T . +Rectangle) (move> . +Shape))



Python

In Python, methods are properties that are functions, so methods are retrieved by getting properties and filtering, using (e.g.) dir() and a list comprehension. Python's inspect module offers a simple way to get a list of an object's methods, though it won't include wrapped, C-native methods (type 'method-wrapper', type 'wrapper_descriptor', or class 'wrapper_descriptor', depending on version). Dynamic methods can be listed by overriding __dir__ in the class.

import inspect

# Sample classes for inspection
class Super(object):
  def __init__(self, name):
    self.name = name
  
  def __str__(self):
    return "Super(%s)" % (self.name,)
  
  def doSup(self):
    return 'did super stuff'
  
  @classmethod
  def cls(cls):
    return 'cls method (in sup)'
  
  @classmethod
  def supCls(cls):
    return 'Super method'
  
  @staticmethod
  def supStatic():
    return 'static method'

class Other(object):
  def otherMethod(self):
    return 'other method'

class Sub(Other, Super):
  def __init__(self, name, *args):
    super(Sub, self).__init__(name);
    self.rest = args;
    self.methods = {}
  
  def __dir__(self):
    return list(set( \
        sum([dir(base) for base in type(self).__bases__], []) \
        + type(self).__dict__.keys() \
        + self.__dict__.keys() \
        + self.methods.keys() \
      ))
  
  def __getattr__(self, name):
    if name in self.methods:
      if callable(self.methods[name]) and self.methods[name].__code__.co_argcount > 0:
        if self.methods[name].__code__.co_varnames[0] == 'self':
          return self.methods[name].__get__(self, type(self))
        if self.methods[name].__code__.co_varnames[0] == 'cls':
          return self.methods[name].__get__(type(self), type)
      return self.methods[name]
    raise AttributeError("'%s' object has no attribute '%s'" % (type(self).__name__, name))
  
  def __str__(self):
    return "Sub(%s)" % self.name
  
  def doSub():
    return 'did sub stuff'
  
  @classmethod
  def cls(cls):
    return 'cls method (in Sub)'
  
  @classmethod
  def subCls(cls):
    return 'Sub method'
  
  @staticmethod
  def subStatic():
    return 'Sub method'

sup = Super('sup')
sub = Sub('sub', 0, 'I', 'two')
sub.methods['incr'] = lambda x: x+1
sub.methods['strs'] = lambda self, x: str(self) * x

# names
[method for method in dir(sub) if callable(getattr(sub, method))]
# instance methods
[method for method in dir(sub) if callable(getattr(sub, method)) and hasattr(getattr(sub, method), '__self__') and getattr(sub, method).__self__ == sub]
#['__dir__', '__getattr__', '__init__', '__str__', 'doSub', 'doSup', 'otherMethod', 'strs']
# class methods 
[method for method in dir(sub) if callable(getattr(sub, method)) and hasattr(getattr(sub, method), '__self__') and getattr(sub, method).__self__ == type(sub)]
#['__subclasshook__', 'cls', 'subCls', 'supCls']
# static & free dynamic methods
[method for method in dir(sub) if callable(getattr(sub, method)) and type(getattr(sub, method)) == type(lambda:nil)]
#['incr', 'subStatic', 'supStatic']

# names & values; doesn't include wrapped, C-native methods
inspect.getmembers(sub, predicate=inspect.ismethod)
# names using inspect
map(lambda t: t[0], inspect.getmembers(sub, predicate=inspect.ismethod))
#['__dir__', '__getattr__', '__init__', '__str__', 'cls', 'doSub', 'doSup', 'otherMethod', 'strs', 'subCls', 'supCls']

Raku

(formerly Perl 6)

You can get a list of an object's methods using .^methods, which is part of the Meta Object Protocol.
Each is represented as a Method object that contains a bunch of info:

class Foo {
    method foo ($x)      { }
    method bar ($x, $y)  { }
    method baz ($x, $y?) { }
}

my $object = Foo.new;

for $object.^methods {
    say join ", ", .name, .arity, .count, .signature.gist
}
Output:
foo, 2, 2, (Foo $: $x, *%_)
bar, 3, 3, (Foo $: $x, $y, *%_)
baz, 2, 3, (Foo $: $x, $y?, *%_)

Ring

# Project : Reflection/List methods

o1 = new test
aList = methods(o1)
for x in aList
     cCode = "o1."+x+"()"
     eval(cCode)
next
Class Test
func f1
       see "hello from f1" + nl
func f2
       see "hello from f2" + nl
func f3
       see "hello from f3" + nl
func f4
       see "hello from f4" + nl

Output:

hello from f1
hello from f2
hello from f3
hello from f4

Ruby

Ruby has various properties that will return lists of methods:

Dynamic methods can be listed by overriding these methods. Ancestor methods can be filtered out by subtracting a list of methods from the ancestor.

# Sample classes for reflection
class Super
  CLASSNAME = 'super'
  
  def initialize(name)
    @name = name
    def self.superOwn
      'super owned'
    end
  end
  
  def to_s
    "Super(#{@name})"
  end
  
  def doSup
    'did super stuff'
  end
  
  def self.superClassStuff
    'did super class stuff'
  end
  
  protected
  def protSup
    "Super's protected"
  end
  
  private
  def privSup
    "Super's private"
  end
end

module Other
  def otherStuff
    'did other stuff'
  end
end

class Sub < Super
  CLASSNAME = 'sub'
  attr_reader :dynamic
  
  include Other
  
  def initialize(name, *args)
    super(name)
    @rest = args;
    @dynamic = {}
    def self.subOwn
      'sub owned'
    end
  end
  
  def methods(regular=true)
    super + @dynamic.keys
  end
  
  def method_missing(name, *args, &block)
    return super unless @dynamic.member?(name)
    method = @dynamic[name]
    if method.arity > 0
      if method.parameters[0][1] == :self
        args.unshift(self)
      end
      if method.lambda?
        # procs (hence methods) set missing arguments to `nil`, lambdas don't, so extend args explicitly
        args += args + [nil] * [method.arity - args.length, 0].max
        # procs (hence methods) discard extra arguments, lambdas don't, so discard arguments explicitly (unless lambda is variadic)
        if method.parameters[-1][0] != :rest
          args = args[0,method.arity]
        end
      end
      method.call(*args)
    else
      method.call
    end
  end
  
  def public_methods(all=true)
    super + @dynamic.keys
  end
  
  def respond_to?(symbol, include_all=false)
    @dynamic.member?(symbol) || super
  end
  
  def to_s
    "Sub(#{@name})"
  end
  
  def doSub
    'did sub stuff'
  end
  
  def self.subClassStuff
    'did sub class stuff'
  end
  
  protected
  def protSub
    "Sub's protected"
  end
  
  private
  def privSub
    "Sub's private"
  end
end

sup = Super.new('sup')
sub = Sub.new('sub', 0, 'I', 'two')
sub.dynamic[:incr] = proc {|i| i+1}

p sub.public_methods(false)
#=> [:superOwn, :subOwn, :respond_to?, :method_missing, :to_s, :methods, :public_methods, :dynamic, :doSub, :incr]

p sub.methods - Object.methods
#=> [:superOwn, :subOwn, :method_missing, :dynamic, :doSub, :protSub, :otherStuff, :doSup, :protSup, :incr]

p sub.public_methods - Object.public_methods
#=> [:superOwn, :subOwn, :method_missing, :dynamic, :doSub, :otherStuff, :doSup, :incr]

p sub.methods - sup.methods
#=> [:subOwn, :method_missing, :dynamic, :doSub, :protSub, :otherStuff, :incr]

# singleton/eigenclass methods
p sub.methods(false)
#=> [:superOwn, :subOwn, :incr]
p sub.singleton_methods
#=> [:superOwn, :subOwn]

Scala

Java Interoperability

Output:

Best seen running in your browser by Scastie (remote JVM).

object ListMethods extends App {

  private val obj = new {
    def examplePublicInstanceMethod(c: Char, d: Double) = 42

    private def examplePrivateInstanceMethod(s: String) = true
  }
  private val clazz = obj.getClass

  println("All public methods (including inherited):")
  clazz.getMethods.foreach(m => println(s"${m}"))

  println("\nAll declared fields (excluding inherited):")
  clazz.getDeclaredMethods.foreach(m => println(s"${m}}"))

}

Sidef

The super-method Object.methods() returns an Hash with method names as keys and LazyMethod objects as values. Each LazyMethod can be called with zero or more arguments, internally invoking the method on the object on which .methods was called.

class Example {
    method foo { }
    method bar(arg) { say "bar(#{arg})" }
}

var obj = Example()
say obj.methods.keys.sort          #=> ["bar", "call", "foo", "new"]

var meth = obj.methods.item(:bar)  # `LazyMethod` representation for `obj.bar()`
meth(123)                          # calls obj.bar()

Tcl

In TclOO, the info command can inspect the complete state of an object or a class, including private and methods:

% info object methods ::oo::class -all -private
<cloned> create createWithNamespace destroy eval new unknown variable varname

For many more examples, see https://wiki.tcl.tk/40640 and the linked manuals for info class and info object. Plugins for tkcon and twDebugInspector (also found on the wiki) use this to create interactive object inspectors similar to Smalltalk's.

Wren

Wren doesn't currently have reflection as such but it's possible to identify a class's methods 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 method names appear is undefined.

#! 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 instance methods available for object 'c':")
for (method in c.type.attributes.self["instance_methods"]) System.print(method.key)
Output:
List of instance methods available for object 'c':
n
m
o

zkl

Every object has a "methods" method, which returns a list of method names [for that object]. If you want to get a method from a string, you can use reflection.

methods:=List.methods;
methods.println();
List.method(methods[0]).println();  // == .Method(name) == .BaseClass(name)
Output:
L("create","createLong","copy","toString","toBool","toData","toDictionary","toList","isType","isInstanceOf","holds","append","write","writeln","read","readln","extend","insert","find","findBop",...)
Method(TSList.create)