Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 块局部变量的语法_Ruby_Syntax_Convention - Fatal编程技术网

Ruby 块局部变量的语法

Ruby 块局部变量的语法,ruby,syntax,convention,Ruby,Syntax,Convention,我对采用一种好的样式来定义块局部变量感到困惑。这些选择包括: 选择A: method_that_calls_block { |v, w| puts v, w } 选择B: method_that_calls_block { |v; w| puts v, w } 当我希望块本地有一个默认值时,混淆是被计算出来的。我感到困惑的选择是: 选择C: method_that_calls_block { |v, w = 1| puts v, w } 选择D: method_that_calls_blo

我对采用一种好的样式来定义块局部变量感到困惑。这些选择包括:

选择A:

method_that_calls_block { |v, w| puts v, w }
选择B:

method_that_calls_block { |v; w| puts v, w }
当我希望块本地有一个默认值时,混淆是被计算出来的。我感到困惑的选择是:

选择C:

method_that_calls_block { |v, w = 1| puts v, w }
选择D:

method_that_calls_block { |v, w: 1| puts v, w }
是否有关于如何定义块局部变量的约定

另外,似乎是
语法不起作用!奇怪

选项B无效。正如@matt所指出的,这是一种有效的(虽然不太清楚)语法(请参见此处:)


选项C为
w
提供了一个默认值,这是一个常规值,而选项D是默认值的语法。

这四个选项都是有效的,但它们都有不同的语义——正确与否取决于您试图实现的目标

例子 考虑以下方法,该方法生成多个值

def frob
产量1,2,3
结束
选项A:块参数 “给我前两个收益值,如果有的话,我不关心其他的。”

frob{v,w}[v,w].inspect}
# => "[1, 2]"
选项B:块参数+块局部变量 “给我第一个值,我不关心其他值;给我一个额外的未初始化变量”

frob{v;w{v,w].inspect}
#=>“[1,无]”
选项C:块参数,有些带有默认值 “获取前两个值,如果第二个值未初始化,请将该变量设置为1:”

frob{v,w=1}[v,w].inspect}
#=>“[1,2]”“[1,2,3,nil,99]”
选项D:位置和关键字块参数 “获取第一个值,如果该方法生成关键字参数
w
,则也获取该值;如果没有,则将其设置为1。”

frob{v,w:1}[v,w].inspect}
# => "[1, 1]"
这是为以下情况而设计的:方法产生块参数:

def frobble
产量1,2,3,w:4
结束
弗罗布尔{v,w:1{v,w].检查}
# => "[1, 4]"
在Ruby<2.7中,带有关键字参数的块也会分解散列,尽管Ruby 2.7会给您一个函数,就像您将散列传递给一个采用关键字参数的方法一样:

def frobnitz
h={w:99}
产量1,2,3,h
结束
#Ruby 2.7
弗罗布尼茨{v,w:1{v,w].检查}
#警告:不推荐使用最后一个参数作为关键字参数;也许应该在通话中添加**
# => "[1, 99]"
Ruby 3.0不会给您一个弃用警告,但它也会忽略哈希:

#Ruby 3.0
弗罗布尼茨{v,w:1{v,w].检查}
# => [1, 1]
生成一个显式关键字参数仍然可以像3.0中预期的那样工作,不过:

#Ruby 3.0
弗罗布尔{v,w:1{v,w].检查}
# => "[1, 4]"
请注意,如果该方法产生意外的关键字,则关键字参数表单将失败:

def泡沫酸盐
产量1,2,3,w:99,z:-99
结束
Frobnite{v,w:1 |[v,w].检查}
#=>ArgumentError(未知关键字::z)
数组分解 当考虑返回数组的方法时,差异变得明显的另一种方式是:

def gork 收益率[1,2,3] 结束
通过一个参数传递一个块将获得整个数组:

gork{v|v.inspect}
# => "[1, 2, 3]"
但是,传递带有多个参数的块将获得数组元素,即使传递的参数太少或太多:

gork{v,w}[v,w].inspect}
# "[1, 2]" 
gork{v,w,x,y}[v,w,x,y].inspect}
#=>“[1,2,3,零]”
这里又是
块局部变量的语法可以派上用场:

gork{v;w{v,w].inspect}
#=>“[[1,2,3],零]”
但是请注意,即使是关键字参数也会导致数组被分解:

gork{v,w:99}[v,w].inspect}
# => "[1, 99]"
gork{v,w:99;x{v,w,x].inspect}
#=>“[1,99,零]”
外变量阴影 通常,如果在块内使用外部变量的名称,则使用该变量:

w=1;frob{v|w=99};W
# => 99
您可以通过上述任何一种选择来避免这种情况;它们中的任何一个都会对外部变量进行阴影处理,从而对块隐藏外部变量,并确保块对其产生的任何影响都是局部的

选项A:块参数:

w=1;frob{v,w | put[v,w]。检查;w=99};W
# [1, 2]
# => 1
选项B:块参数+块局部变量

w=1;frob{v;w|put[v,w]。检查;w=99};W
#[1,无]
# => 1
选项C:块参数,有些带有默认值

w=1;frob{v,w=33 | put[v,w]。检查;w=99};W
# [1, 2]
# => 1
选项D:位置和关键字块参数

w=1;frob{v,w:33 | put[v,w]。检查;w=99};W
# [1, 33]
# => 1
不过,其他的行为差异仍然存在

默认值 不能为块局部变量设置默认值

frob{v;w=1}[v,w].inspect}
#语法错误,意外的“=”,应为“|”
也不能将关键字参数用作块参数

frob { |v; w: 1| [v, w].inspect }
# syntax error, unexpected ':', expecting '|'
如果您知道正在调用的方法没有生成块参数,那么您可以使用默认值声明一个假块参数,并使用该值获得一个预初始化的块局部变量。重复上述第一选择D示例:

frob{v,w:1}[v,w].inspect}
# => "[1, 1]"

那么你推荐C&D而不是其他选项吗?A、C&D适用于不同的用例-A当你传递两个值时,C当你传递一个或两个值时,D当你传递一个值和一个散列时…谢谢你的澄清!“选项B无效。”–这是用于将变量声明为块的局部变量的语法,这样您就不会覆盖现有的局部变量