0

我正在从 PERL 转换为 Ruby。我在 PERL 中喜欢的一件事是能够通过使用我的命令在 sub 中拥有本地范围。IE 此代码不起作用,因为 $only_in_the_if 超出范围。

...
if (cond) {
my ($only_in_the_if) = bar($foo );
}
bar1($only_in_the_if) ; #can't work, $only_in_the_if scope is finished
...

在 Ruby 中,only_in_the_if 将出现在方法范围内。有任何想法吗?

4

2 回答 2

0

Ruby 的代码块与 Perl 和 AFAIK 的代码块不同,没有简单的方法可以将变量声明性地限定为仅在复合语句(例如 if)中的词法范围内。

您可以使用 Taryn 建议的代码块。我不确定收益是否会超过成本(在执行速度和与其他 Ruby 开发人员工作方式的差异方面)。

另一个简单的解决方案是保持复合语句的轻量级,并依靠更短的方法来实现严格的变量范围。在 Perl 中,您可能会编写一个 30 行的方法,在 ifs 和 fors 中有 4 或 5 行的小子块,而在 Ruby 中,可以使用具有主要流程的控制方法来完成相同的流程和范围,以及几个变量范围的私有方法。这些方法之间共享的数据可以是对象状态(在@变量中)或控制方法中的范围变量,这些变量作为参数传递给私有方法。

def main_method foo
  if (cond)
    bar foo
  end
end

private 
def bar param
 only_in_bar = Math.whatever(param)
 # Do some stuff with only_in_bar
end 
于 2013-03-07T12:19:21.687 回答
0

简单范围显然不在条件范围内...

irb(main):001:0> if my_cond
irb(main):002:1>   my_var = 'blah'
irb(main):003:1>   puts my_var
irb(main):004:1> end
blah
=> nil
irb(main):005:0> puts my_var
blah
=> nil

但是你可以使用一个块来强制作用域......即使它有点奇怪。

irb(main):006:0> 1.times { new_var = 'blah'; puts new_var } if my_cond
blah
=> 1
irb(main):007:0> new_var
NameError: undefined local variable or method `new_var' for main:Object
    from (irb):7
    from :0

如果您愿意,您可以将其元编程到一个名为“my”的方法中;)

于 2013-03-07T11:21:49.007 回答