Reputation: 19178
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?
Upvotes: 6
Views: 5538
Reputation: 9943
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.)
Upvotes: 2
Reputation: 6397
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?
Upvotes: 5