(1)
2
1
输出
a = [1, 2]
puts b while b = a.pop
(2)
undefined local variable or method `b'
导致错误
b = nil
a = [1, 2]
puts b while b = a.pop
(3)
2
1
输出
b
发生了什么事?为什么#2中$ ruby --version
ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux]
的范围与其他任何范围不同?
public interface IPerson
{
}
public abstract class Person
{
public string Name { get; set; }
public string LastName { get; set; }
public Int16 Age { get; set; }
}
public class Politics : Person, IPerson
{
public string Party { get; set; }
public int Experience { get; set; }
}
public class Students : Person, IPerson
{
public string Major { get; set; }
public int Year { get; set; }
}
public class Retired: Person, IPerson
{
public int Pension { get; set; }
public string Hobby { get; set; }
}
public class PersonLists : IPerson
{
public List<Retired> AllRetired = new List<Retired>();
public List<IPerson> AllPeople = new List<IPerson>();
public Students AStudent = new Students();
public Politics APolitic = new Politics();
public Retired ARetired = new Retired();
}
编辑:最初我列出了irb的行为不同。它不是;我在一个“肮脏”的会议中工作。
答案 0 :(得分:0)
puts语句在最初定义变量'b'之前执行,因此导致错误。
作为一个类似的示例,但使用until语句,请考虑以下代码:
a = [1, 2]
begin
puts "in the block"
end until b = a.pop
您是否希望在块内定义b?
从技术上讲,唯一的区别是直到真正的返回值停止,而只要a.pop返回真值,while将继续。
两种情况都是b在发生之前,b <范围内 。在作业完成后,例如当循环返回时,b在当前范围内可用。这就是所谓的词法范围,就像ruby一样适用于像这样的局部变量。
我发现this article有助于理解ruby中的范围。
更新1:在我的回答的上一个版本中,我写道,这与 if 无法比较。虽然这仍然是正确的,但它与问题无关,这是一个简单的范围问题。
更新2:添加了一些链接,以获取有关红宝石作用域的更多详细说明。
更新3:删除了第一句,因为它错了。
答案 1 :(得分:0)
变量由词法解析器声明到它们的范围,它是线性的。在while b = a.pop do puts b end
中,解析器在使用(b = a.pop
)之前会看到赋值(puts b
)。在第二个示例puts b while b = a.pop
中,当定义仍然未知时会看到使用,这会产生错误。
答案 2 :(得分:-1)
a = [1, 2]
while b = a.pop do puts b end
与
相同a = [1, 2]
b = a.pop
puts b
b = a.pop
puts b
(2)
a = [1, 2]
puts b while b = a.pop
与此相同
a = [1, 2]
puts b
b = a.pop
puts b
b = a.pop
puts b
当b第一次传入时,它尚未初始化。因此错误信息
(3) b初始化为零。甚至nil是ruby中的一个对象
b = nil
a = [1, 2]
puts b while b = a.pop