proc doStreaming(reader: Reader) {.async.} =
var data = await reader.read(8192)
# .... do sth. with data ....
I want the readers to have polymorphism, i.e. different kinds of readers read in different ways, and I know I can normally use methods, but the async paragma doesn't seem to play well with methods.
And AFAIK there's no way to wrap an async proc in a normal method.
Currently I'm using some kind of hand-crafted virtual function table:
type
TReader* = object of RootObj
readImpl: proc(r: Reader): Future[string]
Reader* = ref TReader
proc read*(r: Reader, size: int): Future[string] {.async.} =
return (await r.readImpl(r, size))
type
TAsyncSocketReader* = object of TReader
socket*: AsyncSocket
AsyncSocketReader* = ref TAsyncSocketReader
proc asRead*(r: Reader, size: int): Future[string] {.async.} =
var sr = AsyncSocketReader(r)
# .... do my reading logic ....
proc newAsyncSocketReader*(socket: AsyncSocket): AsyncSocketReader =
new(result)
result.socket = socket
result.readImpl = asRead
This is cumbersome, as if I'm going back to the C ages. Is it possible for Nim to support async methods? Or is there a better way of doing this?
@dom96 Thanks!
But I failed to understand the term object variants, any examples or pointers?
Hi IO4m33
An object variant is a way of defining an object with conditional members (think union in old-school C). You use a case statement on a suitable enum value to alter the object layout. It's not as good as a real method/inheritance if that's what you really want, but it could be a little cleaner than what you have above. (And you can inherit from an object variant type if there's lots of stuff that would be more convenient to have in a class / non-async methods).
THe type definition for what you have above would be something like:
type
ReaderKind = enum
rkBasic,
rkAsyncSocket
Reader = ref ReaderBaseObj
ReaderBaseObj = object
case readkind: ReaderKind
of rkBasic:
readerfunc: proc(): Future[string]
of rkAsyncSocket:
readerfunc_socket: proc(r: Reader, size: int): Future[string]
for the type definition.
@perturbation2 Thank you very much for the explanation!
But indeed I prefer inheritance. With object variants, one would need to modify my code if she wants her own type of Reader behavior.