Need help with delegates and vibed

Mathias Lang via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Mar 16 13:52:45 PDT 2016


On Wednesday, 16 March 2016 at 20:08:40 UTC, Suliman wrote:
> I can't understand how to get works delegates works from this 
> doc http://vibed.org/api/vibe.http.client/requestHTTP
>
> I see example, but when I am looking on Prototypes I really 
> can't figure how to use them.
>
> For example what does this mean:
>  scope void delegate(scope HTTPClientRequest) requester,
>
> it's function that point to method inside class?

No, its a delegate, essentially a fat pointer bundling a function 
and a context together.
It can be a pointer to a class member, e.g. 
`&myHandler.sendHttpRequest`, but it can also
be a literal using the context of the function:

```
void foo ()
{
   string foo;

   scope requester = (scope HTTPClientRequest req) { 
req.header["foo"] = foo; }

   requestHTTP("http://google.com", requester);
}
```

By default, `delegate`s are allocated on the heap (GC-allocated).
`scope` delegate means its allocated on the stack (which also 
means that if you return a `scope delegate`, you'll get random 
behaviour / segfault because your context points to an 
invalidated stack frame).


> Why I can not call it like:
>
> requestHTTP(url,
> 	scope req,
> 	scope res);
>
> I am getting error:
>
> Error: expression expected, not 'scope'
> Error: found 'req' when expecting ','
> Error: expression expected, not ','
> Error: found 'scope' when expecting ','
>
> ---

You have two usage of `scope` here. First a `scope delegate` 
which is used to avoid memory allocation. This `scope delegate` 
takes parameter: the requester takes a request object (what will 
be send to the server), and the receiver takes a response object 
(what has been read from the connection as the response). Those 
object are marked as `scope`, which means the memory will be 
destroyed when you exit the `delegate`s. That's also to reduce 
memory allocation. If you want to save anything (like some 
headers value), you have to [i]dup it.

> Is it's optional parameter?
>
> scope void delegate(scope HTTPClientRequest) requester = 
> cast(void delegate(scope HTTPClientRequest req))null
>
> so I can place instead in just `null`?

Yes. The reason for the various overloads is performance vs 
convenience.
If you provide both requester and receiver, you can process 
request with a minimal amount of memory allocation. However, if 
you take the overload that returns an `HTTPClientResponse`, then 
it will have to allocate it (as well as all the data inside).


More information about the Digitalmars-d-learn mailing list