www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Need help with delegates and vibed

reply Suliman <evermind live.ru> writes:
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? 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 ','

---
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`?
Mar 16 2016
parent reply Mathias Lang <pro.mathias.lang gmail.com> writes:
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).
Mar 16 2016
parent reply Suliman <evermind live.ru> writes:
Thanks! I am understand a little bit better, but not all.

```
shared static this()
{
	auto settings = new HTTPServerSettings;
	settings.port = 8080;

	listenHTTP(settings, &handleRequest);
}

void handleRequest(HTTPServerRequest req,
                    HTTPServerResponse res)
{
	if (req.path == "/")
		res.writeBody("Hello, World!", "text/plain");
}
```
https://github.com/rejectedsoftware/vibe.d/blob/master/source/vibe/http/server.d#L104
I expected to see in listenHTTP() function some processing but 
it's simply get args and then do return:
return listenHTTP(...)

Could you explain why it's do so?

--
Where is constructor of this class? 
http://vibed.org/api/vibe.http.client/HTTPClientRequest

How I should use it if have only docs, and do not have examples? 
(I am trying understand how to use docs without cope-past 
examples)
Mar 19 2016
parent reply Alex Parrill <initrd.gz gmail.com> writes:
On Saturday, 19 March 2016 at 19:53:01 UTC, Suliman wrote:
 Thanks! I am understand a little bit better, but not all.

 ```
 shared static this()
 {
 	auto settings = new HTTPServerSettings;
 	settings.port = 8080;

 	listenHTTP(settings, &handleRequest);
 }

 void handleRequest(HTTPServerRequest req,
                    HTTPServerResponse res)
 {
 	if (req.path == "/")
 		res.writeBody("Hello, World!", "text/plain");
 }
 ```
 https://github.com/rejectedsoftware/vibe.d/blob/master/source/vibe/http/server.d#L104
 I expected to see in listenHTTP() function some processing but 
 it's simply get args and then do return:
 return listenHTTP(...)

 Could you explain why it's do so?

 --
 Where is constructor of this class? 
 http://vibed.org/api/vibe.http.client/HTTPClientRequest

 How I should use it if have only docs, and do not have 
 examples? (I am trying understand how to use docs without 
 cope-past examples)
The function is overloaded; it's calling the main implementation at line 77 after transforming the arguments. The constructor for HTTPClientRequest is likely undocumented because you should not construct it yourself; vibe.d constructs it and passes it to the function you register with listenHTTP.
Mar 19 2016
parent Suliman <evermind live.ru> writes:
 The constructor for HTTPClientRequest is likely undocumented 
 because you should not construct it yourself; vibe.d constructs 
 it and passes it to the function you register with listenHTTP.
How to understand looking at docs that it work as you saying?
Mar 20 2016