简体   繁体   中英

Local Variables and Methods with Ruby

I am having a problem making a change with an array in Ruby. The method is not able to use the global method. I am confused here and would love some assistance. How can I get an answer from a user and also use that answer?

a = [1,2,3,4,5]

puts "Pick number to insert into array:"
number = gets.chomp()

def insert(answer, number)
  a.insert(1,number)
end

insert(answer,number)

Of course I am getting the error:

methods.rb:13:in `insert': undefined local variable or method `a' for main:Object (NameError)
    from methods.rb:16:in `<main>'

The variable a is not defined within the scope of the insert method.

There are several types of variables in ruby, which can be summarised by the following table :

$            A global variable
@            An instance variable
[a-z] or _   A local variable
[A-Z]        A constant
@@           A class variable

In order for your code to work, you could either define a as a global variable (although this is generally considered bad practice!):

$a = [1,2,3,4,5]

puts "Pick number to insert into array:"
answer = gets.chomp()

def insert(answer)
  $a.insert(1, answer)
end

insert(answer)

Or, you could define a within the scope of the method:

puts "Pick number to insert into array:"
answer = gets.chomp()

def insert(answer)
  a = [1,2,3,4,5]
  a.insert(1, answer)
end

insert(answer)

Or, you could pass a into the method as a parameter:

puts "Pick number to insert into array:"
answer = gets.chomp()

def insert(a, answer)
  a.insert(1, answer)
end

a = [1,2,3,4,5]
insert(a, answer)

Or, you could define a class and make a an instance variable of that class - for example, something like:

class HelloWorld
  attr_reader :a
  def initialize
    @a = [1,2,3,4,5]
  end

  def insert(answer)
    @a.insert(1, answer)
  end
end

puts "Pick number to insert into array:"
answer = gets.chomp()

my_awesome_object = HelloWorld.new
my_awesome_object.insert(answer)
puts my_awesome_object.a

Method declaration introduces the new scope. There are many ways to accomplish a task, eg with instance variable:

@a = [1,2,3,4,5]

puts "Pick number to insert into array:"
number = gets.chomp

def insert(answer, number)
  @a.insert(1,number)
end

the method insert dont have variable a . You must send it there. So modify the code like this.

def insert(a, number)
  a.insert(1,number)
end

insert(a, number)

I hope this helps

Unlike blocks, methods do not capture the environment they were created in for the most part, other than object scope if a method is defined inside a class.

In your case, passing a explicitly to insert could help:

def insert(a, answer, number)
  a.insert(1, number)
end

If a and insert go hand-in-hand, a good OO design might be to encapsulate that data and behavior into a separate class. Not sure if it's the case here, but something to keep in mind.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM