0

How can I access an array defined outside the function? I've tried adding $coins.length as I had read somewhere for global variable — it didn't work. The reason I define the array outside is because there are other functions below that will be pushing a new item into that same array.

coins = []

def start

    puts "It's a sunny day. It's warm and you feel great."
    puts "You've picked up your son from creche. He's in a good mood and you've got home no problem."
    puts "This is when troubles start, and you know it."
    puts "You go out of the elevator and before you reach the door... 'give me the keeys'!"
    puts "Do you give him the keys? (Y/N)"
    print "> "


    while keys = gets.chomp.downcase
        case keys
        when "y"
            puts "you are in, good job. And you get a coin"
            coins.push("1")
            puts "you now have #{coins.length} coins"
            room
        when "n"
            cry("I wanted to dooooooo iiiiiiiit!")
        else    
            again
        end
    end
end
Pere
  • 850
  • 3
  • 14
  • 34

2 Answers2

2

Ruby is an object oriented language. Even more, Ruby appeared on the scene with a motto “everything is an object.” Even numbers and (sic!) nil in Ruby are objects:

▶ 42.class
#⇒ Fixnum < Integer
▶ nil.__id__
#⇒ 8

So, you are supposed to use objects for anything that is slightly more complicated than a one-liner. Objects have a lot of goodness out of the box: instance variables, lifecycle, etc.

class Game
  def initialize
    @coins = []
  end

  def add_coin(value)
    @coins << value
  end

  def coins
    @coins
  end

  def amount
    @coins.size
  end
end

Now you might create in instance of this class and while it’s alive, it will hold the value of @coins:

game = Game.new
game.add_coin("1")
puts game.coins
#⇒ ["1"]
puts game.amount
#⇒ 1
game.add_coin("1")
game.add_coin("2")
puts game.coins
#⇒ ["1", "1", "2"]
puts game.amount
#⇒ 3
Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
1

instead of defining global variable, try to define a method which you can use everywhere, like:

def coins
  @coins ||= []
end

def start

    puts "It's a sunny day. It's warm and you feel great."
    puts "You've picked up your son from creche. He's in a good mood and you've got home no problem."
    puts "This is when troubles start, and you know it."
    puts "You go out of the elevator and before you reach the door... 'give me the keeys'!"
    puts "Do you give him the keys? (Y/N)"
    print "> "


    while keys = gets.chomp.downcase
        case keys
        when "y"
            puts "you are in, good job. And you get a coin"
            coins.push("1")
            puts "you now have #{coins.length} coins"
            room
        when "n"
            cry("I wanted to dooooooo iiiiiiiit!")
        else    
            again
        end
    end
end

This way, the method will not be global and other methods can also access this method(coins) within the file.

Kuldeep
  • 884
  • 7
  • 12
  • Interesting use of ||=. I've read quite a lot, like https://stackoverflow.com/questions/995593/what-does-or-equals-mean-in-ruby, but I still can't figure out what it does in this case. It's interesting that @coins = [] wouldn't work. Could elaborate on what ||= is doing in this case? thx! – Pere Jul 30 '17 at 07:33
  • 1
    `foo ||= 42` is a shorthand for `foo = foo || 42`, as well as e.g. ` foo += 42` is a shorthand for `foo = foo + 42`. Here it’s used to set `@coins` instance variable if and only it was not set previously. – Aleksei Matiushkin Jul 30 '17 at 14:53