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
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.
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?
--
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
> ----- "William Song" <wei_song1990@hotmail.com> wrote:
>
>> 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?
>> --
>> 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' ) )
>
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.
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.