Reflective programming: Difference between revisions

Content deleted Content added
No edit summary
 
(12 intermediate revisions by the same user not shown)
Line 76:
using std::meta::info;
using std::views::filter;
 
class Foo {
private:
// ...
public:
void printHello() const noexcept {
std::println("Hello, world!");
}
};
 
[[nodiscard]]
Line 96 ⟶ 105:
 
template <info Ty, auto Name>
constexpr auto createInvokerImpl = []() -> auto {
using Type = [: Ty :];
static constexpr info M = findMethod(Ty, Name);
static_assert(parameters_of(M).size() == 0 && return_type_of(M) == ^^void);
return [](Type& instance) -> void { instance.[: M :](); };
}();
 
Line 130 ⟶ 139:
using System;
using System.Reflection;
 
class Foo {
// ...
public void PrintHello() {
Console.WriteLine("Hello, world!");
}
}
 
public class InvokeFooExample {
Line 218 ⟶ 234:
<syntaxhighlight lang="java">
import java.lang.reflect.Method;
 
class Foo {
// ...
public void printHello() {
System.out.println("Hello, world!");
}
}
 
public class InvokeFooExample {
Line 223 ⟶ 246:
// Without reflection
Foo foo = new Foo();
foo.helloprintHello();
 
// With reflection
Line 229 ⟶ 252:
Foo foo = Foo.class.getDeclaredConstructor().newInstance();
 
Method m = foo.getClass().getDeclaredMethod("helloprintHello", new Class<?>[0]);
m.invoke(foo);
} catch (ReflectiveOperationException e) {
Line 303 ⟶ 326:
 
// Sending "hello" to a Foo instance without reflection.
Foo * obj = [[Foo alloc] init];
[obj hello];
 
Line 356 ⟶ 379:
 
<syntaxhighlight lang="python">
from typing import Any
# Without reflection
obj = Foo()
obj.hello()
 
class Foo:
# With reflection
# ...
obj = globals()["Foo"]()
def print_hello() -> None:
getattr(obj, "hello")()
print("Hello, world!")
 
if __name__ == "__main__":
# With eval
# Without reflection
eval("Foo().hello()")
obj: Foo = Foo()
obj.print_hello()
 
# With reflection
obj: Foo = globals()["Foo"]()
_: Any = getattr(obj, "helloprint_hello")()
 
# With eval
eval("Foo().helloprint_hello()")
</syntaxhighlight>
 
Line 400 ⟶ 431:
 
===Rust===
[[Rust (programming language)|Rust]] does not have compile-time reflection in the standard library, but it is possible using some third-party libraries such as "[https://docs.rs/bevy_reflect/latest/bevy_reflect/ "{{mono|bevy_reflect}}"]".
 
<syntaxhighlight lang="rust">
use std::any::TypeId;
 
use bevy_reflect::prelude::*;
use bevy_reflect::{
FunctionRegistry,
Reflect, ReflectMut, ReflectRef, TypeRegistry, ReflectFunction, ReflectFunctionRegistry,
FunctionRegistry, GetTypeRegistration,
Reflect,
ReflectFunction,
ReflectFunctionRegistry,
ReflectMut,
ReflectRef,
TypeRegistry
};
use std::any::TypeId;
 
/// A simple struct with a method to reflectively call.
#[derive(Reflect)]
#[reflect(DoFoo)]
struct Foo; {
// ...
}
 
impl Foo {
Line 420 ⟶ 459:
}
 
fn helloprint_hello(&self) {
println!("Hello, from Fooworld!");
}
}
Line 427 ⟶ 466:
#[reflect_trait]
trait DoFoo {
fn helloprint_hello(&self);
}
 
impl DoFoo for Foo {
fn helloprint_hello(&self) {
self.helloprint_hello(); // call the actual method
}
}
Line 439 ⟶ 478:
// Without reflection
let foo: Foo = Foo::new();
foo.print_hello();
 
// With reflection (version 1)
let mut registry: TypeRegistry = TypeRegistry::default();
 
Line 450 ⟶ 490:
let reflect_foo: Box<dyn Reflect> = Box::new(foo);
 
// Version 1: call hello by trait
let trait_registration: &ReflectDoFoo = registry
.get_type_data::<ReflectDoFoo>(TypeId::of::<Foo>())
Line 458 ⟶ 499:
.expect("Failed to get DoFoo trait object");
 
trait_object.helloprint_hello();
 
// Version 2: call hello by function name
// With reflection (version 2)
let func_registry: &FunctionRegistry = registry
.get_type_data::<FunctionRegistry>(TypeId::of::<Foo>())
.expect("FunctionRegistry not found for Foo");
 
if let Some(dyn_func): Option<&dyn ReflectFunction> = func_registry.get("helloprint_hello") {
let result: Option<Box<dyn Reflect>> = dyn_func
.call(&*reflect_foo, Vec::<Box<dyn Reflect>>::new())
Line 474 ⟶ 515:
}
} else {
println!("No function named `hello` found in FunctionRegistry");
}
}