On May 8, 2006, at 3:13 PM, Pat Maddox wrote:

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

proc { h }.call is redundant.

define_method(name) { h } should work


Though I question whether hand name { ... } is necessary.

Why not just do

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

puts my_hand.inspect