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 greetEx. 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 nilhowever, 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 strworking 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
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 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 falsesome 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