If I try the following code:
call/wait/output {webrequest http://google.com login password} content
REBOL complains with an error. Instead, I have to use the following:
content: ""
call/wait/output {webrequest http://google.com login password} content
Why?
Update: I thought answer would be simple …
“Why?” is a tricky question! I’ll try and give a rationale…
When passing back a value from a function that is supposed to gather data and hand it back, there are two basic options (in most languages).
One is to use it as the
return. (In languages like Rebol and Ruby, the implicit return is what the last statement in a code block evaluates to.) The other way to hand back data is to poke it into a parameter which the caller has passed “by reference” or “by pointer”.Current design of
callis that it returns the exit code of the process. But let us imagine an alternate universe where the refinement tocallof/outputchanged the return value, it might look like this:The design choice was not to do this.
callalways returns the simple exit code. Instead, if you care about the/outputof a call, you pass a parameter by reference…into which Rebol will write the console results.It’s very flexible, because Rebol lets you (for instance) pass in a parameter which is an open file to write the results…as opposed to making you store a function return that might be very large and then writing it out. Whether
callshould be writing to a file or putting the results in a string is cued by the data type of the “by reference” parameter.In short, this is a design decision of the language. Rather than making an assumption about where the output should go, Rebol “sniffs” the parameter type and does the appropriate thing. If you haven’t established a data type for
content…it can’t work. Again if we consider an “alternate universe”, it would be possible forcallto have different refinements:And then it wouldn’t have to worry about whether
contentwas previously declared, call would assume it’s supposed to turn content into a string. If you were writing to a file, it could create it for you…like this:But that wouldn’t let you write into an arbitrary location of an already-existing file, or a position in an existing string. Simply put, requiring
contentto be previously declared finesses this. But as you’ve noticed, it takes a little more code. You could, if you wished, put the declaration inline: