Skip to content

Instantly share code, notes, and snippets.

@joshsarna
Last active March 5, 2019 18:16
Show Gist options
  • Save joshsarna/cc3ea6c22cb7e1e52b380f8f0bc620b0 to your computer and use it in GitHub Desktop.
Save joshsarna/cc3ea6c22cb7e1e52b380f8f0bc620b0 to your computer and use it in GitHub Desktop.

In ruby, as in other programming languages, it's not always intuitive when you have access to what variables. Instance variables are available anywhere within a file (or other files that load or have access to that file). Non-instance variables, though, are sometimes available within code blocks and sometimes aren't. The table below is a quick reference, but we'll dive into specifics below.

Access Non-Instance Variables Defined Outside From Within Access Non-Instance Variables Defined Inside From Without
Methods no no
Loops yes no
Conditionals yes yes

Methods

Variables defined outside of methods can't be accessed within methods unless they are passed in (or the method is called on them) or they are instance variables.

x = 3
@y = 4

def print_x_and_y
  p @y  # => 4
  p x  # => undefined local variable or method `x' for main:Object (NameError)
end

print_x_and_y

Likewise, variables defined within methods cannot be accessed outside of those methods unless they are instance variables or are returned.

def some_letters
  x = 3
  @y = 4
  z = 5
  return z
end

z = some_letters

p z  # => 5
p @y  # => 4
p x  # => undefined local variable or method `x' for main:Object (NameError)

Loops

Loops handle scope differently than methods. Variables defined outside of loops can be used within loops, but variables defined within loops (or as block variables) cannot be used outside of those loops).

i = 0
1.times do
  p i  # => 0
end
1.times do
  i = 0
  p i  # => 0
end

p i  # => undefined local variable or method `i' for main:Object (NameError)

Conditionals

Conditionals have no particular rules for scope and are therefore something of a welcome breath of fresh air. Variables defined outside of conditionals can be used within conditionals. Variables defined inside conditionals can be used outside.

x = 1

if true
  p x  # => 1
  y = 2
else
  p "!!true == false, apparently"
end

p y  # => 2

Initializing Instance Variables

Ruby reads files top to bottom. For the most part, variables can only be referenced after they are defined.

p x  # => undefined local variable or method `x' for main:Object (NameError)
x = 2

An exception to this occurs with instance variables. Instance variables are "lifted out" and initialized at the beginning of runtime (before the rest of the file runs), although they are set to nil.

p @x  # => nil
@x = 2

While this isn't often useful, it could be valuable in loops that make use of conditional statements:

i = 1
until @i_is_greater_than10
  i += 1
  if i > 10
    @i_is_greater_than10 = true
  end
end

p i

It's not life changing, but it means we don't have to set @i_is_greater_than10 equal to false ourselves before starting the loop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment