Question

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?

Était-ce utile?

La solution

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?

Autres conseils

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.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top