If it was not async, this could have a much simplier API, like
response = req.start()
But instead it is designed that you pass a code block as callback function. Whatever return you use in the callback function will not return from the outer fn function, but only once the inner function is called.
Look into passing a callback function to fn that works on the value you were trying to return, or look into Promises that you can directly return from fn. There is a SketchUp-compatible Promise library.
You cannot. A Ruby method returns when it’s last statement has finished being evaluated and always returns that last value evaluated or nil otherwise.
But … any references local to the method go out of scope when the method returns.
So your req reference will go out of scope and get garbage collected. It is better in practice to use a @var so other methods could access the request object if needed. (Notice how in the documentation persistent @request references are shown?)
We are assuming that your @req reference and method fn are properly wrapped within a custom module.
P.S.: Do not insert spaces between method names and their argument lists. Ruby does not like this and may output warnings to the console. Users may see these warnings and become concerned.
The Ruby Net::Http module is synchronous. But note that it might not work properly in older SU versions. Also, any HTTP request could for unexpected reasons out of your control take a significant time due to network issues - they are much better done as async for the sake of user experience. From the point of a developer it takes some readjustments, but generally the better approach.