Skip to content

Instantly share code, notes, and snippets.

@bharris62
Created August 17, 2016 23:13
Show Gist options
  • Save bharris62/fd29a466a2981a255c2117100842d78c to your computer and use it in GitHub Desktop.
Save bharris62/fd29a466a2981a255c2117100842d78c to your computer and use it in GitHub Desktop.

Local Variable Scope, especially how local variable interact with blocks and methods

Local variables cannot be accessed in a method, but can in a block.

ex. this is not possible

greet = 'hello!'

def greeter(str)
  puts greet + str #greet is not accessible inside the method.
end

greeter('Joe')

NameError: undefined local variable or method `greet' for main:Object

however, inside a code block it is possible to access a local variable

greet = ['hello', 'hola', 'howdy']
name = 'Jon'

greet.each do |greeting| # greeting is a local variable only accesible to the block, however. 
  puts "#{greeting} #{name}"
end  


# for reference, the `.each` method returns the array of greet

how passing an object into a method can or cannot permanently change the object

Ex. of a non destructive method

arry = [1, 2, 3, 4, 5]

new_arry = arry.select { |num|  num > 3} # the select method is non destructive, it returns a new array with the values selected

puts arry  # unaltered prints out 1,2,3,4,5
puts new_arry # only has the numbers of 4 and 5

# puts return nil

however, some methods are destructive, such as map!

arry = [1, 2, 3, 4, 5]

new_arry = arry.map! { |num| num + 1 } # map! returns the new array, also mutates the existing array 

puts arry # prints 2,3,4,5,6
puts new_arry # prints 2,3,4,5,6

# for reference, map does not mutate the original array, only map! does.  

It is generally a good sign that if a method has a ! or 'bang' operator it is destuctive. And by destructive I mean that it will mutate the original array, or hash.

passing values into methods can also cause some odd, and adverse effects

def amethod(param)
  param += " world"   # this is going to return a new string object, NOT permanent, reassignment, outputs hello
                      # param = param + " world" (reassigning param to )
  param + " world"    # NOT permanent, string concatination, the + is a method, outputs hello
  param << " world"   # WILL mutate the calling object, which is param, << is a method call
                      # destructive, outputs hello world
end

str = "hello"
amethod(str)

p str

working with collections (Array, Hash, String), and popular collection methods (each, map, select, etc). Study these methods carefully.

.each method iterates over an array and returns the original array, or hash

a = [1,2,3]
 
a.each { |num| puts num + 1}

# prints
# 2
# 3
# 4

# =>[1, 2, 3]

hash

a = {a: 1, b: 2, c: 3}

a.each { |key,value| puts "#{key}: #{value+1}"}

# prints 
# a: 2
# b: 3
# c: 4

# returns {:a=>1, :b=>2, :c=>3}

Look above for .map .map! and .select both .map and .select are non destructive and return new arrays, whereas .map! both returns a new array and modifies a new array.

.each_with_index

a = ["a", "b", "c"]

a.each_with_index do |val, idx|
  puts "#{idx}: #{val}"
end

# prints 
# 0: a
# 1: b
# 2: c

# returns ["a", "b", "c"]

or creating a hash with each_with_index

hash = Hash.new

%w(cat dog wombat).each_with_index { |item, index|
  hash[item] = index
}
hash   #=> {"cat"=>0, "dog"=>1, "wombat"=>2}

More of these can be found in the ruby enumeral section

a few more popular ones

pop removes the last element in an array. returns the removed value, mutates original array. shift removes the first element in an array. returns the removed value, mutates original array. any? returns true or false based on block, indicated by ?, does not alter original array. all? returns true or false based on block, indicated by ?, does not alter original array none? only returns true if NONE of the objects return true find returns the first value based on the block that returns true.

puts vs returns

puts are printed values, not returned values. see above when looking at .each the method prints out what is specified by the block, but it still returns the original array or hash.

##false vs nil

true and false are not just simply keywords. Every object in ruby can be evaluated to a boolean value.

although nil evaluates to false, it is not the same as 2 > 5.

4 && 5 # This returns 5
nil && true # This returns nil
true && nil # This returns nil
true || nil # This returns true
nil || "" # This returns ""
0.nil? # returns false

some differences: -nil cannot be a value, whereas false can be a value -false is a boolean, whereas nil is not -nil is an object for NilClass, where false is an object of FalseClass -nil is not a data type

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