What is a Rust equivalent to C++'s virtual overwriting to prevent code rewriting? - rust

In C++, I've written this code:
class MessageHandler {
virtual MediaPlayer::Ptr handle_message(...);
virtual RtspServer::Ptr decideRtspServer(...);
virtual RtspClient::Ptr decideRtspClient(...);
virtual Decoder::Ptr decideDecoder(...);
virtual Renderer::Ptr decideRenderer(...);
};
This class handles a message that informs which RtspServer, RtspClient, Decoder, Renderer to use, and returns a MediaPlayer. I want to write MessageHandlers for lots of devices: Android, Windows, Linux, etc, so I can override each decision. For example, I can override decideRenderer to decide an specific renderer that is only available in Linux, but the rest should not be overridden as it's the same in all devices.
I'm looking to do the same in Rust: have default decisions but the ability to "override" one if needed, when implementing a MessageHandler for an specific device.
How can I achieve something similar in Rust? I don't care if it looks like OOP or not, I just want to prevent rewriting the same code.

What speaks against trait objects? Something along the lines of this:
trait MessageHandler {
handle_message(...) -> Box<MediaPlayer> {
Box::new(DefaultMediaPlayer{})
}
decideRtspServer(...) -> Box<RtspServer> {
Box::ne(DefaultRtspServer{})
}
// and others
};
struct LinuxMessageHandler {...}
impl MessageHandler for LinuxMessageHandler {
handle_message(...) -> Box<MediaPlayer> {
Box::new(LinuxSpecificMediaPlayer{})
}
// do not implement any other method: instead, automatically "inherit" them from MessageHandler
}
Then, these "trait objects" are passed around as e.g. Box<dyn MessageHandler>.

Related

How can I make this Rust code more idiomatic

Recently I started to learn Rust and one of my main struggles is converting years of Object Oriented thinking into procedural code.
I'm trying to parse a XML that have tags that are processed by an specific handler that can deal with the data it gets from the children.
Further more I have some field members that are common between them and I would prefer not to have to write the same fields to all the handlers.
I tried my hand on it and my code came out like this:
use roxmltree::Node; // roxmltree = "0.14.0"
fn get_data_from(node: &Node) -> String {
let tag_name = get_node_name(node);
let tag_handler: dyn XMLTagHandler = match tag_name {
"name" => NameHandler::new(),
"phone" => PhoneHandler::new(),
_ => DefaultHandler::new()
}
if tag_handler.is_recursive() {
for child in node.children() {
let child_value = get_data_from(&child);
// do something with child value
}
}
let value: String = tag_handler.value()
value
}
// consider that handlers are on my project and can be adapted to my needs, and that XMLTagHandler is the trait that they share in common.
My main issues with this are:
This feels like a Object oriented approach to it;
is_recursive needs to be reimplemented to each struct because they traits cannot have field members, and I will have to add more fields later, which means more boilerplate for each new field;
I could use one type for a Handler and pass to it a function pointer, but this approach seems dirty. e.g.:=> Handler::new(my_other_params, phone_handler_func)
This feels like a Object oriented approach to it
Actually, I don't think so. This code is in clear violation of the Tell-Don't-Ask principle, which falls out from the central idea of object-oriented programming: the encapsulation of data and related behavior into objects. The objects (NameHandler, PhoneHandler, etc.) don't have enough knowledge about what they are to do things on their own, so get_data_from has to query them for information and decide what to do, rather than simply sending a message and letting the object figure out how to deal with it.
So let's start by moving the knowledge about what to do with each kind of tag into the handler itself:
trait XmlTagHandler {
fn foreach_child<F: FnMut(&Node)>(&self, node: &Node, callback: F);
}
impl XmlTagHandler for NameHandler {
fn foreach_child<F: FnMut(&Node)>(&self, _node: &Node, _callback: F) {
// "name" is not a recursive tag, so do nothing
}
}
impl XmlTagHandler for DefaultHandler {
fn foreach_child<F: FnMut(&Node)>(&self, node: &Node, callback: F) {
// all other tags may be recursive
for child in node.children() {
callback(child);
}
}
}
This way you call foreach_child on every kind of Handler, and let the handler itself decide whether the right action is to recurse or not. After all, that's why they have different types -- right?
To get rid of the dyn part, which is unnecessary, let's write a little generic helper function that uses XmlTagHandler to handle one specific kind of tag, and modify get_data_from so it just dispatches to the correct parameterized version of it. (I'll suppose that XmlTagHandler also has a new function so that you can create one generically.)
fn handle_tag<H: XmlTagHandler>(node: &Node) -> String {
let handler = H::new();
handler.foreach_child(node, |child| {
// do something with child value
});
handler.value()
}
fn get_data_from(node: &Node) -> String {
let tag_name = get_node_name(node);
match tag_name {
"name" => handle_tag::<NameHandler>(node),
"phone" => handle_tag::<PhoneHandler>(node),
_ => handle_tag::<DefaultHandler>(node),
}
}
If you don't like handle_tag::<SomeHandler>(node), also consider making handle_tag a provided method of XmlTagHandler, so you can instead write SomeHandler::handle(node).
Note that I have not really changed any of the data structures. Your presumption of an XmlTagHandler trait and various Handler implementors is a pretty normal way to organize code. However, in this case, it doesn't offer any real improvement over just writing three separate functions:
fn get_data_from(node: &Node) -> String {
let tag_name = get_node_name(node);
match tag_name {
"name" => get_name_from(node),
"phone" => get_phone_from(node),
_ => get_other_from(node),
}
}
In some languages, such as Java, all code has to be part of some class – so you can find yourself writing classes that don't exist for any other reason than to group related things together. In Rust you don't need to do this, so make sure that any added complication such as XmlTagHandler is actually pulling its weight.
is_recursive needs to be reimplemented to each struct because they traits cannot have field members, and I will have to add more fields later, which means more boilerplate for each new field
Without more information about the fields, it's impossible to really understand what problem you're facing here; however, in general, if there is a family of structs that have some data in common, you may want to make a generic struct instead of a trait. See the answers to How to reuse codes for Binary Search Tree, Red-Black Tree, and AVL Tree? for more suggestions.
I could use one type for a Handler and pass to it a function pointer, but this approach seems dirty
Elegance is sometimes a useful thing, but it is subjective. I would recommend closures rather than function pointers, but this suggestion doesn't seem "dirty" to me. Making closures and putting them in data structures is a very normal way to write Rust code. If you can elaborate on what you don't like about it, perhaps someone could point out ways to improve it.

How do I use an IOC container with typescript generics in node?

I am attempting to use container-ioc, but am happy to use any package supplying IoC. I cannot find any examples that use typescript generics. Basically, I want:
interface A<T> {
foo();
}
class A<T> {
foo() {
}
}
interface B<T> {
bar: A<T>;
}
class B<T> {
bar: A<T>;
constructor(param: A<T>) {
this.bar = param;
}
}
where I can set up an IoC container to inject A into B. I am using typescript in a node app. I have syntax that seems to parse at least, but cannot craft the container resolve() as I don't know how to pass the generic parameter. Not to mention, I'm not sure whether this is actually supported.
So, I have a workaround that works for my situation. Firstly, I set a symbol for the generic type with const MyFoo = Symbol("Foo<My>"). Then, I use a factory constructor when registering the type:
container.register([
{ token: MyBar, useFactory: () => new Bar<My>() },
token: MyFoo, useFactory: () => new Foo<My>( container.resolve(MyBar) )}]);
Finally, I do not #inject the parameter on the constructor. This method means that I need to know what generic types I will be using beforehand. In my case, I do: my generic types implement an entity repository and related classes, and my entities are the generic parameters. I'd prefer to not have yet another place to maintain when setting up new entities, so I am leaving this answer unaccepted in case someone has a better solution.

What is the use of a static initialization block in Groovy?

What is the use of the static initialization block in Groovy. Why does Geb use it? If the use of it is the same as in Java, then how can you initialize non-declared fields in a situtation like this?
class ManualsMenuModule extends Module {
static content = {
toggle { $("div.menu a.manuals") }
linksContainer { $("#manuals-menu") }
links { linksContainer.find("a") }
}
void open() {
toggle.click()
waitFor { !linksContainer.hasClass("animating") }
}
}
Some answers to your questions are provided in the section about the content DSL of the Geb manual.
The DSL is implemented using Groovy's methodMissing() mechanism and modification of the delegate of the closure assigned to the static content field. If you are interested in digging deeper then you can always look at the implementation in PageContentTemplateBuilder.
I'm not expert on Geb, I can only explain the groovy meaning of the code.
1st off, it's not the static initialization block like in java. In those lines static content = {...} you are assigning to a static variable a Closure instance which is evaluated and executed LATER (hence, lazy).
The closure represents a (part of) a Geb's Groovy Builder which is called by Geb framework to register/perform some tasks.
There's no Java counterpart to achieve the same, and that's the reason why groovy-based frameworks are so nice to use for testing purposes and they follow the general rule of thumb:
test code should be more abstract then the code under test
UPDATE:
This line:
toggle { $("div.menu a.manuals") }
can be rewritten like
toggle( { $("div.menu a.manuals") } )
or
def a = { $("div.menu a.manuals") }
toggle a
so it's a method invocation and not an assignment. In groovy you can omit the brackets in some cases.

How do I improve this object design in Typescript?

I have created a class in Typescript that implements a simple stream (FRP). Now I want to extend it with client side functionality (streams of events). To illustrate my problem, here is some pseudo-code:
class Stream<T> {
map<U>(f: (value: T) => U): Stream<U> {
// Creates a new Stream instance that maps the values.
}
// Quite a few other functions that return new instances.
}
This class can be used both on the server and on the client. For the client side, I created a class that extends this one:
class ClientStream<T> extends Stream<T> {
watch(events: string, selector: string): Stream<Event> {
// Creates a new ClientStream instance
}
}
Now the ClientStream class knows about map but the Stream class doesn't know about watch. To circumvent this, functions call a factory method.
protected create<U>(.....): Stream<U> {
return new Stream<U>(.....)
}
The ClientStream class overrides this function to return ClientStream instances. However, the compiler complains that ClientStream.map returns a Stream, not a ClientStream. That can be 'solved' using a cast, but besides being ugly it prevents chaining.
Example code that exhibits this problem:
class Stream {
protected create(): Stream {
return new Stream()
}
map() {
return this.create()
}
}
class ClientStream extends Stream {
protected create(): ClientStream {
return new ClientStream()
}
watch() {
return this.create()
}
}
let s = new ClientStream().map().watch()
This does not compile because according to the compiler, the stream returned from map is not a ClientStream: error TS2339: Property 'watch' does not exist on type 'Stream'.
I don't really like this pattern, but I have no other solution that is more elegant. Things I've thought about:
Use composition (decorator). Not really an option given the number of methods I would have to proxy through. And I want to be able to add methods to Stream later without having to worry about ClientStream.
Mix Stream into ClientStream. More or less the same problem, ClientStream has to know the signatures of the functions that are going to be mixed in (or not? Please tell).
Merge these classes into one. This is a last resort, the watch function has no business being on the server.
Do you have a better (more elegant) solution? If you have an idea that gets closer to a more functional style, I'd be happy to hear about it. Thanks!
What you're trying to do is called F-bounded polymorphism.
In TypeScript this is done via the this keyword. Take a look at Typescript's documentation for polymorphic this types. If you follow the documentation, you should be able to implement what you want :-)
Actually, just make sure that you're returning this in your member methods and you should be fine!

Use 'owner' property in Groovy DSL

Let's consider a simple Groovy DSL
execute {
sendNotification owner
sendNotification payee
}
The implementation of execute is
public static void execute(Closure dslCode) {
Closure clonedCode = dslCode.clone()
def dslDelegate = new MyDslDelegate(owner: 'IncCorp', payee: 'TheBoss')
clonedCode.delegate = dslDelegate
clonedCode.call()
}
and custom Delegate is
public static class MyDslDelegate {
def owner
def payee
void sendNotification(to) {
println "Notification sent to $to"
}
}
The expected result of running execute block is
Notification sent to IncCorp
Notification sent to TheBoss
the actual one is
Notification sent to class package.OwnerClassName
Notification sent to TheBoss
The problem is owner is a reserved property in the Groovy Closure itself and no resolveStrategy options help to replace owner value with custom value from delegate due to Groovy getProperty implementation for Closure
public Object getProperty(final String property) {
if ("delegate".equals(property)) {
return getDelegate();
} else if ("owner".equals(property)) {
return getOwner();
...
} else {
switch(resolveStrategy) {
case DELEGATE_FIRST:
...
}
My question is how some one can outcome this limitation and use owner property name in a custom DSL?
This is a bit of a hack, but this should get you what you want, without altering Groovy source:
public static void execute(Closure dslCode) {
Closure clonedCode = dslCode.clone()
def dslDelegate = new MyDslDelegate(owner: 'IncCorp', payee: 'TheBoss')
clonedCode.#owner = dslDelegate.owner
clonedCode.resolveStrategy = Closure.DELEGATE_ONLY
clonedCode.delegate = dslDelegate
clonedCode.call()
}
Ref: Is it possible to change the owner of a closure?
The simple answer is no, you can't. 'owner' is a reserved keyword in Groovy, and therefore by definition cannot be used as an arbitrary symbol. Even if there is a way to hack around this, you're far better off just using a name that doesn't conflict with the implementation of the language- this is especially true in Groovy, which keeps promising to redesign its MOP completely, meaning that any hack you implement may well stop working in future versions.
Perhaps the question would make more sense if you explained why you are willing to offer a bounty and search for a way of hacking around this problem, rather than just changing the name to something different and avoiding the problem entirely. Reserved symbols are a pretty fundamental limitation of a language, and ever attempting to work around them seems very unwise.

Resources