Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

258
Visualizações
Why doesn't assignment to variable y work in a Ruby block?

I assign the value "1" to the variables x and y outside the block, and then I reference the variable x of the same name outside the block in a block, so x is both 1.

Next, I assign the value of x to y in the block. In theory, y should also be 1, but the most trusted result is x = 1, y = 3.

Please tell me why.

x = 1               
y = 1               
ary = [1, 2, 3]

ary.each do |x|     
    y = x           
end

p [x, y]            
over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

The source of confusion here is so-called shadowing. You have two local variables called x here, but only one called y. The second x variable is shadowing the first one - meaning that any attempt to access or assign to the first variable is doomed to fail.

When you do ary.each do |x|, you are creating new variable, which has nothing (except for the name) to do with the variable x you have created in the outer scope.

y on the other hand is not shadowed and the loop binding is accessing (and assigning to) the variable defined in the parent scope. Unfortunately there is no way (at least that I am aware of) of explicit local variable creation like var/let/const in javascript.

In short, your code executes as follow:

x = 1               
y = 1               
ary = [1, 2, 3]

ary.each do |x2|     
  y = x2         
end

p [x, y]

So in fact, assignment to y works just as expected. You assign it value of 1 before the block, and then you assign 3 more times within the block. The last assignment is y=3 so that's its final value.

BEWARE, THE HACK:

Well there actually is a way of forcing the local variable creation, and it is to add an extra yielding argument to each block. This should never be done in the actual code, and I only present it for completeness. You should actually avoid any variable shadowing whenever possible.

x = y = 1
ary = [2,3,4]

ary.each do |x, y| # this creates new local variables x and y, y is always set to nil for each iteration.
  y = x # y here is a shadowing variable, not the y of the parent scope
  puts [x,y].inspect
end

puts [x,y].inspect

# OUTPUTS:
  
[2, 2]
[3, 3]
[4, 4]
[1, 1]
over 4 years ago · Santiago Trujillo Relatório

0

Block parameters (the stuff between the pipes like |x,y|) are local to the block. But pre-existing variables are not.

total = 0
[1,5].each{|n| total += n} #works because total starts out as 0
puts total # => 6

If you want a block-local total then follow the parameters by a semicolon and a comma-separated list of variables

total = 0
[1,5].each{|n; total, _unused| total += n} #Error because total is nil
puts total 
over 4 years ago · Santiago Trujillo Relatório

0

Because you are redefining x in the scope of the block. ary.each do |x| does this.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda