Ruby循环局部变量与不可变性

Ruby循环局部变量与不可变性,ruby,functional-programming,Ruby,Functional Programming,我有以下代码: # Assuming each element in foo is an array. foo.each do |bar| zaz = bar.first # Other code using zaz, but not modifying it. end zaz局部变量是否会在循环内的每次迭代中被修改,使其可变?我不确定Ruby在这里的行为。这实际上取决于循环之前的代码 如果这是所有代码,则zaz是一个块局部变量,每次计算循环体时都会创建一个新的zaz变量 但是,如果周

我有以下代码:

# Assuming each element in foo is an array.
foo.each do |bar|
  zaz = bar.first
  # Other code using zaz, but not modifying it.
end

zaz
局部变量是否会在循环内的每次迭代中被修改,使其可变?我不确定Ruby在这里的行为。

这实际上取决于循环之前的代码

如果这是所有代码,则
zaz
是一个块局部变量,每次计算循环体时都会创建一个新的
zaz
变量

但是,如果周围范围中存在
zaz
局部变量,则
zaz
是块中的自由变量,并且由于块范围嵌套在其周围范围中,因此每次对块求值时,块外的现有
zaz
变量都将被反复重新分配

通过在块的参数列表中将
zaz
显式声明为块局部变量,可以确保始终将其视为块局部变量,并且从不在周围范围中查找:

foo.each do |bar; zaz|
  zaz = bar.first
end
但是,请注意,您的代码只有在IFF时才有意义,因为您的代码是不纯净和可变的:

  • 您指定给
    zaz
    ,但从未在块内实际使用它。因此,唯一有意义的方法是,如果
    zaz
    是外部范围中的局部变量,并且您正在分配它。尽管在这种情况下,您的整个循环只相当于
    zaz=foo.last.first

  • 每个
    仅评估块的副作用。如果没有副作用,
    每个
    都毫无意义,因此使用
    每个
    意味着你有副作用


  • 请注意,没有附加限定的术语“不可变”通常指数值。当谈到“不可变变量”时,我们通常明确地说“不可变变量”,以表明我们只讨论变量是否可以重新绑定,而不是改变对象状态。或者,我们可以说“常量”,这是“不可变变量”的技术术语……尽管这个术语在Ruby中已经有了特定的含义。

    它实际上取决于循环之前的代码

    如果这是所有代码,则
    zaz
    是一个块局部变量,每次计算循环体时都会创建一个新的
    zaz
    变量

    但是,如果周围范围中存在
    zaz
    局部变量,则
    zaz
    是块中的自由变量,并且由于块范围嵌套在其周围范围中,因此每次对块求值时,块外的现有
    zaz
    变量都将被反复重新分配

    通过在块的参数列表中将
    zaz
    显式声明为块局部变量,可以确保始终将其视为块局部变量,并且从不在周围范围中查找:

    foo.each do |bar; zaz|
      zaz = bar.first
    end
    
    但是,请注意,您的代码只有在IFF时才有意义,因为您的代码是不纯净和可变的:

  • 您指定给
    zaz
    ,但从未在块内实际使用它。因此,唯一有意义的方法是,如果
    zaz
    是外部范围中的局部变量,并且您正在分配它。尽管在这种情况下,您的整个循环只相当于
    zaz=foo.last.first

  • 每个
    仅评估块的副作用。如果没有副作用,
    每个
    都毫无意义,因此使用
    每个
    意味着你有副作用


  • 请注意,没有附加限定的术语“不可变”通常指数值。当谈到“不可变变量”时,我们通常明确地说“不可变变量”,以表明我们只讨论变量是否可以重新绑定,而不是改变对象状态。或者,我们可以说“常量”,这是“不可变变量”的技术术语……尽管这个术语在Ruby中已经有了特定的含义。

    每个
    循环都会改变对象。每个人都必须做点什么。 因为
    each
    不返回任何有用的东西-它返回数组本身,如果它将每个元素发送到某个地方(比如打印在屏幕上),它不会改变对象

    foo.each do |bar|
      # do something with element like
      # print it, change it, save it
    end
    
    功能交替映射

    foo.map { |bar| bar.something }
    
    它返回以不变方式处理的原始数组的新数组。显然,您必须小心使用不可变的方法。这不是一成不变的:

    foo.map { |bar| bar.something! } 
    
    这里是
    什么对数组的元素执行破坏性操作。
    
    然而,我从未见过像这样使用
    map
    。对破坏性的东西使用
    每一个

    每一个
    循环通常会使对象发生变异。每个人都必须做点什么。
    因为
    each
    不返回任何有用的东西-它返回数组本身,如果它将每个元素发送到某个地方(比如打印在屏幕上),它不会改变对象

    foo.each do |bar|
      # do something with element like
      # print it, change it, save it
    end
    
    功能交替映射

    foo.map { |bar| bar.something }
    
    它返回以不变方式处理的原始数组的新数组。显然,您必须小心使用不可变的方法。这不是一成不变的:

    foo.map { |bar| bar.something! } 
    
    这里是
    什么对数组的元素执行破坏性操作。
    
    然而,我从未见过像这样使用
    map
    。用
    每一个
    来做一些破坏性的事情。

    我的坏,我的意思是zaz变量而不是foo。我已经编辑了这个问题,“使这个代码可变”——你是什么意思
    Array#first
    不会修改数组,而且从未使用过
    zaz
    。我没有正确地发布问题,现在我已修复了它。只是想知道
    zaz
    是否会被认为是不可变的。在我的真实代码中,
    zaz
    被引用,但从未被修改。@Navarro“可变”和“不可变”通常指对象。正如名字所暗示的,变量应该是变化的。因此答案是肯定或否定,这取决于
    zaz
    的含义:变量
    zaz
    确实会改变,但对象
    zaz
    是referrin