Chris Braddock on 21 Nov 2005 23:55:08 -0000

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: [PhillyOnRails] a little hold 'em code ... help please

Minor ruby idiom as you asked for feedback =)

Absolutely - just the kind of stuff I'm interested in - thanks.

A Ruby/OO noob could use a little help here.

I saw the Hold 'Em trainer project on the community wiki. Thought I might kick it around a bit.

I think I have some basic code to get a deck shuffled but there is one place where I'm a little confused (see comments) and I'd love to get some code critiques as I'm just fumbling my way through this right now.

class Card
 attr_reader :suit, :rank
 def initialize(suit, rank)
   @suit = suit
   @rank = rank

class Deck
 attr_reader :deck
 SUITS = ["C","D","H","S"]
 RANKS = ["2","3","4","5","6","7","8","9","10","J","Q","K","A"]

A very common idiom for constructing lists of strings is to use %w, a la

irb(main):001:0> ary = %w(2 3 4 5 6 7 8 9 10 J Q K A)
=> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]

Ah ok - very nice.

The %W variant allows interpolation:

irb(main):002:0> ace = 'A'
=> "A"
irb(main):003:0> ary2 = %W(2 3 4 5 6 7 8 9 10 J Q K #{ace})
=> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]

It just saves some typing for a common case =)

Does that accomplish something for this specific case or were you just bringing %W to my attention?

 def initialize
   @deck =
   SUITS.each do |suit|
     RANKS.each do |rank|
       @deck[@deck.length] =, rank)

It might be clearer to say

@deck <<, rank)

Yes that is more succinct.


 def shuffle
   deck_shuffled =
   deck_length_orig = @deck.length
   while deck_shuffled.length < deck_length_orig
     rand_card = rand(@deck.length)
     deck_shuffled << @deck[rand_card]

deck =
# why do I need to use deck.deck if I'm returning self on initialize? have pointer to self object and that's <> the array?

why not define each for the deck?

class Deck
  def each &block
    @deck.each &block


class Deck
  def each
    @deck.each { |card| yield card }

I like the first, personally, but either works, and each, traditionally, uses yield not an explicit param

Phew. Pretty cool. I guess this is the sort of thing where I'm going to have to rearrange my thinking patterns to embrace OO.

So was I right in my guess that the reason I have to use deck.deck to begin with is that the 'deck' before the period points to the object deck and the second 'deck' points to the instance variable @deck?

I still don't quite grasp why I can't return @deck in Deck#initialize and have a pointer directly to the @deck instance var.

Also I kind of expected that someone might come back and say it doesn't make sense to have the object that just points to the array and suggest I structure it differently altogether.

_______________________________________________ talk mailing list