为什么在使用 call/wait/output 重定向 shell 之前需要初始化 var
如果我尝试以下代码:
call/wait/output {webrequest http://google.com login password} content
REBOL 抱怨错误。相反,我必须使用以下内容:
content: ""
call/wait/output {webrequest http://google.com login password} content
为什么?
更新:我以为答案很简单......
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 ...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
“为什么?”这是一个棘手的问题!我将尝试给出一个基本原理...
当从应该收集数据并将其返回的函数传回一个值时,有两个基本选项(在大多数语言中)。
一种是将其用作
返回
。 (在 Rebol 和 Ruby 等语言中,隐式返回是代码块中最后一个语句的计算结果。)传回数据的另一种方法是将其放入调用者“通过引用”或“通过”传递的参数中。指针”。call
当前的设计是返回进程的退出代码。但是让我们想象一个替代宇宙,其中对/output
的call
的细化改变了返回值,它可能看起来像这样:设计选择不是这样做。
call
始终返回简单的退出代码。相反,如果您关心调用的/output
,您可以通过引用传递一个参数...Rebol 会将控制台结果写入其中。它非常灵活,因为 Rebol 允许您(例如)传入一个参数,该参数是一个打开的文件来写入结果......而不是让您存储可能非常大的函数返回,然后将其写出来。
call
是否应该写入文件或将结果放入字符串中由“按引用”参数的数据类型提示。简而言之,这是语言的设计决定。 Rebol 不是对输出应该去哪里做出假设,而是“嗅探”参数类型并执行适当的操作。如果您还没有为
内容
建立数据类型...它就无法工作。同样,如果我们考虑一个“替代宇宙”,call
可能有不同的改进:然后它就不必担心
content是否
之前已经声明过,调用会假设它应该将内容转换为字符串。如果您正在写入文件,它可以为您创建它......就像这样:但这不会让您写入已存在文件的任意位置或现有字符串中的位置。简而言之,要求事先声明
content
可以巧妙地实现这一点。但正如您所注意到的,它需要更多的代码。如果您愿意,您可以将声明内联:"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
call
is that it returns the exit code of the process. But let us imagine an alternate universe where the refinement tocall
of/output
changed the return value, it might look like this:The design choice was not to do this.
call
always returns the simple exit code. Instead, if you care about the/output
of 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
call
should 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 forcall
to have different refinements:And then it wouldn't have to worry about whether
content
was 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
content
to 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:这很简单。如果您对 CALL 进行帮助,您将看到 /OUTPUT 选项需要以下类型之一的参数:字符串!、端口!、文件!、url!或没有!当您只传递 CONTENT 单词而不定义它时,您将传递一个未设置的!值与参数预期类型不匹配,因此会生成错误。
It is simple. If you do a HELP on CALL, you'll see that the /OUTPUT option requires an argument of one of following types: string!, port!, file!, url! or none!. When you just pass CONTENT word without defining it, you are passing an unset! value which doesn't match the argument expected type, hence generates an error.