Forum: Ruby How can I write the awesome kind of code?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
42172acdf3c6046f84d644cb0b94642c?d=identicon&s=25 Pat Maddox (pergesu)
on 2006-05-08 20:40
(Received via mailing list)
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
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2006-05-08 20:49
(Received via mailing list)
On May 8, 2006, at 1:38 PM, Pat Maddox wrote:

>
> How can I do something like that?

class Hand
   ...
end

def hand( ..., &init )
   Hand.new( ... ).instance_eval(&init)
end

I really think you'll be happy in the long run though if you drop the
instance_eval() and pass the hand into the block instead.

James Edward Gray II
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-05-08 20:59
(Received via mailing list)
On May 8, 2006, at 2:38 PM, Pat Maddox wrote:

>
> 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
42172acdf3c6046f84d644cb0b94642c?d=identicon&s=25 Pat Maddox (pergesu)
on 2006-05-08 21:02
(Received via mailing list)
On 5/8/06, James Edward Gray II <james@grayproductions.net> wrote:
> >
> end
>
> I really think you'll be happy in the long run though if you drop the
> instance_eval() and pass the hand into the block instead.
>
> James Edward Gray II
>
>

Okay so now I have

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(&init)
  yield(Hand.new) if block_given?
end

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

Does that look right?

How can I use the Hand object that I just created?
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2006-05-08 21:14
(Received via mailing list)
On May 8, 2006, at 1:59 PM, Pat Maddox wrote:

>> >  chips     1000
>> def hand( ..., &init )
> Okay so now I have
>  end
>
> Does that look right?

You can remove the &init parameter to hand(), since you are using
yield.  You may also want to make players() and chips() more Rubyish
with players=() and chips=().

To keep the hand object you could have hand return it, or perhaps add
it to some global Hash by name.

Hope that helps.

James Edward Gray II
42172acdf3c6046f84d644cb0b94642c?d=identicon&s=25 Pat Maddox (pergesu)
on 2006-05-08 21:14
(Received via mailing list)
On 5/8/06, Logan Capaldo <logancapaldo@gmail.com> wrote:
> > end
>        @name = name
>        @chips = i
>
> 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
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-05-08 21:24
(Received via mailing list)
On May 8, 2006, at 3:13 PM, Pat Maddox wrote:

>> >  players 10
>> class Hand
>>
>>      Hand.new(name, &block)
>> #<Hand:0x363450 @name="my_hand", @chips=1000, @players=10>
> Hey Logan,
> class Hand
>
> 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
42172acdf3c6046f84d644cb0b94642c?d=identicon&s=25 Pat Maddox (pergesu)
on 2006-05-08 21:27
(Received via mailing list)
On 5/8/06, James Edward Gray II <james@grayproductions.net> wrote:
> >> > hand "my_hand" do
> >> end
> >>
> >    @chips = c unless c.nil?
> >  h.chips   1000
>
> Hope that helps.
>
> James Edward Gray II
>
>
>

I took out &init, I understand why I don't need that in there.

However after doing all this, I'm not sure I get any benefit,
particularly if I stick to the more Rubyish players= and chips=

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

vs

my_hand = Hand.new
my_hand.chips = 1000
my_hand.players = 10

It's basically the same...

Pat
This topic is locked and can not be replied to.