Tod Lazarov
Tod Lazarov

Reputation: 91

A nil class when trying to initialize a deck of cards

The following code is resulting in nil and I can't figure out why. Is there something wrong with my initialization?

class Card
    VALUES = %w(2 3 4 5 6 7 8 9 10 J Q K A)
    SUITS = %w(S H D C)

    def initialize(suit, value)
        @suit = suit
        @value = value
    end
end

class Deck
    attr_accessor :cards

    def initialize
        @cards = []
        Card::SUITS.each do |suit|
            Card::VALUES.each do |value|
                @cards << Card.new(suit, value)
            end
        end
    end
end

Deck.new

p @cards

Upvotes: 0

Views: 153

Answers (5)

Sagar Pandya
Sagar Pandya

Reputation: 9497

Currently your output for @cards array is difficult to read and contains object info. I thought I'd offer an alternative I've just conjoured up, hope it helps:

class Deck

  attr_writer :suits, :values
  attr_accessor :deck

  def initialize
    suits
    values
    generate_deck
    shuffle
  end

  def generate_deck
    @deck = []
    @suits.each do |suit|
      @values.each { |value| @deck << [suit, value] }
    end
  end

  def suits
    @suits  = ['Clubs', 'Diamonds', 'Hearts', 'Spades' ]
  end

  def values
    @values = ('2'..'10').to_a + ['J','Q','K','A']
  end

  #just in case you want to shuffle your deck
  def shuffle
    @deck.shuffle!
  end

end

require 'pp' #this makes the output prettier
new_deck = Deck.new
pp new_deck.deck #calls your current deck so you can see it

Output example:

$ ruby yourfilename.rb
[["Hearts", "K"],
 ["Spades", "5"],
 ["Clubs", "7"],

 #code omitted... (the rest of your cards would be here)

 ["Clubs", "K"],
 ["Hearts", "5"],
 ["Diamonds", "J"],
 ["Hearts", "7"]]

Upvotes: 0

Sagar Pandya
Sagar Pandya

Reputation: 9497

In short, instance variables can only be seen by other methods from within the same class. I believe what you're trying to do is:

new_deck = Deck.new
p new_deck.cards

Calling the cards method on new_deck returns @cards.

Upvotes: 1

hirolau
hirolau

Reputation: 13921

or just:

my_deck = Deck.new

p my_deck.cards

Upvotes: 1

knut
knut

Reputation: 27875

@cards is not known outside the object. Outside the class Deck it is a instance variable of the top-level scope in Ruby.

You have to use the accessor method to get the content:

class Card
    VALUES = %w(2 3 4 5 6 7 8 9 10 J Q K A)
    SUITS = %w(S H D C)

    def initialize(suit, value)
        @suit = suit
        @value = value
    end
end

class Deck
    attr_accessor :cards

    def initialize
        @cards = []
        Card::SUITS.each do |suit|
            Card::VALUES.each do |value|
                @cards << Card.new(suit, value)
            end
        end
    end
end

deck = Deck.new  #<--- Store object in a variable

p deck.cards  #<--- Use accessor

Upvotes: 1

eugen
eugen

Reputation: 9226

You create a new object Deck.new, but you don't print the value of its cards - you print a @cards instance variable which in this context is nil.

You probably wanted something like p Deck.new.cards.

Upvotes: 0

Related Questions