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
On May 8, 2006, at 1:38 PM, Pat M. 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 G. II
On May 8, 2006, at 2:38 PM, Pat M. 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
On 5/8/06, James Edward G. II [email protected] 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 G. 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?
On May 8, 2006, at 1:59 PM, Pat M. 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 G. II
On May 8, 2006, at 3:13 PM, Pat M. 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
On 5/8/06, James Edward G. II [email protected] wrote:
hand “my_hand” do
end
@chips = c unless c.nil?
h.chips 1000
Hope that helps.
James Edward G. 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
On 5/8/06, Logan C. [email protected] 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