I'm learning Ruby and practicing by writing a Caesar cipher. Here's my code so far:
print "Enter rotation: "
rotation = gets.chomp
print "Enter string to encrypt: "
string = gets.chomp
def encrypt
keys = (' '..'z').to_a
values = (' '..'z').to_a.rotate(rotation)
hash = Hash[keys.zip(values)]
chars = string.split('')
encrypted_chars = chars.collect { |char| hash[char] }
encryptd_string = encrypted_chars.join
end
puts "Encrypted string: " + encrypt
It's saying that I don't have access to the rotation
variable inside of the encrypt
method. NameError: undefined local variable or method 'rotation' for main:Object
.
From what I understand, rotation
is a local variable with outer scope, and should be accessible inside of the encrypt
method. Obviously something is wrong with that reasoning, so could someone explain what's wrong?
This is a duplicate of Ruby accessing outer variables in nested function.
You could make it an instance variable on the containing object by calling it @rotation
, but why not just pass string
and rotation
into the encrypt
method?
The reason for this behaviour is that Local variables exist in a local scope and defining a method creates a new local scope for that method. Local varables are only visible in the current scope.
I was confused by this and found that relating the OP's question to one of nested methods only added confusion. But I've done a bit more research and discovered this succinct question and, in particular, this answer that explains it clearly as well as demonstrating a way to define a method without creating a new scope.
(I'm just adding this answer for the benefit of others because my search for an answer led me to this question.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With