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

> ----- "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.

-- 
Rein Henrichs
http://puppetlabs.com
http://reinh.com