On 5/8/06, Logan Capaldo <logancapaldo / gmail.com> wrote:
>
> On May 8, 2006, at 2:38 PM, Pat Maddox wrote:
>
> > I'm writing a small app to do poker simulations.  I read a lot of
> > blogs in which the author shows off his cool DSL.  I decided I want to
> > be able to specify a poker hand in my app like
> >
> > hand "my_hand" do
> >  players 10
> >  chips     1000
> > end
> >
> > my_hand.foo
> >
> > How can I do something like that?
> >
> > Pat
> >
>
> class Hand
>    def initialize(name, &block)
>        @name = name
>        if block
>           instance_eval(&block)
>        end
>        self
>    end
>    def players(i)
>        @players = i
>    end
>
>    def chips(i)
>        @chips = i
>    end
>
>    def foo
>      puts self.inspect
>    end
> end
>
> def hand(name, &block)
>      Hand.new(name, &block)
> end
>
>
> my_hand = hand "my_hand" do
>              players 10
>              chips 1000
>            end
>
> my_hand.foo
>
> #<Hand:0x363450 @name="my_hand", @chips=1000, @players=10>
>
> If you want to automatically set 'my_hand' you can put it inside an
> enclosing object and dynamically define the my_hand method
>
>
>
>
>
>

Hey Logan,

Thanks for the input.  Here's what I ended up with.  I don't know if
I'm doing bad stuff though to define the object - please let me know. 
In the hand method, I'm creating the hand and passing the block like
normally.  Then to let me call the hand by the name I pass in, I
define a new method that calls a closure that simply returns the value
of the newly created object.  It works great...I just don't know if
there's a better way, or if this is a bad approach.

class Hand
  def players(p = nil)
    @players = p unless p.nil?
    @players
  end

  def chips(c = nil)
    @chips = c unless c.nil?
    @chips
  end
end

def hand(name, &init)
  h = Hand.new
  yield(h) if block_given?
  self.class.class_eval { define_method(name) { proc { h }.call } }
  h
end

hand "my_hand" do |h|
  h.players 10
  h.chips   1000
end

puts my_hand.inspect