Brian McCallister on 22 Nov 2005 00:33:27 -0000


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

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


On Nov 21, 2005, at 3:54 PM, Chris Braddock wrote:

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"]
irb(main):004:0>

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?

Just bringing it to your attention as I mentioned %w.


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

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?

Correct.

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.

Initialize is called by the constructor (new) and any return value is discarded. Constructors (new) return the thing being constructed by definition.


If you wanted to just return the array, consider:

module Deck

  def create_deck
    ...
  end
end

instead, which is more in line with passing around a data structure to functions designed to operate on that data structure. OO purists start coughing and complaining at stuff like this though =) Regardless, sometimes it is stil the thing to do =)

In this case I think it makes more sense to have a Deck class which you can iterate, and which defines deck specific operations (cut, for example, which takes an index and cuts the deck at that index).

It would be interesting to implement shuffle using the actual shuffle algorithm: cut at the mid point, merge every other with a 50/50 chance of a given side going "first", repeat seven times. It isn't *truly* random, but is the algorithm classically used for shuffling by hand.

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.

No, it makes complete sense to use an array internally to hold data if you have operations on it. You *could* use a pseduo-prototype approach and add singleton methods to the particular array:


# readable version
deck = %w(2 3 4 5 6 7 8 9 10 J Q K A)
deck.instance_eval do
    def cut index
        first, second = self[0, index], self[index, length]
        replace(second + first)
    end
end

deck.cut 7


# in irb irb(main):012:0> deck = %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"] irb(main):013:0> deck.instance_eval do irb(main):014:1* def cut index irb(main):015:2> first, second = self[0,index], self[index, length] irb(main):016:2> replace(second + first) irb(main):017:2> end irb(main):018:1> end => nil irb(main):019:0> deck.cut 7 => ["9", "10", "J", "Q", "K", "A", "2", "3", "4", "5", "6", "7", "8"] irb(main):020:0>

This would not be idiommatic however, as ruby rather encourages classes. I think your approach of defining a Deck class makes perfect sense. If you wanted to generalize it, you might mix in Enumerable so that you get the select, inject, etc methods. On the other hand, if you don't need them, don't. Anyone else using it can just reopen your class and mix it in if they need them.

-Brian



_______________________________________________
talk mailing list
talk@phillyonrails.org
http://lists.phillyonrails.org/mailman/listinfo/talk

_______________________________________________ talk mailing list talk@phillyonrails.org http://lists.phillyonrails.org/mailman/listinfo/talk