Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable scope in Ruby

Tags:

ruby

Consider the following two snippets of ruby code.

puts "One"
if false
  d = 1
end
puts "Two"
puts d
puts "Three"

This prints the following

One
Two

Three

Now, consider the following

[].each do |i|
  flag = false
end
puts "Two"
puts flag
puts "Three"

This gives the following

Two
'<main>': undefined local variable or method 'flag' for main:Object (NameError)

Why is it that in the first case a blank is printed and the 2nd case an error is thrown ?

Thanks

like image 601
jimcgh Avatar asked Nov 24 '15 17:11

jimcgh


People also ask

What is variable scope in Ruby?

What is Variable Scope? Scope defines where in a program a variable is accessible. Ruby has four types of variable scope, local, global, instance and class. In addition, Ruby has one constant type.

What is variable scope example?

Variables have a global or local "scope". For example, variables declared within either the setup() or draw() functions may be only used in these functions. Global variables, variables declared outside of setup() and draw(), may be used anywhere within the program.

What is meant by variable scope?

Variable scope refers to the extent of code in which a variable can be referenced (accessed and modified). Variables defined inside a function are called local variables. The scope of local variables and dummy arguments is limited to the function in which they are defined.

What is variable in Ruby on Rails?

Ruby variables are locations which hold data to be used in the programs. Each variable has a different name. These variable names are based on some naming conventions. Unlike other programming languages, there is no need to declare a variable in Ruby.


1 Answers

The difference is that the if block isn't actually a separate scope like it is in other languages such as Java. Variables declared within the if block have the same scope as the surrounding environment. Now, in your case, that if block won't actually be executed, so you'd normally expect d to be undefined (resulting in the same error you got in the second example). But ruby is a little "smrt" in that the interpreter will set up a variable with that label the moment it sees it, regardless whether it is actually executed, because it essentially doesn't know just yet whether that branch will indeed execute. This is explained in "The Ruby Programming Language" by David Flanagan and Yukihiro Matsumoto (can't copy paste the text, adding screenshot instead): enter image description here

In the case of the .each loop, that do...end you've written in is actually a block, and it does have its own local scope. In other words, variables declared within a block are local to that block only.

However, blocks "inherit" the scope of the environment in which they're declared, so what you can do is declare flag outside of the .each iteration block, and then the block will be able to access it and set its value. Note that in the example you've given, that won't happen because you're attempting to iterate an empty array, but at the very least you won't receive an error any more.

Some additional reading:

  • Block variable scope in ruby
  • Understanding scopes in ruby
like image 65
Paul Richter Avatar answered Sep 20 '22 14:09

Paul Richter