Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialDavid Savoir
6,172 Pointsundefined method `+' for nil:NilClass (NoMethodError)
I'm still attempting to solve caesar's cipher , but somehow am getting an error on the following block of code
def caesar_cipher(string, interval)
cipherlist = []
cipherlist = string.split()
#Iterate over every word (loop)
cipherlist.each do |word|
word.split("").each do |letter|
puts("Printing original letter #{letter}")
if letter == letter.upcase
newword = upcase_cipher(word, letter, interval)
else
if letter == [a-z]
newword += downcase_cipher(word, letter, interval)
else
newword+= letter
puts newword
end
end
end
end
end
And the error is referring to the assignments of the respective functions' return to the variable newword: undefined method `+' for nil:NilClass (NoMethodError)
Any idea what I'm doing wrong here ?
Thanks in advance,
David
7 Answers
Maciej Czuchnowski
36,441 PointsOK, I have a partial solution: your scopes are wrong. You have to change all instances of variables arraycounter
, counter
and newword
into @arraycounter
, @counter
and @newword
. You will get a result, no errors, but the result won't be what you were looking for. And I still don't know what this should do: if letter == [a-z]
Maciej Czuchnowski
36,441 PointsWhich line throws the error? Maybe this should have a space before the +: newword+= letter
.
David Savoir
6,172 PointsHere's the entire code:
def downcase_cipher(word, letter, interval)
arraycounter = 0
counter = 0
newword = ""
if letter.ord() + interval > 122
resultant = (letter.ord()+interval) - 122
newletter = (97 + resultant).chr
newword += newletter
counter += 1
if word.length == counter
cipherlist[arraycounter] = newword
puts ("This is word number: #{arraycounter} #{cipherlist[arraycounter]}")
newword = ""
arraycounter += 1
counter = 0
end
else
newletter = (letter.ord + interval).chr
puts ("Printing newletter #{newletter}")
newword += newletter
puts ("Printing newword #{newword}")
counter += 1
if word.length == counter
cipherlist[arraycounter] = newword
puts ("This is word number: #{arraycounter} #{cipherlist[arraycounter]}")
newword = ""
arraycounter += 1
counter = 0
end
end
return newletter
end
def upcase_cipher(word, letter, interval)
if letter.ord() + interval > 90
arraycounter = 0
counter = 0
newword = ""
resultant = (letter.ord()+interval) - 90
newletter = (65 + resultant).chr
newword += newletter
counter += 1
if word.length == counter
cipherlist[arraycounter] = newword
puts ("This is word number: #{arraycounter} #{cipherlist[arraycounter]}")
newword = ""
arraycounter += 1
counter = 0
end
else
newletter = (letter.ord + interval).chr
puts ("Printing newletter #{newletter}")
newword += newletter
puts ("Printing newword #{newword}")
counter += 1
if word.length == counter
cipherlist[arraycounter] = newword
puts ("This is word number: #{arraycounter} #{cipherlist[arraycounter]}")
newword = ""
arraycounter += 1
counter = 0
end
end
return newletter
end
def caesar_cipher(string, interval)
cipherlist = []
cipherlist = string.split()
#Iterate over every word (loop)
cipherlist.each do |word|
word.split("").each do |letter|
puts("Printing original letter #{letter}")
if letter == letter.upcase
newword = upcase_cipher(word, letter, interval)
else
if letter == [a-z]
newword += downcase_cipher(word, letter, interval)
else
newword+= letter
puts newword
end
end
end
end
end
caesar_cipher("What a string!", 5)
Here's the full error message:
*Printing original letter W
Printing original letter h
/home/ubuntu/workspace/caesar_cypher.rb:76:in block (2 levels) in caesar_cipher': undefined local variable or method
a' for main:Object (NameError)
from /home/ubuntu/workspace/caesar_cypher.rb:71:in each'
from /home/ubuntu/workspace/caesar_cypher.rb:71:in
block in caesar_cipher'
from /home/ubuntu/workspace/caesar_cypher.rb:70:in each'
from /home/ubuntu/workspace/caesar_cypher.rb:70:in
caesar_cipher'
from /home/ubuntu/workspace/caesar_cypher.rb:87:in `<main>' *
Maciej Czuchnowski
36,441 PointsOK, so first you have to deal with line 76:
if letter == [a-z]
Right now they seem to be names of variables that have no value. You probably want to put them in quotes, do an .ord method to convert them into numbers and then back again into a character.
In line 79, you are trying to operate on a value that is nil. + is a method, it adds stuff. But nil is not a numerical and it's not a string value, so it doesn't know what to do with it. You could do something like this:
newword = ""
newword += letter
But then it will give you an error in line 52 and then some more errors along the way (including the error in variable counter
- it also has a nil value and you're trying to add something to it).
You have to go through your whole code again and follow the values of each variable along the way.
David Savoir
6,172 PointsThanks ! Care to elaborate on the scope part though ? I am not using classes here, but is ruby assuming that I am ?
Thanks in advance.
Maciej Czuchnowski
36,441 PointsYou're defining three separate methods:
def downcase_cipher, def upcase_cipher and def caesar_cipher
You define the variables I mentioned in the first method and they are local variables (no @), so their scope is only limited to that single method. Other methods have no idea what these variables are.
David Savoir
6,172 PointsMakes sense! Thanks!
David Savoir
6,172 PointsActually the if letter = [a-z] part was supposed to be a regex.
I turned it into this:
if letter == /^[a-z]*$/
I also found a thread referring to using the .tr method on stackoverflow, but I decided to try and stay with what I know for now :-)