Defining struct in a class

How can I properly define a struct in a class?

If I have

class Cards
Card = Struct.new(:suit, :number)
@cardsOnHand=[]

@cardsOnHand.push(Card.new("S","5"))

end

This will give me an error message saying the push is not defined for
NilClass. How should I fix this?

On 2010-06-07 15:16:33 -0700, William Song said:

This will give me an error message saying the push is not defined for
NilClass. How should I fix this?

The error you reported has nothing to do with your Card struct. Besides
which, your code works for me as is.

Rein H. wrote:

On 2010-06-07 15:16:33 -0700, William Song said:

This will give me an error message saying the push is not defined for
NilClass. How should I fix this?

The error you reported has nothing to do with your Card struct. Besides
which, your code works for me as is.

Sorry, I meant to put it into a function. I over-simplified it when
posted here.

class Cards
Card = Struct.new(:suit, :number)
@cardsOnHand=[]

def a()
    @cardsOnHand.push(Card.new("S","5"))
end

end

cards = Cards.new
cards.a()

The above code will give an error.

I assume you want the first two lines of you class definition to be run
every time someone creates an instance of you class. If you do you
should put the into a method called initialize. That will be run
automatically when new is called and should solve your problem

On 2010-06-07 16:16:57 -0700, William Song said:

Sorry, I meant to put it into a function. I over-simplified it when

cards = Cards.new
cards.a()

The above code will give an error.

You create an instance variable, @cardsOnHand, in the class scope. That
means it is an instance variable of the object Cards (the class). You
then attempt to access it in the scope of an instance method, i.e. on a
Cards instance. They are two different objects, two different scopes
and two different variables.

I would suggest reading the chapter Classes, Objects and Variables in
Programming Ruby: The Pragmatic Programmer's Guide to better understand the
concept of scope in Ruby and how it effects variables. Hint: you
probably want to set this instance variable when you initialize an
Cards object.

I would also suggest reading
styleguide/RUBY-STYLE at master · leahneukirchen/styleguide · GitHub to get
a better grasp of common Ruby style, such as two space indention,
adding spacing before and after the = in a variable assignment, using
camel_case for variable and method names, and removing empty () on the
ends of methods.

----- “William Song” [email protected] wrote:

This will give me an error message saying the push is not defined for
NilClass. How should I fix this?

Posted via http://www.ruby-forum.com/.

Your problem is not a struct but the fact that you are not properly
instantiating an instance variable. I probably wouldn’t use a struct
like you have instead solve the problem understand that your cards class
is a deck that structurally is just an array:

class Deck < Array
def add( card )
raise ArgumentError unless card.is_a?( Card )
# Other checks on how many cards per suite and not allowing
duplicate cards

self.push( card )

end
end

class Card
attr_accessor :number, :suite

def initialize( number, suite )
@number = number.to_s if /[2-9AKQJ]/.match( number.to_s )
@suite = suite.to_s if /[CHDS]/.match( suite.to_s )

raise Exception if @number.nil? || @suite.nil?

end
end

deck = Deck.new

deck.add( Card.new( 3, :H ) )
deck.add( Card.new( ‘4’, ‘S’ ) )

----- “Rein H.” [email protected] wrote:

@cardsOnHand=[]
instantiating an instance variable. I probably wouldn’t use a struct
end
end
deck of cards. It would be better to create a Deck class that delegated

Rein H.
http://puppetlabs.com
http://reinh.com

Thanks for pointing that out Rein. You learn something new every day
when active in this mailing list. Forwardable might be possible but I
think you are right that Deck is really its own class that uses an array
object as the internal data store.

On 2010-06-08 14:02:03 -0700, Wes B. said:

@cardsOnHand.push(Card.new(“S”,“5”))
class is a deck that structurally is just an array:
class Card
deck = Deck.new

deck.add( Card.new( 3, :H ) )
deck.add( Card.new( ‘4’, ‘S’ ) )

The fact that the Deck class violates the Liskov Substitution Principle
should imply that a Deck is not necessarily an Array. For instance, the
semantics of many Array and Enumerable methods would be undefined on a
deck of cards. It would be better to create a Deck class that delegated
semantically appropriate methods to an internal array object (using
Forwardable, for instance) rather than expecting a Deck to conform to
the entire Array interface.

This is why it is, in general, somewhat dubious to subclass base
classes for your own use, even when there seems to be a superficial
similarity.

Of course, none of this has anything to do with the original problem.